TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Source_PDF_EF.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Source_PDF_EF.h>
17#include <Domaine.h>
18#include <Domaine_EF.h>
19#include <Domaine_Cl_EF.h>
20#include <Probleme_base.h>
21#include <Equation_base.h>
22#include <Schema_Temps_base.h>
23#include <Champ_Q1_EF.h>
24#include <Discretisation_base.h>
25#include <Matrice_Morse.h>
26#include <Matrice_Bloc.h>
27#include <TRUSTTrav.h>
28#include <Interpolation_IBM_elem_fluid.h>
29#include <Interpolation_IBM_mean_gradient.h>
30#include <Interpolation_IBM_hybrid.h>
31#include <Interpolation_IBM_power_law_tbl.h>
32#include <Interpolation_IBM_power_law_tbl_u_star.h>
33#include <Dirichlet.h>
34#include <SFichier.h>
35#include <Op_Conv_EF.h>
36
37Implemente_instanciable(Source_PDF_EF,"Source_PDF_EF",Source_PDF_base);
38
39/*##################################################################################################
40####################################################################################################
41################################# READON AND PRINTON ###############################################
42####################################################################################################
43##################################################################################################*/
44
46{
48 return s;
49}
50
52{
54 return s;
55}
56
57/*##################################################################################################
58####################################################################################################
59################################# PROBLEM ASSOCIATION AND ZONES ####################################
60####################################################################################################
61##################################################################################################*/
62
64{
66
67 int nb_som=le_dom_EF->domaine().nb_som();
68 tab_u_star_ibm_.resize(nb_som);
69 tab_y_plus_ibm_.resize(nb_som);
70}
71
76
78 const Domaine_Cl_dis_base& domaine_Cl_dis)
79{
80 le_dom_EF = ref_cast(Domaine_EF, domaine_dis);
81 le_dom_Cl_EF = ref_cast(Domaine_Cl_EF, domaine_Cl_dis);
82}
83
84void Source_PDF_EF::multiply_coeff_volume(DoubleTab& coeff) const
85{
86 const DoubleVect& vol_som=ref_cast(Domaine_EF, le_dom_EF.valeur()).volumes_sommets_thilde();
87 int n = vol_som.size_totale();
88 int nc = coeff.dimension_tot(0) ;
89 if (n != nc)
90 {
91 Cerr<<" dimensions differentes n nc = "<<n<<" "<<nc<<finl;
92 exit();
93 }
94 int ndim = coeff.dimension(1) ;
95 for (int i=0; i<n; i++)
96 {
97 for (int comp=0; comp<ndim; comp++) coeff(i,comp) = coeff(i,comp)*vol_som(i);
98 }
99}
100
101void Source_PDF_EF::volume_source_term_PDF(DoubleTab& volume_term_PDF)
102{
103 const DoubleTab& variable=equation().inconnue().valeurs();
104 int nb_som= variable.dimension(0);
105 assert(nb_som == volume_term_PDF.dimension(0));
106 volume_term_PDF = 0.;
107
108 const IntTab& elems= le_dom_EF.valeur().domaine().les_elems() ;
109 const DoubleVect& volume_thilde = le_dom_EF.valeur().volumes_thilde();
110 int nb_som_elem = le_dom_EF.valeur().domaine().nb_som_elem();
111 double inv_nb_som = 1. / nb_som_elem;
112 int nb_elems = le_dom_EF.valeur().domaine().nb_elem_tot();
113 const DoubleTab& aire=champ_aire_->valeurs();
114 DoubleTrav pond(nb_elems);
115 pond = 1.;
116
117 for (int num_elem=0; num_elem<nb_elems; num_elem++)
118 {
119 if (aire(num_elem)<=0.) pond(num_elem) =0.;
120 // pond = volume_thilde / (8*8)
121 pond(num_elem) *= volume_thilde(num_elem)*inv_nb_som*inv_nb_som;
122 for (int i=0; i<nb_som_elem; i++)
123 {
124 volume_term_PDF(elems(num_elem,i)) += pond(num_elem)*nb_som_elem;
125 }
126 }
127
128 double bilan = 0.0;
129 for (int j=0; j<nb_som; j++) bilan += volume_term_PDF(j);
130 Cerr<<"(IBM) volume_source_term_PDF: bilan = "<<bilan<<finl;
131}
132
133/*##################################################################################################
134####################################################################################################
135################################# AJOUTER_ #########################################################
136####################################################################################################
137##################################################################################################*/
138
139/*
140This function redirects toward the ajouter_ which correspond to the model chosen.
141*/
142
143DoubleTab& Source_PDF_EF::ajouter_(const DoubleTab& variable, DoubleTab& resu, const int i_traitement_special) const
144{
145 // calcul de : coefficient rho/dt * coeff_relax * (volume_thilde / 8) * variable
146 /* i_traitement_special = 0 => traitement classique; coefficient (1/eta) */
147 /* i_traitement_special = 1 => coefficient (1/eta -> 1) */
148 /* i_traitement_special = 2 => coefficient (1/eta -> 1 + 1/eta) */
149
150 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
151 const IntTab& elems= domaine_EF.domaine().les_elems() ;
152 int nb_som_elem=domaine_EF.domaine().nb_som_elem();
153 int nb_elems=domaine_EF.domaine().nb_elem_tot();
154 const DoubleVect& volume_thilde=domaine_EF.volumes_thilde();
155 int dim_esp = Objet_U::dimension ;
156 int dim_var = variable.dimension(1);
157 if (dim_var != 1 && dim_var != dim_esp)
158 {
159 Cerr<<"ajouter_: dimension variable differente 1 ou "<<dim_esp<<"! "<<finl;
160 exit();
161 }
162 ArrOfDouble tuvw(dim_var);
163 const DoubleTab& rotation=champ_rotation_->valeurs();
164 const DoubleTab& aire=champ_aire_->valeurs();
165 //OWN_PTR(Champ_Don_base) rho_test;
166 //champ_rho_->affecter(equation().probleme().get_champ("masse_volumique"));
167 const DoubleTab& rho_m=champ_rho_->valeurs();
168 DoubleTab pond;
169
170 // return = rho/dt * coeff_relax * volume_thilde / (8*8)
171 pond = compute_pond(rho_m, aire, volume_thilde, nb_som_elem, nb_elems);
172
173 for (int num_elem=0; num_elem<nb_elems; num_elem++)
174 {
175 if (aire(num_elem)>0.)
176 {
177 if (i_traitement_special == 0)
178 {
179 for (int k=0; k<dim_var; k++) tuvw[k] = 1.0 / modele_lu_.eta_;
180 }
181 else if (i_traitement_special == 1) //terme temps en rho v
182 {
183 for (int k=0; k<dim_var; k++) tuvw[k] = 1.0;
184 }
185 else if (i_traitement_special == 101) //terme temps en v
186 {
187 for (int k=0; k<dim_var; k++) tuvw[k] = 1.0 / rho_m(num_elem);
188 }
189 else if (i_traitement_special == 2)
190 {
191 for (int k=0; k<dim_var; k++) tuvw[k] = 1.0 + 1.0 / modele_lu_.eta_;
192 }
193 else if (i_traitement_special == 102)
194 {
195 for (int k=0; k<dim_var; k++) tuvw[k] = 1.0 / rho_m(num_elem) + 1.0 / modele_lu_.eta_;
196 }
197 else
198 {
199 Cerr << "Source_PDF_EF::ajouter_ : i_traitement_special should be 0, 1, 2, 101 or 102" << finl;
200 exit();
201 }
202 for (int comp=0; comp<dim_var; comp++)
203 {
204 double tijvj=0;
205 if (dim_var == 1)
206 {
207 tijvj = tuvw[0];
208 }
209 else
210 // dim_var = dim_esp
211 {
212 for (int c=0; c<dim_var; c++)
213 {
214 double coeff_im=0;
215 for(int k=0; k<dim_esp; k++)
216 {
217 coeff_im+=rotation(num_elem,3*k+comp)*tuvw[k]*rotation(num_elem,3*k+c);
218 }
219 tijvj+=coeff_im ;
220 }
221 }
222 // Cerr<< "Source_PDF_EF::ajouter_ tijvj=" <<tijvj<<" pond("<<num_elem<<") = "<<pond(num_elem)<< finl;
223 // cas generique : 1/eta rho/dt * coeff_relax * (volume_thilde / 8) * variable
224 for (int i=0; i<nb_som_elem; i++)
225 {
226 resu(elems(num_elem,i),comp)-=pond(num_elem)*nb_som_elem*tijvj*variable(elems(num_elem,i),comp);
227 // Cerr<< "Source_PDF_EF::ajouter_ noeud: "<<i <<" "<<pond(num_elem)*nb_som_elem*tijvj*variable(elems(num_elem,i),comp)<<" variable = "<<variable(elems(num_elem,i),comp)<< finl;
228 }
229 }
230 }
231 }
232 return resu;
233}
234
235DoubleTab& Source_PDF_EF::ajouter_(const DoubleTab& variable, DoubleTab& resu) const
236{
237 const int i_traitement_special = 0 ;
238 ajouter_(variable, resu, i_traitement_special) ;
239 return resu;
240}
241
242/*##################################################################################################
243####################################################################################################
244################################# CONTRIBUER_A_AVEC ################################################
245####################################################################################################
246##################################################################################################*/
247
248/*
249This function redirects toward the contribuer_avec_ which correspond to the model chosen.
250*/
251
252void Source_PDF_EF::contribuer_a_avec(const DoubleTab& inco, Matrice_Morse& matrice) const
253{
254 // calcul : 1/eta rho/dt * coeff_relax * volume_thilde / (8 * 8)
255 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
256 const IntTab& elems= domaine_EF.domaine().les_elems();
257 int nb_som_elem=domaine_EF.domaine().nb_som_elem();
258 int nb_elems=domaine_EF.domaine().nb_elem_tot();
259 const DoubleVect& volume_thilde=domaine_EF.volumes_thilde();
260 const DoubleTab& variable=equation().inconnue().valeurs();
261 int dim_var = variable.dimension(1);
262 int dim_esp = Objet_U::dimension ;
263 if (dim_var != 1 && dim_var != dim_esp)
264 {
265 Cerr<<"contribuer_a_avec: dimension variable differente 1 ou "<<dim_esp<<"! "<<finl;
266 exit();
267 }
268 ArrOfDouble tuvw(dim_var);
269 const DoubleTab& rotation=champ_rotation_->valeurs();
270 const DoubleTab& aire=champ_aire_->valeurs();
271 //champ_rho_->affecter(equation().probleme().get_champ("masse_volumique"));
272 const DoubleTab& rho_m=champ_rho_->valeurs();
273 DoubleTab pond ;
274
275 // return = rho/dt * coeff_relax * volume_thilde / (8*8) pour elements interceptes
276 pond = compute_pond(rho_m, aire, volume_thilde, nb_som_elem, nb_elems);
277
278 for (int num_elem=0; num_elem<nb_elems; num_elem++) //elements loop
279 {
280 if (aire(num_elem)>0.)
281 {
282 for (int k=0; k<dim_var; k++) tuvw[k] = 1.0 / modele_lu_.eta_;
283 // Cerr<< "Source_PDF_EF::contribuer_a_avec: tuvw=" <<tuvw<<" pond("<<num_elem<<") = "<<pond(num_elem)<< finl;
284
285 for (int comp=0; comp<dim_var; comp++)
286 {
287 for (int comp2=0; comp2<dim_var; comp2++)
288 {
289 for (int i=0; i<nb_som_elem; i++)
290 {
291 for (int j=0; j<nb_som_elem; j++)
292 {
293 int s1=elems(num_elem,i);
294
295 double coeff_im=0;
296 if (dim_var == 1)
297 {
298 coeff_im = tuvw[0];
299 }
300 else
301 // dim_var = dim_esp
302 {
303 for (int k=0; k<dim_esp; k++)
304 {
305 coeff_im+=rotation(num_elem,3*k+comp)*tuvw[k]*rotation(num_elem,3*k+comp2);
306 }
307 }
308 int c1=s1*dim_var+comp;
309
310 // 1.0/eta * rho/dt * coeff_relax * volume_thilde / (8*8)
311 matrice.coef(c1,c1)+=pond(num_elem)*coeff_im;
312 // Cerr<< "Source_PDF_EF::contribuer_a_avec: contribution matrice c1c1 : "<<c1<<" = "<<pond(num_elem)*coeff_im<< finl;
313 }
314 }
315 }
316 }
317 }
318 }
319 // verif_ajouter_contrib(variable, matrice) ;
320}
321
322void Source_PDF_EF::verif_ajouter_contrib(const DoubleTab& variable, Matrice_Morse& matrice) const
323{
324 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
325 const IntTab& elems= domaine_EF.domaine().les_elems() ;
326 int nb_elems=domaine_EF.domaine().nb_elem_tot();
327 int nb_som_elem=domaine_EF.domaine().nb_som_elem();
328 const DoubleTab& aire=champ_aire_->valeurs();
329
330 DoubleTrav force(variable);
331 int dim_var = variable.dimension(1);
332 ajouter_(variable,force);
333 DoubleTrav force2(variable);
334 matrice.ajouter_multvect_(variable, force2) ;
335 DoubleTab diforce(force);
336 diforce += force2 ;
337 double difmax = 0.;
338 for (int num_elem=0; num_elem<nb_elems; num_elem++)
339 {
340 if (aire(num_elem)>0.)
341 {
342 for (int i=0; i<nb_som_elem; i++)
343 {
344 int s1=elems(num_elem,i);
345 double difmod2 = 0.;
346 for (int k=0; k<dim_var; k++) difmod2 += diforce(s1,k)*diforce(s1,k);
347 if (difmod2 > 1.0e-5)
348 {
349 if (difmod2 > difmax) difmax = difmod2 ;
350 // for (int k=0; k<dim_var; k++) Cerr << " ajouter multvect diforce x = "<< force(s1,k) << " "<< force2(s1,k) << " " << diforce(s1,k)<<finl;
351 }
352 }
353 }
354 }
355 if (difmax > 0.)
356 {
357 Cerr<< "Source_PDF: Max norme caree diff. force absolue = "<<difmax<<finl;
358 }
359}
360
361/*##################################################################################################
362####################################################################################################
363################################# calculer_variable_imposee ########################################
364####################################################################################################
365##################################################################################################*/
366
368{
369 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
370 int nb_som=domaine_EF.domaine().nb_som();
371 int dim_esp = Objet_U::dimension;
372 const Domaine& dom = domaine_EF.domaine();
373 // const IntTab& elems= zone_EF.zone().les_elems();
374 DoubleTab& variable_imposee_mod = modele_lu_.variable_imposee_->valeurs();
375 DoubleTab& variable_imposee_calculee = variable_imposee_;
376 Interpolation_IBM_elem_fluid& interp = ref_cast(Interpolation_IBM_elem_fluid,interpolation_lue_.valeur());
377 DoubleTab& fluid_points = interp.fluid_points_->valeurs();
378 DoubleTab& solid_points = interp.solid_points_->valeurs();
379 DoubleTab& fluid_elems = interp.fluid_elems_->valeurs();
380
381 Champ_Q1_EF& champ_variable_inconnue = ref_cast(Champ_Q1_EF,equation().inconnue());
382 DoubleTab& val_variable_inconnue = champ_variable_inconnue.valeurs();
383 int nb_comp = val_variable_inconnue.dimension(1);
384
385 DoubleTab xf(1, dim_esp);
386 DoubleTab vf(1, nb_comp);
387 ArrOfInt cells(1);
388 double eps = 1e-12;
389
390 for (int i = 0; i < nb_som; i++)
391 {
392 if (fluid_elems(i) >= 0.0)
393 {
394 double d1 = 0.0;
395 double d2 = 0.0;
396 for(int j = 0; j < dim_esp; j++)
397 {
398 double xj = dom.coord(i,j);
399 double xjf = fluid_points(i,j);
400 xf(0, j) = xjf;
401 double xjs = solid_points(i,j);
402 d1 += (xj-xjs)*(xj-xjs);
403 d2 += (xjf-xj)*(xjf-xj);
404 //Cerr << "xj " << xj << "xjf " << xjf << "xjs " << xjs << finl;
405 }
406 d1 = sqrt(d1);
407 d2 = sqrt(d2);
408 double inv_d ;
409 if ( (d1 + d2) > eps ) inv_d = 1.0 / (d1 + d2);
410 else inv_d = 0. ;
411 cells[0] = int(fluid_elems(i));
412 champ_variable_inconnue.value_interpolation(xf,cells, val_variable_inconnue, vf);
413 for (int j = 0; j < nb_comp; j++)
414 {
415 double vjs = variable_imposee_mod(i,j);
416 variable_imposee_calculee(i,j) = vjs + (vf(0, j)-vjs)*inv_d*d1;
417 }
418 // for(int j = 0; j < nb_comp; j++) Cerr<<"variable_imposee_calculee("<<i<<","<<j<<") = "<<variable_imposee_calculee(i,j)<<finl;
419 }
420 else
421 {
422 for(int j = 0; j < nb_comp; j++)
423 {
424 variable_imposee_calculee(i,j) = variable_imposee_mod(i,j);
425 }
426 // for(int j = 0; j < nb_comp; j++) Cerr<<"variable_imposee_calculee("<<i<<","<<j<<") = variable_imposee_mod = "<<variable_imposee_calculee(i,j)<< finl;
427 }
428 }
429 //variable_imposee_calculee.echange_espace_virtuel();
430}
431
433{
434 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
435 int nb_som=domaine_EF.domaine().nb_som();
436 int dim_esp = Objet_U::dimension;
437 const Domaine& dom = domaine_EF.domaine();
438 // const IntTab& elems= zone_EF.zone().les_elems();
439 DoubleTab& variable_imposee_mod = modele_lu_.variable_imposee_->valeurs();
440 DoubleTab& variable_imposee_calculee = variable_imposee_;
441 Interpolation_IBM_mean_gradient& interp = ref_cast(Interpolation_IBM_mean_gradient,interpolation_lue_.valeur());
442 DoubleTab& solid_points = interp.solid_points_->valeurs();
443 DoubleTab& is_dirichlet = interp.is_dirichlet_->valeurs();
444 double eps = 1e-12;
445 DoubleTab& variable_inconnue = equation().inconnue().valeurs();
446 int nb_comp = variable_inconnue.dimension(1);
447
448 variable_imposee_mod.echange_espace_virtuel();
449
450 // DoubleTrav nb_vois(is_dirichlet);
451 for (int i = 0; i < nb_som; i++)
452 {
453 if (is_dirichlet(i) > 0.0)
454 {
455 double d2 = 0.0;
456 for(int j = 0; j < dim_esp; j++)
457 {
458 double x = dom.coord(i,j);
459 double xp = solid_points(i,j);
460 d2 += (x - xp)*(x - xp);
461 }
462 for(int j = 0; j <nb_comp ; j++) variable_imposee_calculee(i,j) = variable_imposee_mod(i,j);
463 d2 = sqrt(d2);
464 if (d2 > eps)
465 {
466 IntList& voisins = interp.getSommetsVoisinsOf(i);
467 if (!(voisins.est_vide()))
468 {
469 ArrOfDouble mean_grad(nb_comp);
470 mean_grad = 0.0;
471 int taille = voisins.size();
472 // nb_vois(i) = taille * 1.0 ;
473 int nb_contrib = 0;
474 for (int k = 0; k < taille; k++)
475 {
476 int num_som = voisins[k];
477 double d1 = 0.0;
478 for (int j = 0; j < dim_esp; j++)
479 {
480 double xf = dom.coord(num_som,j);
481 double xpf = solid_points(num_som,j);
482 d1 += (xf - xpf)*(xf - xpf);
483 }
484 d1 = sqrt(d1);
485 if (d1 > eps)
486 {
487 for (int j = 0; j < nb_comp; j++)
488 {
489 double vpf = variable_imposee_mod(num_som,j);
490 double vf = variable_inconnue(num_som,j);
491 mean_grad[j] += (vf - vpf)/d1;
492 }
493 nb_contrib += 1;
494 }
495 }
496 for (int j = 0; j < nb_comp; j++)
497 {
498 mean_grad[j] /= nb_contrib;
499 variable_imposee_calculee(i,j) += mean_grad[j]*d2;
500 }
501 }
502 }
503 }
504 else
505 {
506 for(int j = 0; j < nb_comp; j++)
507 {
508 variable_imposee_calculee(i,j) = variable_imposee_mod(i,j);
509 }
510 }
511 }
512 //variable_imposee_calculee.echange_espace_virtuel();
513 //Cerr<<"Min/max/norme : nb_vois "<< mp_min_vect(nb_vois) << " " << mp_max_vect(nb_vois) << " " << mp_norme_vect(nb_vois) << finl;
514}
515
517{
518 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
519 int nb_som=domaine_EF.domaine().nb_som();
520 int dim_esp = Objet_U::dimension;
521 const Domaine& dom = domaine_EF.domaine();
522 // const IntTab& elems= zone_EF.zone().les_elems();
523 DoubleTab& variable_imposee_mod = modele_lu_.variable_imposee_->valeurs();
524 DoubleTab& variable_imposee_calculee = variable_imposee_;
525 Interpolation_IBM_hybrid& interp = ref_cast(Interpolation_IBM_hybrid,interpolation_lue_.valeur());
526 DoubleTab& solid_points = interp.solid_points_->valeurs();
527 DoubleTab& fluid_elems = interp.fluid_elems_->valeurs();
528 DoubleTab& fluid_points = interp.fluid_points_->valeurs();
529 double eps = 1e-12;
530 Champ_Q1_EF& champ_variable_inconnue = ref_cast(Champ_Q1_EF,equation().inconnue());
531 DoubleTab& variable_inconnue = champ_variable_inconnue.valeurs();
532 int nb_comp = variable_inconnue.dimension(1);
533
534 DoubleTab xf(1, dim_esp);
535 DoubleTab vf(1, nb_comp);
536 ArrOfInt cells(1);
537
538 for (int i = 0; i < nb_som; i++)
539 {
540 if (fluid_elems(i) >= 0.0)
541 {
542 double d1 = 0.0;
543 double d2 = 0.0;
544 for(int j = 0; j < dim_esp; j++)
545 {
546 double xj = dom.coord(i,j);
547 double xjf = fluid_points(i,j);
548 xf(0, j) = xjf;
549 double xjs = solid_points(i,j);
550 d1 += (xj-xjs)*(xj-xjs);
551 d2 += (xjf-xj)*(xjf-xj);
552 }
553 d1 = sqrt(d1);
554 d2 = sqrt(d2);
555 double inv_d = 1.0 / (d1 + d2);
556 cells[0] = int(fluid_elems(i));
557 champ_variable_inconnue.value_interpolation(xf,cells, variable_inconnue, vf);
558 for (int j = 0; j < nb_comp; j++)
559 {
560 double vjs = variable_imposee_mod(i,j);
561 variable_imposee_calculee(i,j) = variable_imposee_mod(i,j) + (vf(0, j)-vjs)*inv_d*d1;
562 }
563 }
564 else if (fluid_elems(i) > -1.5 && fluid_elems(i) < -0.5)
565 {
566 double d2 = 0.0;
567 for(int j = 0; j < dim_esp; j++)
568 {
569 double x = dom.coord(i,j);
570 double xp = solid_points(i,j);
571 d2 += (x - xp)*(x - xp);
572 }
573 d2 = sqrt(d2);
574 for(int j = 0; j <nb_comp ; j++) variable_imposee_calculee(i,j) = variable_imposee_mod(i,j);
575 if (d2 > eps)
576 {
577 IntList& voisins = interp.getSommetsVoisinsOf(i);
578 if (!(voisins.est_vide()))
579 {
580 ArrOfDouble mean_grad(nb_comp);
581 mean_grad = 0.0;
582 int taille = voisins.size();
583 int nb_contrib = 0;
584 for (int k = 0; k < taille; k++)
585 {
586 int num_som = voisins[k];
587 double d1 = 0.0;
588 for (int j = 0; j < dim_esp; j++)
589 {
590 double xjf = dom.coord(num_som,j);
591 double xpf = solid_points(num_som,j);
592 d1 += (xjf - xpf)*(xjf - xpf);
593 }
594 d1 = sqrt(d1);
595 if (d1 > eps)
596 {
597 for (int j = 0; j < nb_comp; j++)
598 {
599 double vpf = variable_imposee_mod(num_som,j);
600 double vjf = variable_inconnue(num_som,j);
601 mean_grad[j] += (vjf - vpf)/d1;
602 }
603 nb_contrib += 1;
604 }
605 }
606 for (int j = 0; j < nb_comp; j++)
607 {
608 mean_grad[j] /= nb_contrib;
609 variable_imposee_calculee(i,j) += mean_grad[j]*d2;
610 }
611 }
612 }
613 }
614 else
615 {
616 for(int j = 0; j < nb_comp; j++)
617 {
618 variable_imposee_calculee(i,j) = variable_imposee_mod(i,j);
619 }
620 }
621 }
622 //variable_imposee_calculee.echange_espace_virtuel();
623}
624
625/*##################################################################################################
626####################################################################################################
627################################# calculer_vitesse_imposee #########################################
628####################################################################################################
629##################################################################################################*/
630
632{
633 assert(Objet_U::dimension==3);
634 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
635 int nb_som=domaine_EF.domaine().nb_som();
636 int nb_comp = Objet_U::dimension;
637 const Domaine& dom = domaine_EF.domaine();
638 // const IntTab& elems= zone_EF.zone().les_elems();
639 DoubleTab& vitesse_imposee_mod = modele_lu_.variable_imposee_->valeurs();
640 DoubleTab& vitesse_imposee_calculee = variable_imposee_;
641 Interpolation_IBM_power_law_tbl& interp = ref_cast(Interpolation_IBM_power_law_tbl,interpolation_lue_.valeur());
642 int form_WJSP = interp.get_formulation_WJSP();
643 DoubleTab& fluid_points = interp.fluid_points_->valeurs();
644 DoubleTab& solid_points = interp.solid_points_->valeurs();
645 DoubleTab& fluid_elems = interp.fluid_elems_->valeurs();
646 double A_pwl = interp.get_A_pwl(form_WJSP);
647 double B_pwl = interp.get_B_pwl();
648 double y_c_p_pwl = 0;
649 double C_pwl_WJSP = 0;
650 double D_pwl_WJSP = 0;
651 double p_pwl_WJSP = 0;
652 double y_c1_p_pwl_WJSP = 0;
653 double y_c2_p_pwl_WJSP = 0;
654 if (!form_WJSP)
655 {
656 y_c_p_pwl = interp.get_y_c_p_pwl();
657 }
658 else
659 {
660 C_pwl_WJSP = interp.get_C_pwl_WJSP();
661 D_pwl_WJSP = interp.get_D_pwl_WJSP();
662 p_pwl_WJSP = interp.get_p_pwl_WJSP();
663 y_c1_p_pwl_WJSP = interp.get_y_c1_p_pwl_WJSP();
664 y_c2_p_pwl_WJSP = interp.get_y_c2_p_pwl_WJSP();
665 }
666 int impr_yplus = interp.get_impr() ;
667 Champ_Q1_EF& champ_vitesse_inconnue = ref_cast(Champ_Q1_EF,equation().inconnue());
668 DoubleTab& val_vitesse_inconnue = champ_vitesse_inconnue.valeurs();
669 if (nb_comp != val_vitesse_inconnue.dimension(1))
670 {
671 Cerr<<"Source_PDF_EF::calculer_vitesse_imposee_power_law_tbl: variable must be a vector of dimension "<<Objet_U::dimension<<" ! "<<finl;
672 abort();
673 }
674 double form_lin_pwl = interp.get_formulation_linear_pwl();
675
676 DoubleTab xf(1, nb_comp);
677 DoubleTab vf(1, nb_comp);
678 ArrOfInt cells(1);
679
680 // operateur(0) : diffusivite
681 if (equation().nombre_d_operateurs()<1)
682 {
683 Cerr << "Source_PDF_EF : nombre_d_operateurs = "<<equation().nombre_d_operateurs()<<" < 1"<<finl;
684 exit();
685 }
686 int flag = 0;
687 const Op_Diff_EF_base& opdiffu = ref_cast(Op_Diff_EF_base,equation().operateur(0).l_op_base());
688 flag = opdiffu.diffusivite().valeurs().dimension(0)>1 ? 1 : 0;
689
690 double eps = 1e-12;
691 double d1_min = 1.0e+10;
692 double d1_max = 0.0;
693 double d1_mean = 0.0;
694 double yplus_min = 1.0e+10;
695 double yplus_max = 0.0;
696 double yplus_mean = 0.0;
697 double u_tau_min = 1.0e+10;
698 double u_tau_max = 0.0;
699 double u_tau_mean = 0.0;
700 double yplus_ref_min = 1.0e+10;
701 double yplus_ref_max = 0.0;
702 double yplus_ref_mean = 0.0;
703 double u_tau_ref_min = 1.0e+10;
704 double u_tau_ref_max = 0.0;
705 double u_tau_ref_mean = 0.0;
706 double h_yplus_min = 1.0e+10;
707 double h_yplus_max = 0.0;
708 double h_yplus_mean = 0.0;
709 int yplus_count=0 ;
710 double y_plus=0;
711
712 int N = interp.get_N_histo();
713 DoubleTab tab_h(1, nb_som);
714 DoubleTab abs_h(1, N+1);
715 DoubleTab compteur_h(1, N);
716 compteur_h = 0.;
717 tab_h = 0.;
718
719 tab_u_star_ibm_ = 0.;
720 tab_y_plus_ibm_ = 0.;
721
722 for (int i = 0; i < nb_som; i++)
723 {
724 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = vitesse_imposee_mod(i,j);
725 int itisok = 1;
726 if (fluid_elems(i) >= 0.0)
727 {
728 double d1 = 0.0;
729 double d2 = 0.0;
730 DoubleTab normale(1, nb_comp);
731 double norme_de_la_normale= 0.0;
732 for(int j = 0; j < nb_comp; j++)
733 {
734 double xj = dom.coord(i,j);
735 double xjf = fluid_points(i,j);
736 xf(0, j) = xjf;
737 double xjs = solid_points(i,j);
738 d1 += (xj-xjs)*(xj-xjs);
739 d2 += (xjf-xj)*(xjf-xj);
740 normale(0,j) = xjf - xjs;
741 norme_de_la_normale += normale(0,j)*normale(0,j);
742 }
743 d1 = sqrt(d1);
744 d2 = sqrt(d2);
745 double y_ref= d1+d2;
746
747 // traitement des exceptions
748 if (d1 < eps) itisok = 0; //le point P est sur la frontiere immergee : affectation
749 norme_de_la_normale = sqrt(norme_de_la_normale);
750 if ( norme_de_la_normale > eps )
751 for(int j = 0; j < nb_comp; j++) normale(0,j) /= norme_de_la_normale; // la on met la norme unite tout en gardant la direction, on normalise quoi
752 else
753 {
754 for(int j = 0; j < nb_comp; j++) normale(0,j) = 0.; // le point fluide est sur la frontiere immergee : affectation
755 itisok = 0;
756 }
757 if ( y_ref < eps ) // le point fluide est sur la frontiere immergee : affectation
758 {
759 y_ref = 1.;
760 itisok = 0;
761 }
762
763 // calcul vitesse power law
764 if (itisok)
765 {
766 cells(0) = int(fluid_elems(i));
767 champ_vitesse_inconnue.value_interpolation(xf,cells, val_vitesse_inconnue, vf); // vf la vitesse totale interpolee au pt fluide
768 double Vn = 0.;
769 for(int j = 0; j < nb_comp; j++) Vn +=vf(0, j) * normale(0,j);
770 DoubleTab v_ref_t(1, nb_comp);
771
772 for(int j = 0; j < nb_comp; j++) v_ref_t(0, j) =vf(0, j) - Vn*normale(0,j);
773
774 double norme_v_ref_t = 0.;
775 for(int j = 0; j < nb_comp; j++) norme_v_ref_t += v_ref_t(0, j)*v_ref_t(0,j) ;
776 norme_v_ref_t = sqrt ( norme_v_ref_t );
777 if (norme_v_ref_t < 1.0e-6) norme_v_ref_t = 1.e-6;
778
779 double nu = (flag ? opdiffu.diffusivite().valeurs()(cells) : opdiffu.diffusivite().valeurs()(0,0));
780
781 // On calcule U_tau_ref pour pouvoir calculer les quantites adimensionees ( y+ ...)
782 // Hypothese : sous-couche puissance
783
784 double u_tau_ref = pow ( norme_v_ref_t , (1/(1+B_pwl)) ) * pow ( A_pwl, (-1/(1+B_pwl)) ) * pow ( y_ref , (-B_pwl/(1+B_pwl)) ) * pow ( nu,(B_pwl/(1+B_pwl)) ) ;
785
786 // Cerr<<"u_tau_ref y_ref nu ="<<u_tau_ref<<" "<<y_ref<<" "<<nu<<finl;
787
788 double y_ref_p = y_ref * u_tau_ref / nu; //la on a enfin tout ce qu'il faut pour etablir la loi polynomiale pour y r+
789 double test_ref;
790
791 if (!form_WJSP)
792 {
793 if ( y_ref_p > y_c_p_pwl) // a partir de la commence l'expression de la loi de paroi polynomiale turbulente
794 {
795 if (!form_lin_pwl)
796 {
797 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = v_ref_t(0,j) * pow ( d1 / y_ref , B_pwl ) ;
798 }
799 else // Formulation lineaire de la loi polynomilale ------------------------------
800 {
801 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = v_ref_t(0,j) *(1. - B_pwl*(1-d1/y_ref)) ;
802 }
803 test_ref = 1.;
804 // Cerr << "zone log/sous-couche inertielle en coherence avec le calcul de u tau" << finl;
805 }
806 else
807 {
808 // En fait, on est en sous-couche visqueuse
809 if (!form_lin_pwl)
810 {
811 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = v_ref_t(0,j) * ( d1 / y_ref ) ;
812 }
813 else
814 {
815 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = v_ref_t(0,j) * (1. - pow(u_tau_ref, 2.)*(y_ref-d1)/(nu *norme_v_ref_t));
816 }
817 test_ref = -1. ;
818 u_tau_ref = pow ( (nu * norme_v_ref_t / y_ref) , 0.5 ) ; // on recalcule u_tau et y_plus en lineaire au pt reference
819 y_ref_p = y_ref * u_tau_ref / nu;
820 if ( y_ref_p > y_c_p_pwl )
821 {
822 // Incoherence : on n utilise pas de lois de paroi
823 itisok = 0;
824 }
825 // Cerr << "zone lineaire/sous-couche visqueuse" << finl;
826 } // Fin LdPturb
827
828 double norme_v_imp_c = 0;
829 for(int j=0 ; j < nb_comp; j++) norme_v_imp_c += vitesse_imposee_calculee(i ,j) * vitesse_imposee_calculee(i ,j);
830 norme_v_imp_c = sqrt( norme_v_imp_c );
831
832 double u_tau = pow ( norme_v_imp_c , (1/(1+B_pwl)) ) * pow ( A_pwl, (-1/(1+B_pwl)) ) * pow ( d1 , (-B_pwl/(1+B_pwl)) ) * pow ( nu,(B_pwl/(1+B_pwl)) ) ; // Hypothese : sous-couche puissance
833 y_plus = u_tau * d1 / nu;
834 double test_;
835 if (y_plus >y_c_p_pwl)
836 {
837 test_ = 1.;
838 // Cerr<<"u_tau ="<<u_tau<<" y+ = "<<y_plus<<" y+ref = "<<y_ref_p<<finl;
839 }
840 else
841 {
842 test_ = -1.;
843 u_tau = pow ( (nu * norme_v_imp_c/ d1) , 0.5 ) ; // on recalcule u_tau et y_plus en lineaire au pt force
844 y_plus = u_tau * d1 / nu;
845 if ( y_plus > y_c_p_pwl )
846 {
847 // Incoherence : on n utilise pas de lois de paroi
848 Cerr<<"INCOHERENCE: u_tau ="<<u_tau<<" y+ = "<<y_plus<<" y+ref = "<<y_ref_p<<finl;
849 itisok = 0;
850 }
851 }
852 // Cerr<<"u_tau d1 nu ="<<u_tau<<" "<<d1<<" "<<nu<<finl;;
853
854 // ici on effectue le test pour savoir si le noeud de frontiere et le point fluide se trouvent dans la meme zone: si oui ok, si non on impose la vitesse
855 // Traitement des exceptions
856 if ( (test_ * test_ref < 0) || (itisok == 0) ) //si non on affecte la vitesse paroi
857 {
858 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = vitesse_imposee_mod(i,j);
859
860 // Cerr << "erreur" << finl;
861 itisok = 0;
862 }
863 else
864 {
865 tab_u_star_ibm_(i) = u_tau;
866 tab_y_plus_ibm_(i) = y_plus;
867 }
868
869 if (impr_yplus && itisok && (indicateur_nodal_champ_aire_(i)==1.))
870 {
871 if (d1 > d1_max) d1_max = d1;
872 if (d1 < d1_min) d1_min = d1;
873 d1_mean += d1;
874 if (y_plus > yplus_max) yplus_max = y_plus;
875 if (y_plus < yplus_min) yplus_min = y_plus;
876 yplus_mean += y_plus;
877 if (u_tau > u_tau_max) u_tau_max = u_tau;
878 if (u_tau < u_tau_min) u_tau_min = u_tau;
879 u_tau_mean += u_tau;
880 if (y_ref_p > yplus_ref_max) yplus_ref_max = y_ref_p;
881 if (y_ref_p < yplus_ref_min) yplus_ref_min = y_ref_p;
882 yplus_ref_mean += y_ref_p;
883 if (u_tau_ref > u_tau_ref_max) u_tau_ref_max = u_tau_ref;
884 if (u_tau_ref < u_tau_ref_min) u_tau_ref_min = u_tau_ref;
885 u_tau_ref_mean += u_tau_ref;
886 // Distribution des y+ au voisinage des parois
887 if (y_plus > h_yplus_max) h_yplus_max = y_plus;
888 if (y_plus < h_yplus_min) h_yplus_min = y_plus;
889 h_yplus_mean += y_plus;
890 tab_h(0,yplus_count) = y_plus;
891 yplus_count += 1;
892 }
893 }
894 else
895 {
896 //double u_tau;
897 if ( y_ref_p > y_c2_p_pwl_WJSP) // a partir de la commence l'expression de la loi de paroi polynomiale turbulente
898 {
899 y_plus = u_tau_ref * d1/nu;
900 if (y_plus > y_c2_p_pwl_WJSP)
901 {
902 if (!form_lin_pwl)
903 {
904 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = v_ref_t(0,j) * pow ( d1 / y_ref , B_pwl ) ;
905 }
906 else // Formulation lineaire de la loi polynomilale ------------------------------
907 {
908 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = v_ref_t(0,j) * (1. - B_pwl*(1-d1/y_ref)) ;
909 }
910 }
911 else if (y_plus < y_c2_p_pwl_WJSP and y_plus > y_c1_p_pwl_WJSP)
912 {
913 if (!form_lin_pwl)
914 {
915 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = (C_pwl_WJSP*pow(y_plus,2*p_pwl_WJSP-1) *u_tau_ref + D_pwl_WJSP*pow(y_plus,p_pwl_WJSP-1) *u_tau_ref)* v_ref_t(0,j)/norme_v_ref_t;
916 }
917 else // Formulation lineaire de la loi polynomilale ------------------------------
918 {
919 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = 0 ;
920 }
921 }
922 else
923 {
924 if (!form_lin_pwl)
925 {
926 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = y_plus * u_tau_ref * v_ref_t(0,j)/norme_v_ref_t;
927 }
928 else // Formulation lineaire de la loi polynomilale ------------------------------
929 {
930 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = v_ref_t(0,j) * (1. - B_pwl*(1-d1/y_ref)) ;
931 }
932 }
933 // Cerr << "zone log/sous-couche inertielle en coherence avec le calcul de u tau" << finl;
934 }
935 else // hypothèse buffer layer
936 {
937 u_tau_ref = (nu/y_ref) * pow(-(D_pwl_WJSP/(2*C_pwl_WJSP)) * (1 + pow(1 + 4 * C_pwl_WJSP/pow(D_pwl_WJSP,2) * norme_v_ref_t * y_ref /nu ,1/2)),1/p_pwl_WJSP) ;
938 y_ref_p = y_ref * u_tau_ref / nu;
939 if (y_ref_p < y_c2_p_pwl_WJSP and y_ref_p > y_c1_p_pwl_WJSP)
940 {
941 y_plus = u_tau_ref * d1/nu;
942 if (y_plus < y_c2_p_pwl_WJSP and y_plus > y_c1_p_pwl_WJSP)
943 {
944 if (!form_lin_pwl)
945 {
946 double phi = -pow(1 + 4 * C_pwl_WJSP/pow(D_pwl_WJSP,2) * norme_v_ref_t * y_ref /nu,1/2) - 1;
947 double u_norm = pow(D_pwl_WJSP,2) * nu / (4 * C_pwl_WJSP * y_ref) * (pow ( d1 / y_ref , 2*p_pwl_WJSP - 1 ) * pow(phi,2) + 2 * pow ( d1 / y_ref , p_pwl_WJSP - 1 ) * phi);
948 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = u_norm * v_ref_t(0,j)/norme_v_ref_t;
949 }
950 else // Formulation lineaire de la loi polynomilale ------------------------------
951 {
952 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = 0 ; //à faire
953 }
954 }
955 else
956 {
957 if (!form_lin_pwl)
958 {
959 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = y_plus * u_tau_ref * v_ref_t(0,j)/norme_v_ref_t ;
960 }
961 else // Formulation lineaire de la loi polynomilale ------------------------------
962 {
963 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = 0 ;
964 }
965 }
966 }
967 else
968 {
969 // En fait, on est en sous-couche visqueuse
970 if (!form_lin_pwl)
971 {
972 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = v_ref_t(0,j) * ( d1 / y_ref ) ;
973 }
974 else
975 {
976 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = v_ref_t(0,j) * (1. - pow(u_tau_ref, 2.)*(y_ref-d1)/(nu *norme_v_ref_t));
977 }
978 u_tau_ref = pow ( (nu * norme_v_ref_t / y_ref) , 0.5 ) ; // on recalcule u_tau et y_plus en lineaire au pt reference
979 y_ref_p = y_ref * u_tau_ref / nu;
980 if ( y_ref_p > y_c1_p_pwl_WJSP)
981 {
982 // Incoherence : on n utilise pas de lois de paroi
983 itisok = 0;
984 Cerr << "Incoherence" << finl;
985 }
986 }
987 }
988 // Cerr<<"u_tau d1 nu ="<<u_tau<<" "<<d1<<" "<<nu<<finl;;
989
990 // ici on effectue le test pour savoir si le noeud de frontiere et le point fluide se trouvent dans la meme zone: si oui ok, si non on impose la vitesse
991
992 // Traitement des exceptions
993 if (itisok == 0) //si non on affecte la vitesse paroi
994 {
995 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = vitesse_imposee_mod(i,j);
996
997 // Cerr << "erreur" << finl;
998 itisok = 0;
999 }
1000 else
1001 {
1002 tab_u_star_ibm_(i) = u_tau_ref;
1003 tab_y_plus_ibm_(i) = y_plus;
1004 }
1005 if (impr_yplus && itisok && (indicateur_nodal_champ_aire_(i)==1.))
1006 {
1007 if (d1 > d1_max) d1_max = d1;
1008 if (d1 < d1_min) d1_min = d1;
1009 d1_mean += d1;
1010 if (y_plus > yplus_max) yplus_max = y_plus;
1011 if (y_plus < yplus_min) yplus_min = y_plus;
1012 yplus_mean += y_plus;
1013 if (u_tau_ref > u_tau_max) u_tau_max = u_tau_ref;
1014 if (u_tau_ref < u_tau_min) u_tau_min = u_tau_ref;
1015 u_tau_mean += u_tau_ref;
1016 if (y_ref_p > yplus_ref_max) yplus_ref_max = y_ref_p;
1017 if (y_ref_p < yplus_ref_min) yplus_ref_min = y_ref_p;
1018 yplus_ref_mean += y_ref_p;
1019 if (u_tau_ref > u_tau_ref_max) u_tau_ref_max = u_tau_ref;
1020 if (u_tau_ref < u_tau_ref_min) u_tau_ref_min = u_tau_ref;
1021 u_tau_ref_mean += u_tau_ref;
1022 // Distribution des y+ au voisinage des parois
1023 if (y_plus > h_yplus_max) h_yplus_max = y_plus;
1024 if (y_plus < h_yplus_min) h_yplus_min = y_plus;
1025 h_yplus_mean += y_plus;
1026 tab_h(0,yplus_count) = y_plus;
1027 yplus_count += 1;
1028 }
1029 }
1030 }
1031 }
1032 }
1033 //vitesse_imposee_calculee.echange_espace_virtuel();
1034
1035 if (impr_yplus && (yplus_count >= 1) )
1036 {
1037 d1_mean /= yplus_count;
1038 yplus_mean /= yplus_count;
1039 yplus_ref_mean /= yplus_count;
1040 u_tau_mean /= yplus_count;
1041 u_tau_ref_mean /= yplus_count;
1042 Cerr<<"min mean max y = "<<d1_min<<" "<<d1_mean<<" "<<d1_max<<finl;
1043 Cerr<<"min mean max y+ = "<<yplus_min<<" "<<yplus_mean<<" "<<yplus_max<<finl;
1044 Cerr<<"min mean u_tau = "<<u_tau_min<<" "<<u_tau_mean<<" "<<u_tau_max<<finl;
1045 Cerr<<"min mean max y+_ref = "<<yplus_ref_min<<" "<<yplus_ref_mean<<" "<<yplus_ref_max<<finl;
1046 Cerr<<"min mean u_tau_ref = "<<u_tau_ref_min<<" "<<u_tau_ref_mean<<" "<<u_tau_ref_max<<finl;
1047
1048 h_yplus_mean /= yplus_count;
1049 double range = ( h_yplus_max - h_yplus_min)/N;
1050 for (int k = 0; k < N+1; k++) abs_h(0,k) = (h_yplus_min + k*range);
1051 for (int i=0; i < yplus_count; i++)
1052 {
1053 for (int j = 0; j < N; j++)
1054 {
1055 if ( abs_h(0,j) < tab_h(0,i) && tab_h(0,i) <= abs_h(0,j+1) ) compteur_h(0,j) +=1;
1056 }
1057 }
1058 Cerr<<"histogramme y+ compteur =";
1059 for (int j = 0; j < N; j++) Cerr<<" "<<compteur_h(0,j)<<" ";
1060 Cerr<<finl;
1061 Cerr<<"histogramme y+ abscisse =";
1062 for (int j = 0; j < N+1; j++) Cerr<<" "<<abs_h(0,j)<<" ";
1063 Cerr<<finl;
1064 Cerr<<"histogramme y+ : min = "<<h_yplus_min<<" - mean = "<<h_yplus_mean<<" - max = "<<h_yplus_max<<finl;
1065
1066 Cerr<<"Moyenne sur "<<yplus_count<<" points"<<finl;
1067 }
1068}
1069
1071{
1072 assert(Objet_U::dimension==3);
1073 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
1074 int nb_som=domaine_EF.domaine().nb_som();
1075 int nb_comp = Objet_U::dimension;
1076 const Domaine& dom = domaine_EF.domaine();
1077 DoubleTab& vitesse_imposee_mod = modele_lu_.variable_imposee_->valeurs();
1078 DoubleTab& vitesse_imposee_calculee = variable_imposee_;
1079 Interpolation_IBM_power_law_tbl_u_star& interp = ref_cast(Interpolation_IBM_power_law_tbl_u_star,interpolation_lue_.valeur());
1080 DoubleTab& is_dirichlet = interp.is_dirichlet_->valeurs();
1081 DoubleTab& solid_points = interp.solid_points_->valeurs();
1082 DoubleTab& solid_elems = interp.solid_elems_->valeurs();
1083 double A_pwl = interp.get_A_pwl(0);
1084 double B_pwl = interp.get_B_pwl();
1085 double y_c_p_pwl = interp.get_y_c_p_pwl();
1086 int impr_yplus = interp.get_impr() ;
1087 DoubleTab& vitesse_inconnue = equation().inconnue().valeurs();
1088 if (nb_comp != vitesse_inconnue.dimension(1))
1089 {
1090 Cerr<<"Source_PDF_EF::calculer_vitesse_imposee_power_law_tbl_u_star: variable must be a vector of dimension "<<Objet_U::dimension<<" ! "<<finl;
1091 abort();
1092 }
1093
1094 ArrOfInt cells(1);
1095
1096 // operateur(0) : diffusivite
1097 if (equation().nombre_d_operateurs()<1)
1098 {
1099 Cerr << "Source_PDF_EF : nombre_d_operateurs = "<<equation().nombre_d_operateurs()<<" < 1"<<finl;
1100 exit();
1101 }
1102 int flag = 0;
1103 const Op_Diff_EF_base& opdiffu = ref_cast(Op_Diff_EF_base,equation().operateur(0).l_op_base());
1104 flag = opdiffu.diffusivite().valeurs().dimension(0)>1 ? 1 : 0;
1105
1106 double eps = 1e-12;
1107 double d1_min = 1.0e+10;
1108 double d1_max = 0.0;
1109 double d1_mean = 0.0;
1110 double yplus_min = 1.0e+10;
1111 double yplus_max = 0.0;
1112 double yplus_mean = 0.0;
1113 double u_tau_min = 1.0e+10;
1114 double u_tau_max = 0.0;
1115 double u_tau_mean = 0.0;
1116 double yplus_ref_min = 1.0e+10;
1117 double yplus_ref_max = 0.0;
1118 double yplus_ref_mean = 0.0;
1119 double u_tau_ref_min = 1.0e+10;
1120 double u_tau_ref_max = 0.0;
1121 double u_tau_ref_mean = 0.0;
1122 double h_yplus_min = 1.0e+10;
1123 double h_yplus_max = 0.0;
1124 double h_yplus_mean = 0.0;
1125 int yplus_count=0 ;
1126 int yplus_ref_count=0 ;
1127
1128 int N = interp.get_N_histo();
1129 DoubleTab tab_h(1, nb_som);
1130 DoubleTab abs_h(1, N+1);
1131 DoubleTab compteur_h(1, N);
1132 compteur_h = 0.;
1133 tab_h = 0.;
1134
1135 vitesse_imposee_mod.echange_espace_virtuel();
1136 tab_u_star_ibm_ = 0.;
1137 tab_y_plus_ibm_ = 0.;
1138 // DoubleTrav nb_vois(is_dirichlet);
1139
1140 for (int i = 0; i < nb_som; i++)
1141 {
1142 double x = 0.;
1143 if (is_dirichlet(i) > 0.0)
1144 {
1145 int itisok_P = 1;
1146 double d1P = 0.0;
1147 DoubleTab normaleP(1, nb_comp);
1148 double norme_de_la_normaleP= 0.0;
1149 // normal et distance normale au point P
1150 for(int j = 0; j < nb_comp; j++)
1151 {
1152 vitesse_imposee_calculee(i,j) = vitesse_imposee_mod(i,j);
1153 x = dom.coord(i,j);
1154 double xp = solid_points(i,j);
1155 normaleP(0,j) = x - xp;
1156 norme_de_la_normaleP += normaleP(0,j)*normaleP(0,j);
1157 }
1158 norme_de_la_normaleP = sqrt(norme_de_la_normaleP);
1159 d1P = norme_de_la_normaleP;
1160 if (d1P > eps)
1161 for(int j = 0; j < nb_comp; j++) normaleP(0,j) /= norme_de_la_normaleP;
1162 else normaleP = 0.;
1163
1164 cells(0) = int(solid_elems(i)); //pour definir la viscosite laminaire
1165 double nu = (flag ? opdiffu.diffusivite().valeurs()(cells) : opdiffu.diffusivite().valeurs()(0,0));
1166
1167 double u_tau = 0.;
1168 double y_plus = 0.;
1169 if (d1P > eps)
1170 //le point P n'est pas sur la frontiere immergee
1171 {
1172 IntList& voisins = interp.getSommetsVoisinsOf(i);
1173 if (!(voisins.est_vide()))
1174 // il y a une liste de dof voisins
1175 {
1176 double u_tau_ref;
1177 double y_plus_ref;
1178 DoubleTab mean_u_tau_neighbour(1, nb_comp); // moyenne de u_tau vectoriel sur les dof voisins
1179 mean_u_tau_neighbour = 0.0;
1180 double mean_y_plus_neighbour = 0.; // moyenne de y_plus sur les dof voisins
1181 int taille = voisins.size();
1182 // nb_vois(i) = taille * 1.0 ;
1183 double pond_tot = 0.;
1184 double ponderation_k;
1185 for (int k = 0; k < taille; k++)
1186 // boucle sur les dof voisins
1187 {
1188 int num_som = voisins[k];
1189 int itisok = 1;
1190 double d1 = 0.0;
1191 DoubleTab a(1, nb_comp);
1192 DoubleTab b(1, nb_comp);
1193 double norme_a = 0.0;
1194 double norme_b = 0.0;
1195
1196 for (int j = 0; j < nb_comp; j++)
1197 {
1198 double xf = dom.coord(num_som,j);
1199 double xpf = solid_points(num_som,j);
1200 d1 += (xf - xpf)*(xf - xpf);
1201 a(0,j) = (xf - x);
1202 b(0,j) = (xf - x)*normaleP(0,j);
1203 norme_a += a(0,j)*a(0,j);
1204 norme_b += b(0,j)*b(0,j);
1205 }
1206 d1 = sqrt(d1);
1207 if ( d1 < eps ) itisok = 0;
1208
1209 if ( (norme_a - norme_b) > eps )
1210 ponderation_k = 1/(sqrt(norme_a - norme_b));
1211 else
1212 ponderation_k = 1./eps;
1213
1214 u_tau_ref = 0.;
1215 y_plus_ref = 0.;
1216 if (itisok)
1217 {
1218 // normale et tangente vitesse vis a vis de normalP
1219 double Vn = 0.;
1220 for(int j = 0; j < nb_comp; j++) Vn += vitesse_inconnue(num_som,j) * normaleP(0,j);
1221 DoubleTab vtf_k(1, nb_comp);
1222 for(int j = 0; j < nb_comp; j++) vtf_k(0, j) = vitesse_inconnue(num_som, j) - Vn * normaleP(0,j);
1223 double norme_vtf_k = 0.;
1224 for(int j = 0; j < nb_comp; j++) norme_vtf_k += vtf_k(0, j)*vtf_k(0,j);
1225 norme_vtf_k = sqrt(norme_vtf_k);
1226 u_tau_ref = pow ( norme_vtf_k , (1/(1+B_pwl)) ) * pow ( A_pwl, (-1/(1+B_pwl)) ) * pow ( d1 , (-B_pwl/(1+B_pwl)) ) * pow ( nu,(B_pwl/(1+B_pwl)) ) ; // vitesse de frottement power law au point fluide k
1227 y_plus_ref = d1 * u_tau_ref / nu;
1228 if (y_plus_ref < y_c_p_pwl ) // En fait, on est en lois lineaire !
1229 {
1230 u_tau_ref = pow ( (nu * norme_vtf_k / d1) , 0.5 ) ; // on recalcule u_tau_ref et y_plus_ref en lineaire au point fluide k
1231 y_plus_ref = d1 * u_tau_ref / nu;
1232 if ( y_plus_ref > y_c_p_pwl )
1233 {
1234 // Incoherence : on n utilise pas de lois de paroi
1235 itisok = 0;
1236 }
1237 }
1238
1239 // On moyenne les vecteurs vitesses de frottement tangents (vis a vis de P) par l'inverse des distances
1240 if (norme_vtf_k < eps) itisok = 0;
1241 if (itisok)
1242 {
1243 for(int j = 0; j < nb_comp; j++) mean_u_tau_neighbour(0,j) += (u_tau_ref * vtf_k(0, j) / norme_vtf_k) * ponderation_k;
1244 mean_y_plus_neighbour += y_plus_ref * ponderation_k;
1245 pond_tot += ponderation_k;
1246 }
1247 }
1248
1249 if (impr_yplus && itisok)
1250 {
1251 if (y_plus_ref > yplus_ref_max) yplus_ref_max = y_plus_ref;
1252 if (y_plus_ref < yplus_ref_min) yplus_ref_min = y_plus_ref;
1253 yplus_ref_mean += y_plus_ref;
1254 if (u_tau_ref > u_tau_ref_max) u_tau_ref_max = u_tau_ref;
1255 if (u_tau_ref < u_tau_ref_min) u_tau_ref_min = u_tau_ref;
1256 u_tau_ref_mean += u_tau_ref;
1257 yplus_ref_count += 1;
1258 }
1259
1260 }
1261
1262 // On calcul u_tau moyen, y_plus et la vitesse tangente au point force P
1263 if (pond_tot > 0.)
1264 {
1265 mean_u_tau_neighbour /= pond_tot; // u_tau moyen vectoriel
1266 mean_y_plus_neighbour /= pond_tot; // y_plus moyen
1267 u_tau = 0. ;
1268 for(int j = 0; j < nb_comp; j++) u_tau += mean_u_tau_neighbour(0,j) * mean_u_tau_neighbour(0,j);
1269 u_tau = sqrt(u_tau); // u_tau = norme de u_tau moyen vectoriel
1270 y_plus = u_tau * d1P / nu;
1271 if (u_tau > eps) mean_u_tau_neighbour /= u_tau;
1272 else mean_u_tau_neighbour = 0. ;// tangente en P
1273 if (y_plus > y_c_p_pwl ) // loi polynomiale
1274 {
1275 if (mean_y_plus_neighbour > y_c_p_pwl ) // coherence loi polynomiale
1276 {
1277 double vit_coeff = A_pwl * pow (d1P, B_pwl) / pow (nu, B_pwl);
1278 for (int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = pow (u_tau, (1+B_pwl)) * vit_coeff * mean_u_tau_neighbour(0,j);
1279 }
1280 else itisok_P = 0; // non coherence loi polynomiale
1281 }
1282 else // loi lineaire
1283 {
1284 if (mean_y_plus_neighbour < y_c_p_pwl ) // coherence loi lineaire
1285 {
1286 for (int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = (d1P * u_tau * u_tau / nu) * mean_u_tau_neighbour(0,j);
1287 }
1288 else itisok_P = 0; // non coherence loi lineaire
1289 }
1290 }
1291 // il n y a pas de contribution des dof voisins
1292 else itisok_P = 0;
1293 }
1294 else
1295 // il n y a pas de liste des dof voisins
1296 itisok_P = 0;
1297 }
1298 //le point P est sur la frontiere immergee : affectation
1299 else itisok_P = 0;
1300
1301 if(itisok_P)
1302 {
1303 // pour post-pro
1304 tab_u_star_ibm_(i) = u_tau;
1305 tab_y_plus_ibm_(i) = y_plus;
1306 }
1307
1308 if (impr_yplus && itisok_P)
1309 {
1310 if (d1P > d1_max) d1_max = d1P;
1311 if (d1P < d1_min) d1_min = d1P;
1312 d1_mean += d1P;
1313 if (y_plus > yplus_max) yplus_max = y_plus;
1314 if (y_plus < yplus_min) yplus_min = y_plus;
1315 yplus_mean += y_plus;
1316 if (u_tau > u_tau_max) u_tau_max = u_tau;
1317 if (u_tau < u_tau_min) u_tau_min = u_tau;
1318 u_tau_mean += u_tau;
1319 // Distribution des y+ au voisinage des parois
1320 if (y_plus > h_yplus_max) h_yplus_max = y_plus;
1321 if (y_plus < h_yplus_min) h_yplus_min = y_plus;
1322 h_yplus_mean += y_plus;
1323 tab_h(0,yplus_count) = y_plus;
1324 yplus_count += 1;
1325 }
1326 }
1327 else
1328 {
1329 for(int j = 0; j < nb_comp; j++) vitesse_imposee_calculee(i,j) = vitesse_imposee_mod(i,j);
1330 }
1331 }
1332 //vitesse_imposee_calculee.echange_espace_virtuel();
1333
1334 if (impr_yplus && (yplus_count >= 1) && (yplus_ref_count >= 1) )
1335 {
1336 d1_mean /= yplus_count;
1337 yplus_mean /= yplus_count;
1338 yplus_ref_mean /= yplus_ref_count;
1339 u_tau_mean /= yplus_count;
1340 u_tau_ref_mean /= yplus_ref_count;
1341 Cerr<<"min mean max y = "<<d1_min<<" "<<d1_mean<<" "<<d1_max<<finl;
1342 Cerr<<"min mean max y+ = "<<yplus_min<<" "<<yplus_mean<<" "<<yplus_max<<finl;
1343 Cerr<<"min mean u_tau = "<<u_tau_min<<" "<<u_tau_mean<<" "<<u_tau_max<<finl;
1344 Cerr<<"min mean max y+_ref = "<<yplus_ref_min<<" "<<yplus_ref_mean<<" "<<yplus_ref_max<<finl;
1345 Cerr<<"min mean u_tau_ref = "<<u_tau_ref_min<<" "<<u_tau_ref_mean<<" "<<u_tau_ref_max<<finl;
1346
1347 h_yplus_mean /= yplus_count;
1348 double range = ( h_yplus_max - h_yplus_min)/N;
1349 for (int k = 0; k < N+1; k++) abs_h(0,k) = (h_yplus_min + k*range);
1350 for (int i=0; i < yplus_count; i++)
1351 {
1352 for (int j = 0; j < N; j++)
1353 {
1354 if ( abs_h(0,j) < tab_h(0,i) && tab_h(0,i) <= abs_h(0,j+1) ) compteur_h(0,j) +=1;
1355 }
1356 }
1357 Cerr<<"histogramme y+ compteur =";
1358 for (int j = 0; j < N; j++) Cerr<<" "<<compteur_h(0,j)<<" ";
1359 Cerr<<finl;
1360 Cerr<<"histogramme y+ abscisse =";
1361 for (int j = 0; j < N+1; j++) Cerr<<" "<<abs_h(0,j)<<" ";
1362 Cerr<<finl;
1363 Cerr<<"histogramme y+ : min = "<<h_yplus_min<<" - mean = "<<h_yplus_mean<<" - max = "<<h_yplus_max<<finl;
1364
1365 Cerr<<"Moyenne sur "<<yplus_count<<" points forces et "<<yplus_ref_count<<" points references"<<finl;
1366 }
1367}
1368
1369/*##################################################################################################
1370####################################################################################################
1371################################# Pression #########################################################
1372####################################################################################################
1373##################################################################################################*/
1374
1375void Source_PDF_EF::correct_incr_pressure(const DoubleTab& coeff_node, DoubleTab& correction_en_pression) const
1376{
1377 const DoubleTab& aire=champ_aire_->valeurs();
1378 int nb_elem = correction_en_pression.size();
1379
1380 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
1381 const IntTab& elems= domaine_EF.domaine().les_elems();
1382 int nb_som_elem=domaine_EF.domaine().nb_som_elem();
1383 int ncomp = coeff_node.dimension(1) ;
1384 DoubleTrav coef_elem(nb_elem);
1385
1386 DoubleTrav flag_cl(coeff_node);
1387 filtre_CLD(flag_cl);
1388
1389 // int nb_som=domaine_EF.domaine().nb_som();
1390 // for(int som=0; som<nb_som; som++)Cerr<<"som flag_c = "<<som<<" "<<flag_cl(som,0)<<" "<<flag_cl(som,1)<<" "<<flag_cl(som,2)<<finl;
1391
1392 for(int num_elem=0; num_elem<nb_elem; num_elem++)
1393 {
1394 if (aire(num_elem)>0.)
1395 {
1396 correction_en_pression(num_elem) = 0.;
1397 }
1398 else
1399 {
1400 coef_elem(num_elem) = 0. ;
1401 for (int i=0; i<nb_som_elem; i++)
1402 {
1403 int sii=elems(num_elem,i);
1404 for (int comp=0; comp<ncomp; comp++)
1405 {
1406 if ((coeff_node(sii,comp)!= 1.0) || (flag_cl(sii,comp) != 1.0)) coef_elem(num_elem) += 1. ;
1407 }
1408 }
1409 if (coef_elem(num_elem) == (ncomp*nb_som_elem)) correction_en_pression(num_elem) = 0.;
1410 }
1411 }
1412}
1413
1414void Source_PDF_EF::correct_pressure(const DoubleTab& coeff_node, DoubleTab& pression, const DoubleTab& correction_en_pression) const
1415{
1416 const DoubleTab& aire=champ_aire_->valeurs();
1417 int nb_elem = pression.size();
1418
1419 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
1420 const IntTab& elems= domaine_EF.domaine().les_elems();
1421 int nb_som_elem=domaine_EF.domaine().nb_som_elem();
1422 int ncomp = coeff_node.dimension(1) ;
1423 DoubleTrav coef_elem(nb_elem);
1424
1425 DoubleTrav flag_cl(coeff_node);
1426 filtre_CLD(flag_cl);
1427
1428 for(int num_elem=0; num_elem<nb_elem; num_elem++)
1429 {
1430 if (aire(num_elem)<=0.)
1431 {
1432 coef_elem(num_elem) = 0. ;
1433 for (int i=0; i<nb_som_elem; i++)
1434 {
1435 int sii=elems(num_elem,i);
1436 for (int comp=0; comp<ncomp; comp++)
1437 {
1438 if ((coeff_node(sii,comp)!= 1.0) || (flag_cl(sii,comp) != 1.0)) coef_elem(num_elem) += 1. ;
1439 }
1440 }
1441 if (coef_elem(num_elem) != (ncomp*nb_som_elem)) pression(num_elem)+=correction_en_pression(num_elem);
1442 }
1443 }
1444}
1445
1446void Source_PDF_EF::filtre_CLD(DoubleTab& flag_cl) const
1447{
1448 const Domaine_Cl_EF& le_dom_cl = le_dom_Cl_EF.valeur();
1449 int nb_cond_lim = le_dom_cl.nb_cond_lim();
1450 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
1451 const IntTab& faces_sommets=domaine_EF.face_sommets();
1452 int nb_som_face=faces_sommets.dimension(1);
1453 int nb_comp = flag_cl.dimension(1);
1454 flag_cl = 1.;
1455 for (int ij=0; ij<nb_cond_lim; ij++)
1456 {
1457 const Cond_lim_base& la_cl_base = le_dom_cl.les_conditions_limites(ij).valeur();
1458 const Front_VF& le_bord = ref_cast(Front_VF,le_dom_cl.les_conditions_limites(ij)->frontiere_dis());
1459 int nfaces = le_bord.nb_faces_tot();
1460 if (sub_type(Dirichlet,la_cl_base))
1461 {
1462 for (int ind_face=0; ind_face < nfaces; ind_face++)
1463 {
1464 for (int s=0; s<nb_som_face; s++)
1465 {
1466 int face=le_bord.num_face(ind_face);
1467 int som=faces_sommets(face,s);
1468 for (int comp=0; comp<nb_comp; comp++) flag_cl(som,comp) = 0. ;
1469 }
1470 }
1471 }
1472 }
1473 //vector; NS
1474 if (nb_comp == Objet_U::dimension) le_dom_cl.imposer_symetrie(flag_cl,0);
1475 flag_cl.echange_espace_virtuel();
1476 return;
1477}
1478
1479/*##################################################################################################
1480####################################################################################################
1481################################# Impression #######################################################
1482####################################################################################################
1483##################################################################################################*/
1484
1486{
1487 if (out_=="??")
1488 {
1489 Cerr << __FILE__ << (int)__LINE__ << " ERROR / Source_PDF_EF::impr" << finl;
1490 Cerr << "No balance printed for " << que_suis_je() << finl;
1491 Cerr << "Because output file name is not specified." << finl;
1492 return 0;
1493 }
1494 else
1495 {
1496 int nb_compo=bilan_.size();
1497 if (nb_compo==0)
1498 {
1499 Cerr << __FILE__ << (int)__LINE__ << " ERROR / Source_PDF_EF::impr" << finl;
1500 Cerr << "No balance printed for " << que_suis_je() << finl;
1501 Cerr << "Because bilan_ array is not filled." << finl;
1502 return 0;
1503 }
1504 else
1505 {
1507 double temps=sch.temps_courant();
1508 double pdtps = sch.pas_de_temps();
1509 if (temps == pdtps)
1510 {
1511 int flag = Process::je_suis_maitre();
1512 if(flag) ouvrir_fichier(Flux,"",flag);
1513 return 0;
1514 }
1515 const DoubleTab& variable=equation().inconnue().valeurs();
1516 Nom espace=" \t";
1517
1518 int nb_comp = variable.dimension(1);
1519 assert(nb_comp == modele_lu_.dim_variable_);
1520 int pdf_dt_conv = modele_lu_.pdf_bilan();
1521
1522 DoubleTrav secmem_conv(variable);
1523 // defaut pdf_dt_conv = 0
1524 secmem_conv = 0.;
1525 int i_traitement_special = 0;
1526
1527 if (pdf_dt_conv == 1 || pdf_dt_conv == 2)
1528 // pdf_dt_conv = 1 ou 2
1529 {
1530 if (nb_comp == Objet_U::dimension)
1531 {
1532 //vector; NS
1533 Navier_Stokes_std& eq_NS = ref_cast_non_const(Navier_Stokes_std, equation());
1534 int transport_rhou=0;
1535 if (eq_NS.nombre_d_operateurs() > 1)
1536 {
1537 transport_rhou= (eq_NS.vitesse_pour_transport().le_nom()=="rho_u"?1:0);
1538 if (pdf_dt_conv == 2) eq_NS.derivee_en_temps_conv(secmem_conv , variable);
1539 }
1540 i_traitement_special = (transport_rhou==1?2:102);
1541 }
1542 else if (nb_comp == 1)
1543 {
1544 //scalar; temps en rho
1545 Equation_base& eq_Ba = ref_cast_non_const(Equation_base, equation());
1546 if (equation().nombre_d_operateurs() > 1)
1547 {
1548 if (pdf_dt_conv == 2) eq_Ba.derivee_en_temps_conv(secmem_conv , variable);
1549 }
1550 i_traitement_special = 2;
1551 }
1552 else
1553 {
1554 Cerr << "Source_PDF_EF: for scalar or vector only; dim = " <<nb_comp<< finl;
1555 Process::exit();
1556 }
1557 }
1558 else if(pdf_dt_conv != 0 )
1559 {
1560 Cerr<<"Source_PDF_EF: Modele pdf_bilan must be 0; 1 or 2 only"<<finl;
1561 Process::exit();
1562 }
1563
1564 Source_PDF_base& my_src = ref_cast_non_const(Source_PDF_base,*this);
1565 my_src.compute_source_term_PDF(i_traitement_special, secmem_conv, bilan_);
1566
1567 int flag = Process::je_suis_maitre();
1568 if(flag)
1569 {
1570 ouvrir_fichier(Flux,"",flag);
1571 if(nb_comp == Objet_U::dimension)
1572 {
1573 // vector
1574 assert(Objet_U::dimension==3);
1575 Flux << temps << espace << bilan_(0) << espace << bilan_(1) << espace << bilan_(2) << finl;
1576 }
1577 else
1578 {
1579 // scalar
1580 Flux << temps << espace << bilan_(0) << finl;
1581 }
1582 }
1583 }
1584 return 1;
1585 }
1586}
1587// void imprimer_ustar_yplus__mean_only(Sortie&, const Nom& ) const override;
1588
1589
1590/*##################################################################################################
1591####################################################################################################
1592################################# POSTRAITEMENT ####################################################
1593####################################################################################################
1594##################################################################################################*/
1595
1597{
1599
1600 if (motlu=="u_star_ibm" && !champ_u_star_ibm_ && imm_wall_law_)
1601 {
1602 int nb_comp = 1;
1603 Noms noms(1);
1604 noms[0]="u_star_ibm";
1605 Noms unites(1);
1606 unites[0] = "m/s";
1607 double temps=0.;
1609 discr.discretiser_champ("champ_sommets",equation().domaine_dis(),scalaire,noms,unites,nb_comp,temps,champ_u_star_ibm_);
1610 champs_compris_.ajoute_champ(champ_u_star_ibm_);
1611 }
1612 else if (motlu=="y_plus_ibm" && !champ_y_plus_ibm_ && imm_wall_law_)
1613 {
1614 int nb_comp = 1;
1615 Noms noms(1);
1616 noms[0]="y_plus_ibm";
1617 Noms unites(1);
1618 unites[0] = "-";
1619 double temps=0.;
1621 discr.discretiser_champ("champ_sommets",equation().domaine_dis(),scalaire,noms,unites,nb_comp,temps,champ_y_plus_ibm_);
1622 champs_compris_.ajoute_champ(champ_y_plus_ibm_);
1623 }
1624}
1625
1626bool Source_PDF_EF::has_champ(const Motcle& nom, OBS_PTR(Champ_base) &ref_champ) const
1627{
1628 if (Source_PDF_base::has_champ(nom)) return Source_PDF_base::has_champ(nom, ref_champ);
1629
1630 if (nom == "u_star_ibm" && champ_u_star_ibm_)
1631 {
1632 ref_champ = Source_PDF_EF::get_champ(nom);
1633 return true;
1634 }
1635 else if (nom == "y_plus_ibm" && champ_y_plus_ibm_)
1636 {
1637 ref_champ = Source_PDF_EF::get_champ(nom);
1638 return true;
1639 }
1640 else
1641 return false; /* rien trouve */
1642}
1643
1644bool Source_PDF_EF::has_champ(const Motcle& nom) const
1645{
1646 if (Source_PDF_base::has_champ(nom)) return true;
1647
1648 if (nom == "u_star_ibm" && champ_u_star_ibm_)
1649 return true;
1650 else if (nom == "y_plus_ibm" && champ_y_plus_ibm_)
1651 return true;
1652 else
1653 return false; /* rien trouve */
1654}
1655
1657{
1659
1660 if (nom=="u_star_ibm")
1661 {
1662 if (!champ_u_star_ibm_)
1663 throw std::runtime_error(std::string("Field ") + nom.getString() + std::string(" not found !"));
1664
1665 // Initialisation a 0 du champ volumique u_star
1666 DoubleTab& valeurs = champ_u_star_ibm_->valeurs();
1667 valeurs=0;
1668 if (tab_u_star_ibm_.size_array()>0)
1669 {
1670 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
1671 int nb_som=domaine_EF.domaine().nb_som();
1672 for (int num_node=0; num_node<nb_som; num_node++)
1673 valeurs(num_node)=tab_u_star_ibm_(num_node);
1674 }
1675 valeurs.echange_espace_virtuel();
1676 champ_u_star_ibm_->mettre_a_jour(equation().probleme().schema_temps().temps_courant());
1677 return champs_compris_.get_champ(nom);
1678 }
1679 else if (nom=="y_plus_ibm")
1680 {
1681 if (!champ_y_plus_ibm_)
1682 throw std::runtime_error(std::string("Field ") + nom.getString() + std::string(" not found !"));
1683
1684 // Initialisation a 0 du champ volumique u_star
1685 DoubleTab& valeurs = champ_y_plus_ibm_->valeurs();
1686 valeurs=0;
1687 if (tab_y_plus_ibm_.size_array()>0)
1688 {
1689 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
1690 int nb_som=domaine_EF.domaine().nb_som();
1691 for (int num_node=0; num_node<nb_som; num_node++)
1692 valeurs(num_node)=tab_y_plus_ibm_(num_node);
1693 }
1694 valeurs.echange_espace_virtuel();
1695 champ_y_plus_ibm_->mettre_a_jour(equation().probleme().schema_temps().temps_courant());
1696 return champs_compris_.get_champ(nom);
1697 }
1698 else
1699 return champs_compris_.get_champ(nom);
1700}
1701
1703{
1705
1706 Noms noms_compris = champs_compris_.liste_noms_compris();
1707 if(imm_wall_law_)
1708 {
1709 noms_compris.add("u_star_ibm");
1710 noms_compris.add("y_plus_ibm");
1711 }
1712 if (opt==DESCRIPTION)
1713 Cerr<<" Source_PDF_EF : "<< noms_compris <<finl;
1714 else
1715 nom.add(noms_compris);
1716}
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual DoubleTab & valeurs()=0
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
void value_interpolation(const DoubleTab &positions, const ArrOfInt &cells, const DoubleTab &values, DoubleTab &resu, int ncomp=-1) const override
classe Cond_lim_base Classe de base pour la hierarchie des classes qui representent les differentes c...
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
Definition Dirichlet.h:31
classe Discretisation_base Cette classe represente un schema de discretisation en espace,...
void discretiser_champ(const Motcle &directive, const Domaine_dis_base &z, const Nom &nom, const Nom &unite, int nb_comp, int nb_pas_dt, double temps, OWN_PTR(Champ_Inc_base)&champ, const Nom &sous_type=NOM_VIDE) const
int nb_som_elem() const
Renvoie le nombre de sommets des elements geometriques constituants le domaine.
Definition Domaine.h:474
int_t nb_elem_tot() const
Definition Domaine.h:132
IntTab_t & les_elems()
Definition Domaine.h:129
double coord(int_t i, int j) const
Definition Domaine.h:110
int_t nb_som() const
Renvoie le nombre de sommets du domaine.
Definition Domaine.h:121
void imposer_symetrie(DoubleTab &, int tous_les_sommets_sym=0) const
Impose les conditions de symetrie c.
classe Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
int nb_cond_lim() const
Renvoie le nombre de conditions aux limites.
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
class Domaine_EF
Definition Domaine_EF.h:59
const DoubleVect & volumes_thilde() const
Definition Domaine_EF.h:85
int face_sommets(int i, int j) const
renvoie le numero du ieme sommet de la face num_face.
Definition Domaine_VF.h:583
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
DoubleTab & derivee_en_temps_conv(DoubleTab &, const DoubleTab &)
Add convection term In: solution is the unknown I.
virtual const Champ_Inc_base & inconnue() const =0
virtual int nombre_d_operateurs() const =0
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
class Front_VF
Definition Front_VF.h:36
int nb_faces_tot() const
Definition Front_VF.h:58
int num_face(const int) const
Definition Front_VF.h:68
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
DoubleVect & ajouter_multvect_(const DoubleVect &, DoubleVect &) const override
Operation de multiplication-accumulation (saxpy) matrice vecteur.
double coef(int i, int j) const
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
classe Navier_Stokes_std Cette classe porte les termes de l'equation de la dynamique
virtual const Champ_base & vitesse_pour_transport() const
int nombre_d_operateurs() const override
Renvoie le nombre d'operateurs de l'equation: Pour Navier Stokes Standard c'est 2.
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const std::string & getString() const
Definition Nom.h:92
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
static int dimension
Definition Objet_U.h:99
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual const Nom & le_nom() const
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Objet_U.cpp:319
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
class Op_Diff_EF_base Classe de base des operateurs de diffusion EF
virtual const Champ_base & diffusivite() const =0
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
const Discretisation_base & discretisation() const
Renvoie la discretisation associee au probleme.
const Schema_Temps_base & schema_temps() const
Renvoie le schema en temps associe au probleme.
static void abort()
Routine de sortie de Trio-U sur une erreur abort().
Definition Process.cpp:570
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
class Schema_Temps_base
double temps_courant() const
Renvoie le temps courant.
double pas_de_temps() const
Renvoie le pas de temps (delta_t) courant.
Classe de base des flux de sortie.
Definition Sortie.h:52
void calculer_variable_imposee_hybrid() override
void filtre_CLD(DoubleTab &) const override
const Champ_base & get_champ(const Motcle &nom) const override
void correct_incr_pressure(const DoubleTab &, DoubleTab &) const override
DoubleTab & ajouter_(const DoubleTab &, DoubleTab &) const override
void calculer_variable_imposee_elem_fluid() override
DoubleVect tab_u_star_ibm_
valeurs des u* IBM calculees localement
void creer_champ(const Motcle &motlu) override
DoubleVect tab_y_plus_ibm_
valeurs des d+ IBM calculees localement
void associer_pb(const Probleme_base &) override
void verif_ajouter_contrib(const DoubleTab &variable, Matrice_Morse &matrice) const
void multiply_coeff_volume(DoubleTab &) const override
void compute_indicateur_nodal_champ_aire() override
void calculer_variable_imposee_mean_grad() override
bool has_champ(const Motcle &nom, OBS_PTR(Champ_base) &ref_champ) const override
void associer_domaines(const Domaine_dis_base &, const Domaine_Cl_dis_base &) override
void calculer_vitesse_imposee_power_law_tbl() override
void calculer_vitesse_imposee_power_law_tbl_u_star() override
void correct_pressure(const DoubleTab &, DoubleTab &, const DoubleTab &) const override
void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const override
contribution a la matrice implicite des termes sources par defaut pas de contribution
void volume_source_term_PDF(DoubleTab &) override
OBS_PTR(Domaine_EF) le_dom_EF
int impr(Sortie &) const override
void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const override
class Source_PDF_base Base class for the source terms for the penalisation of the momentum in the Imm...
DoubleTab compute_pond(const DoubleTab &rho_m, const DoubleTab &aire, const DoubleVect &volume_thilde, int &nb_som_elem, int &nb_elems) const
void creer_champ(const Motcle &motlu) override
void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const override
DoubleVect & compute_source_term_PDF(int, DoubleTab &, DoubleVect &)
virtual void compute_indicateur_nodal_champ_aire()
void ouvrir_fichier(SFichier &, const Nom &, const int) const override
Ouverture/creation d'un fichier d'impression d'un terme source A surcharger dans les classes derivees...
DoubleTab indicateur_nodal_champ_aire_
const Champ_base & get_champ(const Motcle &) const override
void associer_pb(const Probleme_base &) override
bool has_champ(const Motcle &nom, OBS_PTR(Champ_base) &ref_champ) const override
DoubleTab variable_imposee_
Champs_compris champs_compris_
DoubleVect & bilan()
Definition Source_base.h:88
SFichier Flux
DoubleVect bilan_
int est_vide() const
int size() const
Definition TRUSTList.h:68
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45
_SIZE_ size_totale() const
Definition TRUSTVect.tpp:61
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")