TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Source_PDF_VDF.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_VDF.h>
17#include <Domaine.h>
18#include <Domaine_VDF.h>
19#include <Domaine_Cl_VDF.h>
20#include <Probleme_base.h>
21#include <Equation_base.h>
22#include <Schema_Temps_base.h>
23#include <Discretisation_base.h>
24#include <Matrice_Morse.h>
25#include <Matrice_Bloc.h>
26#include <TRUSTTrav.h>
27#include <Champ_Face_VDF.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_Diff_VDF_base.h>
36// #include <Op_Conv_VDF.h>
37
38Implemente_instanciable(Source_PDF_VDF,"Source_PDF_VDF_Face",Source_PDF_base);
39
40/*##################################################################################################
41####################################################################################################
42################################# READON AND PRINTON ###############################################
43####################################################################################################
44##################################################################################################*/
45
47{
49 return s;
50}
51
53{
55 return s;
56}
57
58/*##################################################################################################
59####################################################################################################
60################################# PROBLEM ASSOCIATION AND ZONES ####################################
61####################################################################################################
62##################################################################################################*/
63
65{
67
68 int nb_som=le_dom_VDF->nb_som();
69 tab_u_star_ibm_.resize(nb_som);
70 tab_y_plus_ibm_.resize(nb_som);
71}
72
77
79 const Domaine_Cl_dis_base& domaine_Cl_dis)
80{
81 le_dom_VDF = ref_cast(Domaine_VDF, domaine_dis);
82 le_dom_Cl_VDF = ref_cast(Domaine_Cl_VDF, domaine_Cl_dis);
83}
84
85void Source_PDF_VDF::multiply_coeff_volume(DoubleTab& coeff) const
86{
87 const DoubleVect& vol=ref_cast(Domaine_VDF, le_dom_VDF.valeur()).volumes_entrelaces();
88 int n = vol.size_totale();
89 int nc = coeff.dimension_tot(0) ;
90 if (n != nc)
91 {
92 Cerr<<" dimensions differentes n nc = "<<n<<" "<<nc<<finl;
93 exit();
94 }
95 int ndim = coeff.dimension(1) ;
96 for (int i=0; i<n; i++)
97 {
98 for (int comp=0; comp<ndim; comp++) coeff(i,comp) = coeff(i,comp)*vol(i);
99 }
100}
101
102/*##################################################################################################
103####################################################################################################
104################################# AJOUTER_ #########################################################
105###########################################################pond#########################################
106##################################################################################################*/
107
108/*
109This function redirects toward the ajouter_ which correspond to the model chosen.
110*/
111
112DoubleTab& Source_PDF_VDF::ajouter_(const DoubleTab& variable, DoubleTab& resu, const int i_traitement_special) const
113{
114 // calcul de : coefficient rho/dt * coeff_relax * (volume_thilde / 8) * variable
115 /* i_traitement_special = 0 => traitement classique; coefficient (1/eta) */
116 /* i_traitement_special = 1 => coefficient (1/eta -> 1) */
117 /* i_traitement_special = 2 => coefficient (1/eta -> 1 + 1/eta) */
118
119 const Domaine_VDF& domaine_VDF = le_dom_VDF.valeur();
120 const IntTab& elems= domaine_VDF.elem_faces() ;
121 int nb_face_elem=domaine_VDF.domaine().nb_faces_elem();
122 int nb_elems=domaine_VDF.domaine().nb_elem_tot();
123 const DoubleVect& volume=domaine_VDF.volumes_entrelaces();
124 int dim_esp = Objet_U::dimension ;
125 int dim_var = variable.dimension(1);
126 // Cerr << "erreur ici" << finl;
127 if (dim_var != 1 && dim_var != dim_esp)
128 {
129 Cerr<<"ajouter_: dimension variable differente 1 ou "<<dim_esp<<"! "<<finl;
130 exit();
131 }
132 ArrOfDouble tuvw(dim_var);
133 const DoubleTab& aire=champ_aire_->valeurs();
134 //OWN_PTR(Champ_Don_base) rho_test;
135 //champ_rho_->affecter(equation().probleme().get_champ("masse_volumique"));
136 const DoubleTab& rho_m=champ_rho_->valeurs();
137 DoubleTab pond;
138
139 // return = rho/dt * coeff_relax * volume
140 int coef1 = nb_face_elem;
141 pond = compute_pond(rho_m, aire, volume, coef1, nb_elems);
142
143 for (int num_elem=0; num_elem<nb_elems; num_elem++)
144 {
145 if (aire(num_elem)>0.)
146 {
147 if (i_traitement_special == 0)
148 {
149 tuvw[0] = 1.0 / modele_lu_.eta_;
150 }
151 else if (i_traitement_special == 1) //terme temps en rho v
152 {
153 tuvw[0] = 1.0;
154 }
155 else if (i_traitement_special == 101) //terme temps en v
156 {
157 tuvw[0] = 1.0 / rho_m(num_elem);
158 }
159 else if (i_traitement_special == 2)
160 {
161 tuvw[0] = 1.0 + 1.0 / modele_lu_.eta_;
162 }
163 else if (i_traitement_special == 102)
164 {
165 tuvw[0] = 1.0 / rho_m(num_elem) + 1.0 / modele_lu_.eta_;
166 }
167 else
168 {
169 Cerr << "Source_PDF_VDF::ajouter_ : i_traitement_special should be 0, 1, 2, 101 or 102" << finl;
170 exit();
171 }
172 double tijvj=0;
173 tijvj = tuvw[0];
174 // Cerr<< "Source_PDF_VEF::ajouter_ tijvj=" <<tijvj<<" pond("<<num_elem<<") = "<<pond(num_elem)<< finl;
175 // cas generique : 1/eta rho/dt * coeff_relax * volume * variable
176 for (int i=0; i<nb_face_elem; i++)
177 {
178 resu(elems(num_elem,i),0)-=pond(num_elem)*coef1*tijvj*variable(elems(num_elem,i),0);
179 // Cerr<< "Source_PDF_VEF::ajouter_ noeud: "<<i <<" "<<pond(num_elem)*coef1*tijvj*variable(elems(num_elem,i),comp)<<" variable = "<<variable(elems(num_elem,i),comp)<< finl;
180 }
181 }
182 }
183 return resu;
184}
185
186DoubleTab& Source_PDF_VDF::ajouter_(const DoubleTab& variable, DoubleTab& resu) const
187{
188 const int i_traitement_special = 0 ;
189 ajouter_(variable, resu, i_traitement_special) ;
190 return resu;
191}
192
193/*##################################################################################################
194####################################################################################################
195################################# CONTRIBUER_A_AVEC ################################################
196####################################################################################################
197##################################################################################################*/
198
199/*
200This function redirects toward the contribuer_avec_ which correspond to the model chosen.
201*/
202
203void Source_PDF_VDF::contribuer_a_avec(const DoubleTab& inco, Matrice_Morse& matrice) const
204{
205 // calcul : 1/eta rho/dt * coeff_relax * volume
206 const Domaine_VDF& domaine_VDF = le_dom_VDF.valeur();
207 const IntTab& elems= domaine_VDF.elem_faces();
208 int nb_face_elem=domaine_VDF.domaine().nb_faces_elem();
209 int nb_elems=domaine_VDF.domaine().nb_elem_tot();
210 const DoubleVect& volume=domaine_VDF.volumes_entrelaces();
211 const DoubleTab& variable=equation().inconnue().valeurs();
212 int dim_var = variable.dimension(1);
213 int dim_esp = Objet_U::dimension ;
214 if (dim_var != 1 && dim_var != dim_esp)
215 {
216 Cerr<<"contribuer_a_avec: dimension variable differente 1 ou "<<dim_esp<<"! "<<finl;
217 exit();
218 }
219 ArrOfDouble tuvw(dim_var);
220 const DoubleTab& aire=champ_aire_->valeurs();
221 //champ_rho_->affecter(equation().probleme().get_champ("masse_volumique"));
222 const DoubleTab& rho_m=champ_rho_->valeurs();
223 DoubleTab pond ;
224
225 // return = rho/dt * coeff_relax * volume pour elements interceptes
226 int coef1 = nb_face_elem;
227 pond = compute_pond(rho_m, aire, volume, coef1, nb_elems);
228
229 for (int num_elem=0; num_elem<nb_elems; num_elem++) //elements loop
230 {
231 if (aire(num_elem)>0.)
232 {
233 tuvw[0] = 1.0 / modele_lu_.eta_;
234 // Cerr<< "Source_PDF_VDF::contribuer_a_avec: tuvw=" <<tuvw<<" pond("<<num_elem<<") = "<<pond(num_elem)<< finl;
235 for (int i=0; i<nb_face_elem; i++)
236 {
237 for (int j=0; j<nb_face_elem; j++)
238 {
239 int s1=elems(num_elem,i);
240 double coeff_im=0;
241 coeff_im = tuvw[0];
242 int c1=s1*dim_var;
243 // Cerr << c1 << finl;
244
245 // 1.0/eta * rho/dt * coeff_relax * volume
246 matrice.coef(c1,c1)+=pond(num_elem)*coeff_im;
247 // Cerr<< "Source_PDF_VDF::contribuer_a_avec: contribution matrice c1c1 : "<<c1<<" = "<<pond(num_elem)*coeff_im<< finl;
248 }
249 }
250 }
251 }
252 // verif_ajouter_contrib(variable, matrice) ;
253}
254
255void Source_PDF_VDF::verif_ajouter_contrib(const DoubleTab& variable, Matrice_Morse& matrice) const
256{
257 const Domaine_VDF& domaine_VDF = le_dom_VDF.valeur();
258 const IntTab& elems= domaine_VDF.elem_faces();
259 int nb_face_elem=domaine_VDF.domaine().nb_faces_elem();
260 int nb_elems=domaine_VDF.domaine().nb_elem_tot();
261 const DoubleTab& aire=champ_aire_->valeurs();
262
263 DoubleTrav force(variable);
264 int dim_var = variable.dimension(1);
265 ajouter_(variable,force);
266 DoubleTrav force2(variable);
267 matrice.ajouter_multvect_(variable, force2) ;
268 DoubleTab diforce(force);
269 diforce += force2 ;
270 double difmax = 0.;
271 for (int num_elem=0; num_elem<nb_elems; num_elem++)
272 {
273 if (aire(num_elem)>0.)
274 {
275 for (int i=0; i<nb_face_elem; i++)
276 {
277 int s1=elems(num_elem,i);
278 double difmod2 = 0.;
279 for (int k=0; k<dim_var; k++) difmod2 += diforce(s1,k)*diforce(s1,k);
280 if (difmod2 > 1.0e-5)
281 {
282 if (difmod2 > difmax) difmax = difmod2 ;
283 // for (int k=0; k<dim_var; k++) Cerr << " ajouter multvect diforce x = "<< force(s1,k) << " "<< force2(s1,k) << " " << diforce(s1,k)<<finl;
284 }
285 }
286 }
287 }
288 if (difmax > 0.)
289 {
290 Cerr<< "Source_PDF: Max norme caree diff. force absolue = "<<difmax<<finl;
291 }
292}
293
294/*##################################################################################################
295####################################################################################################
296################################# calculer_variable_imposee ########################################
297####################################################################################################
298##################################################################################################*/
299
301{
302 const Domaine_VDF& domaine_VDF = le_dom_VDF.valeur();
303 int nb_faces=domaine_VDF.nb_faces();
304 int dim_esp = Objet_U::dimension;
305 const Domaine& dom = domaine_VDF.domaine();
306 const IntTab& faces_sommets=domaine_VDF.face_sommets();
307 int nb_som_face=faces_sommets.dimension(1);
308 int nb_som = domaine_VDF.nb_som();
309 DoubleTab& variable_imposee_mod = modele_lu_.variable_imposee_->valeurs();
310 int nb_comp_real = 3;
311 DoubleTab& variable_imposee_calculee = variable_imposee_;
312 Interpolation_IBM_elem_fluid& interp = ref_cast(Interpolation_IBM_elem_fluid,interpolation_lue_.valeur());
313 DoubleTab& fluid_points = interp.fluid_points_->valeurs();
314 DoubleTab& solid_points = interp.solid_points_->valeurs();
315 DoubleTab& fluid_elems = interp.fluid_elems_->valeurs();
316 Champ_Face_VDF& champ_variable_inconnue = ref_cast(Champ_Face_VDF,equation().inconnue());
317 DoubleTab variable_imposee_sommet(nb_som,nb_comp_real);
318 IntTab sommet_interp(nb_som);
319 DoubleTab xf(1, nb_comp_real);
320 DoubleTab vf(1, nb_comp_real);
321 ArrOfInt cells(1);
322 double eps = 1e-12;
323 variable_imposee_calculee = 0.0;
324 variable_imposee_sommet = 0.0;
325 sommet_interp = 0;
326 for (int i = 0; i < nb_som; i++)
327 {
328 if ((fluid_elems(i) >= 0.0))
329 {
330 sommet_interp(0, i) = 1;
331 double d1 = 0.0;
332 double d2 = 0.0;
333 for(int j = 0; j < dim_esp; j++)
334 {
335 double xj = dom.coord(i,j);
336 double xjf = fluid_points(i,j);
337 xf(0, j) = xjf;
338 double xjs = solid_points(i,j);
339 d1 += (xj-xjs)*(xj-xjs);
340 d2 += (xjf-xj)*(xjf-xj);
341 }
342 d1 = sqrt(d1);
343 d2 = sqrt(d2);
344 double inv_d ;
345 if ( (d1 + d2) > eps ) inv_d = 1.0 / (d1 + d2);
346 else inv_d = 0. ;
347 cells[0] = int(fluid_elems(i));
348 for(int j = 0; j < nb_comp_real; j++) vf(0, j) = champ_variable_inconnue.valeur_a_elem_compo(xf, cells[0], j);
349 for (int j = 0; j < nb_comp_real; j++)
350 {
351 double vjs = variable_imposee_mod(i,j);
352 variable_imposee_sommet(i,j) = vjs + (vf(0, j)-vjs)*inv_d*d1;
353 }
354 }
355 else
356 {
357 for(int j = 0; j < nb_comp_real; j++)
358 {
359 variable_imposee_sommet(i,j) = variable_imposee_mod(i,j);
360 }
361 }
362 }
363 for (int f = 0; f < nb_faces; f++)
364 {
365 int compteur = 0;
366 int som_f = 0;
367 while ((som_f < nb_som_face) and (sommet_interp(faces_sommets(f,som_f))==1))
368 {
369 compteur++;
370 som_f++;
371 }
372 if (compteur == nb_som_face)
373 {
374 int ori = domaine_VDF.orientation(f);
375 for (int som_=0; som_ < nb_som_face; som_++)
376 {
377 int i = faces_sommets(f,som_);
378 variable_imposee_calculee(f,0) += variable_imposee_sommet(i,ori)/nb_som_face;
379 }
380 }
381 }
382}
383
385{
386 const Domaine_VDF& domaine_VDF = le_dom_VDF.valeur();
387 int nb_faces=domaine_VDF.nb_faces();
388 int dim_esp = Objet_U::dimension;
389 const Domaine& dom = domaine_VDF.domaine();
390 const IntTab& faces_sommets=domaine_VDF.face_sommets();
391 int nb_som_face=faces_sommets.dimension(1);
392 int nb_som = domaine_VDF.nb_som();
393 DoubleTab& variable_imposee_mod = modele_lu_.variable_imposee_->valeurs();
394 DoubleTab& variable_imposee_calculee = variable_imposee_;
395 Interpolation_IBM_mean_gradient& interp = ref_cast(Interpolation_IBM_mean_gradient,interpolation_lue_.valeur());
396 DoubleTab& solid_points = interp.solid_points_->valeurs();
397 DoubleTab& is_dirichlet = interp.is_dirichlet_->valeurs();
398 double eps = 1e-12;
399 DoubleTab& variable_inconnue = equation().inconnue().valeurs();
400 int nb_comp = variable_inconnue.dimension(1);
401 variable_imposee_mod.echange_espace_virtuel();
402 int nb_comp_real = variable_imposee_mod.dimension(1);
403 DoubleTab variable_imposee_sommet(nb_som,nb_comp_real);
404 IntTab sommet_interp(nb_som);
405 variable_imposee_calculee = 0.0;
406 variable_imposee_sommet = 0.0;
407 sommet_interp = 0;
408 for (int i = 0; i < nb_som; i++)
409 {
410 if (is_dirichlet(i) > 0.0)
411 {
412 sommet_interp(i) = 1;
413 double d2 = 0.0;
414 for(int j = 0; j < dim_esp; j++)
415 {
416 double x = dom.coord(i,j);
417 double xp = solid_points(i,j);
418 d2 += (x - xp)*(x - xp);
419 }
420 Cerr << "On passe ICI" << finl;
421 for(int j = 0; j <nb_comp ; j++) variable_imposee_sommet(i,j) = variable_imposee_mod(i,j);
422 d2 = sqrt(d2);
423 if (d2 > eps)
424 {
425 IntList& voisins = interp.getSommetsVoisinsOf(i);
426 if (!(voisins.est_vide()))
427 {
428 ArrOfDouble mean_grad(nb_comp_real);
429 mean_grad = 0.0;
430 int taille = voisins.size();
431 int nb_contrib = 0;
432 for (int k = 0; k < taille; k++)
433 {
434 int num_som = voisins[k];
435 double d1 = 0.0;
436 for (int j = 0; j < dim_esp; j++)
437 {
438 double xf = dom.coord(num_som,j);
439 double xpf = solid_points(num_som,j);
440 d1 += (xf - xpf)*(xf - xpf);
441 }
442 d1 = sqrt(d1);
443 if (d1 > eps)
444 {
445 for (int j = 0; j < nb_comp; j++)
446 {
447 double vpf = variable_imposee_mod(num_som,j);
448 double vf = variable_inconnue(num_som,j);
449 Cerr << vf << finl;// calcul de la vitesse a voir comment (besoin d'une fonction d'interp ou moyenne)
450 mean_grad[j] += (vf - vpf)/d1;
451 }
452 nb_contrib += 1;
453 }
454 }
455 for (int j = 0; j < nb_comp; j++)
456 {
457 mean_grad[j] /= nb_contrib;
458 variable_imposee_sommet(i,j) += mean_grad[j]*d2;
459 }
460 }
461 }
462 }
463 else
464 {
465 for(int j = 0; j < nb_comp; j++)
466 {
467 variable_imposee_sommet(i,j) = variable_imposee_mod(i,j);
468 }
469 }
470 }
471 for (int f = 0; f < nb_faces; f++)
472 {
473 int compteur = 0;
474 int som_f = 0;
475 while ((som_f < nb_som_face) and (sommet_interp(faces_sommets(f,som_f))==1))
476 {
477 compteur++;
478 som_f++;
479 }
480 if (compteur == nb_som_face)
481 {
482 int ori = domaine_VDF.orientation(f);
483 for (int som_=0; som_ < nb_som_face; som_++)
484 {
485 int i = faces_sommets(f,som_);
486 variable_imposee_calculee(f,0) += variable_imposee_sommet(i,ori)/nb_som_face;
487 }
488 }
489 }
490}
491
493{
494 Cerr<<"Source_PDF_VDF::calculer_variable_imposee_hybrid not implemented for VDF"<<finl;
495 exit();
496}
497
498/*##################################################################################################
499####################################################################################################
500################################# calculer_vitesse_imposee #########################################
501####################################################################################################
502##################################################################################################*/
503
505{
506 assert(Objet_U::dimension==3);
507 const Domaine_VDF& domaine_VDF = le_dom_VDF.valeur();
508 int nb_faces=domaine_VDF.nb_faces();
509 int nb_comp = Objet_U::dimension;
510 const Domaine& dom = domaine_VDF.domaine();
511 const IntTab& faces_sommets=domaine_VDF.face_sommets();
512 int nb_som_face=faces_sommets.dimension(1);
513 int nb_som=domaine_VDF.nb_som();
514 DoubleTab& vitesse_imposee_mod = modele_lu_.variable_imposee_->valeurs();
515 DoubleTab& vitesse_imposee_calculee = variable_imposee_;
516 Interpolation_IBM_power_law_tbl& interp = ref_cast(Interpolation_IBM_power_law_tbl,interpolation_lue_.valeur());
517 int form_WJSP = interp.get_formulation_WJSP();
518 DoubleTab& fluid_points = interp.fluid_points_->valeurs();
519 DoubleTab& solid_points = interp.solid_points_->valeurs();
520 DoubleTab& fluid_elems = interp.fluid_elems_->valeurs();
521 //DoubleTab& is_dirichlet = interp.is_dirichlet_->valeurs();
522 double A_pwl = interp.get_A_pwl(form_WJSP);
523 double B_pwl = interp.get_B_pwl();
524 double y_c_p_pwl = 0;
525 double C_pwl_WJSP = 0;
526 double D_pwl_WJSP = 0;
527 double p_pwl_WJSP = 0;
528 double y_c1_p_pwl_WJSP = 0;
529 double y_c2_p_pwl_WJSP = 0;
530 if (!form_WJSP)
531 {
532 y_c_p_pwl = interp.get_y_c_p_pwl();
533 }
534 else
535 {
536 C_pwl_WJSP = interp.get_C_pwl_WJSP();
537 D_pwl_WJSP = interp.get_D_pwl_WJSP();
538 p_pwl_WJSP = interp.get_p_pwl_WJSP();
539 y_c1_p_pwl_WJSP = interp.get_y_c1_p_pwl_WJSP();
540 y_c2_p_pwl_WJSP = interp.get_y_c2_p_pwl_WJSP();
541 }
542 int impr_yplus = interp.get_impr() ;
543 Champ_Face_VDF& champ_vitesse_inconnue = ref_cast(Champ_Face_VDF,equation().inconnue());
544 double form_lin_pwl = interp.get_formulation_linear_pwl();
545 DoubleTab xf(1, nb_comp);
546 DoubleTab vf(1, nb_comp);
547 ArrOfInt cells(1);
548 DoubleTab vitesse_imposee_sommet(nb_som,nb_comp);
549 IntTab sommet_interp(1, nb_som);
550 vitesse_imposee_calculee = 0.0;
551 vitesse_imposee_sommet = 0.0;
552 sommet_interp = 0;
553 // operateur(0) : diffusivite
554 if (equation().nombre_d_operateurs()<1)
555 {
556 Cerr << "Source_PDF_VEF : nombre_d_operateurs = "<<equation().nombre_d_operateurs()<<" < 1"<<finl;
557 exit();
558 }
559
560 int flag = 0;
561 const Op_Diff_VDF_base& opdiffu = ref_cast(Op_Diff_VDF_base,equation().operateur(0).l_op_base());
562 flag = opdiffu.diffusivite().valeurs().dimension(0)>1 ? 1 : 0;
563
564 double eps = 1e-12;
565 double d1_min = 1.0e+10;
566 double d1_max = 0.0;
567 double d1_mean = 0.0;
568 double yplus_min = 1.0e+10;
569 double yplus_max = 0.0;
570 double yplus_mean = 0.0;
571 double u_tau_min = 1.0e+10;
572 double u_tau_max = 0.0;
573 double u_tau_mean = 0.0;
574 double yplus_ref_min = 1.0e+10;
575 double yplus_ref_max = 0.0;
576 double yplus_ref_mean = 0.0;
577 double u_tau_ref_min = 1.0e+10;
578 double u_tau_ref_max = 0.0;
579 double u_tau_ref_mean = 0.0;
580 double h_yplus_min = 1.0e+10;
581 double h_yplus_max = 0.0;
582 double h_yplus_mean = 0.0;
583 int yplus_count=0 ;
584 double y_plus=0;
585
586 int N = interp.get_N_histo();
587 DoubleTab tab_h(1, nb_som);
588 DoubleTab abs_h(1, N+1);
589 DoubleTab compteur_h(1, N);
590 compteur_h = 0.;
591 tab_h = 0.;
592
593 tab_u_star_ibm_ = 0.;
594 tab_y_plus_ibm_ = 0.;
595
596 for (int i = 0; i < nb_som; i++)
597 {
598 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = vitesse_imposee_mod(i,j);
599 int itisok = 1;
600 if ((fluid_elems(i) >= 0.0)) //and (is_dirichlet(i) == 1))
601 {
602 sommet_interp(0, i) = 1;
603 double d1 = 0.0;
604 double d2 = 0.0;
605 DoubleTab normale(1, nb_comp);
606 double norme_de_la_normale= 0.0;
607 for(int j = 0; j < nb_comp; j++)
608 {
609 double xj = dom.coord(i,j);
610 //Cerr << "xj " << " j " << j << " val " << xj << finl;
611 double xjf = fluid_points(i,j);
612 //Cerr << "xjf " << " j " << j << " val " << xjf<< finl;
613 xf(0, j) = xjf;
614 double xjs = solid_points(i,j);
615 //Cerr << "xjs " << " j " << j << " val " << xjs<< finl;
616 d1 += (xj-xjs)*(xj-xjs);
617 d2 += (xjf-xj)*(xjf-xj);
618 normale(0,j) = xjf - xjs;
619 norme_de_la_normale += normale(0,j)*normale(0,j);
620
621 }
622 d1 = sqrt(d1);
623 d2 = sqrt(d2);
624 //Cerr << "d1 " << d1 << finl;
625 //Cerr << "d2 " << d2 << finl;
626 double y_ref= d1+d2;
627
628 // traitement des exceptions
629 if (d1 < eps) itisok = 0; //le point P est sur la frontiere immergee : affectation
630 norme_de_la_normale = sqrt(norme_de_la_normale);
631 if ( norme_de_la_normale > eps )
632 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
633 else
634 {
635 for(int j = 0; j < nb_comp; j++) normale(0,j) = 0.; // le point fluide est sur la frontiere immergee : affectation
636 itisok = 0;
637 }
638 if ( y_ref < eps ) // le point fluide est sur la frontiere immergee : affectation
639 {
640 y_ref = 1.;
641 itisok = 0;
642 }
643 // calcul vitesse power law
644 if (itisok)
645 {
646 cells(0) = int(fluid_elems(i));
647 for(int j = 0; j < nb_comp; j++) vf(0, j) = champ_vitesse_inconnue.valeur_a_elem_compo(xf, cells[0], j);// vf la vitesse totale interpolee au pt fluide
648 double Vn = 0.;
649 for(int j = 0; j < nb_comp; j++) Vn += vf(0, j) * normale(0,j);
650 DoubleTab v_ref_t(1, nb_comp);
651
652 for(int j = 0; j < nb_comp; j++) v_ref_t(0, j) =vf(0, j) - Vn*normale(0,j);
653
654 double norme_v_ref_t = 0.;
655 for(int j = 0; j < nb_comp; j++) norme_v_ref_t += v_ref_t(0, j)*v_ref_t(0,j) ;
656 norme_v_ref_t = sqrt ( norme_v_ref_t );
657 if (norme_v_ref_t < 1.0e-6) norme_v_ref_t = 1.e-6;
658
659 double nu = (flag ? opdiffu.diffusivite().valeurs()(cells) : opdiffu.diffusivite().valeurs()(0,0));
660 // On calcule U_tau_ref pour pouvoir calculer les quantites adimensionees ( y+ ...)
661 // Hypothese : sous-couche puissance
662 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)) ) ;
663 // Cerr<<"u_tau_ref y_ref nu ="<<u_tau_ref<<" "<<y_ref<<" "<<nu<<finl;;
664 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+
665
666 double test_ref;
667
668 if (!form_WJSP)
669 {
670 if ( y_ref_p > y_c_p_pwl) // a partir de la commence l'expression de la loi de paroi polynomiale turbulente
671 {
672 if (!form_lin_pwl)
673 {
674 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = v_ref_t(0,j) * pow ( d1 / y_ref , B_pwl ) ;
675 }
676 else // Formulation lineaire de la loi polynomilale ------------------------------
677 {
678 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = v_ref_t(0,j) *(1. - B_pwl*(1-d1/y_ref)) ;
679 }
680 test_ref = 1.;
681 // Cerr << "zone log/sous-couche inertielle en coherence avec le calcul de u tau" << finl;
682 }
683 else
684 {
685 // En fait, on est en sous-couche visqueuse
686 if (!form_lin_pwl)
687 {
688 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = v_ref_t(0,j) * ( d1 / y_ref ) ;
689 }
690 else
691 {
692 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = v_ref_t(0,j) * (1. - pow(u_tau_ref, 2.)*(y_ref-d1)/(nu *norme_v_ref_t));
693 }
694 test_ref = -1. ;
695 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
696 y_ref_p = y_ref * u_tau_ref / nu;
697 if ( y_ref_p > y_c_p_pwl )
698 {
699 // Incoherence : on n utilise pas de lois de paroi
700 itisok = 0;
701 }
702 // Cerr << "zone lineaire/sous-couche visqueuse" << finl;
703 } // Fin LdPturb
704
705 double norme_v_imp_c = 0;
706 for(int j=0 ; j < nb_comp; j++) norme_v_imp_c += vitesse_imposee_sommet(i ,j) * vitesse_imposee_sommet(i ,j);
707 norme_v_imp_c = sqrt( norme_v_imp_c );
708
709 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
710 y_plus = u_tau * d1 / nu;
711 double test_;
712 if (y_plus >y_c_p_pwl)
713 {
714 test_ = 1.;
715 // Cerr<<"u_tau ="<<u_tau<<" y+ = "<<y_plus<<" y+ref = "<<y_ref_p<<finl;
716 }
717 else
718 {
719 test_ = -1.;
720 u_tau = pow ( (nu * norme_v_imp_c/ d1) , 0.5 ) ; // on recalcule u_tau et y_plus en lineaire au pt force
721 y_plus = u_tau * d1 / nu;
722 if ( y_plus > y_c_p_pwl )
723 {
724 // Incoherence : on n utilise pas de lois de paroi
725 Cerr<<"INCOHERENCE: u_tau ="<<u_tau<<" y+ = "<<y_plus<<" y+ref = "<<y_ref_p<<finl;
726 itisok = 0;
727 }
728 }
729 // Cerr<<"u_tau d1 nu ="<<u_tau<<" "<<d1<<" "<<nu<<finl;;
730
731 // 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
732
733 // Traitement des exceptions
734 if ( (test_ * test_ref < 0) || (itisok == 0) ) //si non on affecte la vitesse paroi
735 {
736 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = vitesse_imposee_mod(i,j);
737
738 // Cerr << "erreur" << finl;
739 itisok = 0;
740 }
741 else
742 {
743 tab_u_star_ibm_(i) = u_tau;
744 tab_y_plus_ibm_(i) = y_plus;
745 }
746 if (impr_yplus && itisok && (indicateur_nodal_champ_aire_(i)==1.))
747 {
748 if (d1 > d1_max) d1_max = d1;
749 if (d1 < d1_min) d1_min = d1;
750 d1_mean += d1;
751 if (y_plus > yplus_max) yplus_max = y_plus;
752 if (y_plus < yplus_min) yplus_min = y_plus;
753 yplus_mean += y_plus;
754 if (u_tau > u_tau_max) u_tau_max = u_tau;
755 if (u_tau < u_tau_min) u_tau_min = u_tau;
756 u_tau_mean += u_tau;
757 if (y_ref_p > yplus_ref_max) yplus_ref_max = y_ref_p;
758 if (y_ref_p < yplus_ref_min) yplus_ref_min = y_ref_p;
759 yplus_ref_mean += y_ref_p;
760 if (u_tau_ref > u_tau_ref_max) u_tau_ref_max = u_tau_ref;
761 if (u_tau_ref < u_tau_ref_min) u_tau_ref_min = u_tau_ref;
762 u_tau_ref_mean += u_tau_ref;
763 // Distribution des y+ au voisinage des parois
764 if (y_plus > h_yplus_max) h_yplus_max = y_plus;
765 if (y_plus < h_yplus_min) h_yplus_min = y_plus;
766 h_yplus_mean += y_plus;
767 tab_h(0,yplus_count) = y_plus;
768 yplus_count += 1;
769 }
770 }
771 else
772 {
773 Cerr << "On passe bien dans le WJSP" << finl;
774 //double u_tau;
775 if ( y_ref_p > y_c2_p_pwl_WJSP) // a partir de la commence l'expression de la loi de paroi polynomiale turbulente
776 {
777 y_plus = u_tau_ref * d1/nu;
778 if (y_plus > y_c2_p_pwl_WJSP)
779 {
780 if (!form_lin_pwl)
781 {
782 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = v_ref_t(0,j) * pow ( d1 / y_ref , B_pwl ) ;
783 }
784 else // Formulation lineaire de la loi polynomilale ------------------------------
785 {
786 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = v_ref_t(0,j) * (1. - B_pwl*(1-d1/y_ref)) ;
787 }
788 }
789 else if (y_plus < y_c2_p_pwl_WJSP and y_plus > y_c1_p_pwl_WJSP)
790 {
791 if (!form_lin_pwl)
792 {
793 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(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;
794 }
795 else // Formulation lineaire de la loi polynomilale ------------------------------
796 {
797 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = 0 ;
798 }
799 }
800 else
801 {
802 if (!form_lin_pwl)
803 {
804 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = y_plus * u_tau_ref * v_ref_t(0,j)/norme_v_ref_t;
805 }
806 else // Formulation lineaire de la loi polynomilale ------------------------------
807 {
808 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = v_ref_t(0,j) * (1. - B_pwl*(1-d1/y_ref)) ;
809 }
810 }
811 // Cerr << "zone log/sous-couche inertielle en coherence avec le calcul de u tau" << finl;
812 }
813 else // hypothèse buffer layer
814 {
815 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) ;
816 y_ref_p = y_ref * u_tau_ref / nu;
817 if (y_ref_p < y_c2_p_pwl_WJSP and y_ref_p > y_c1_p_pwl_WJSP)
818 {
819 y_plus = u_tau_ref * d1/nu;
820 if (y_plus < y_c2_p_pwl_WJSP and y_plus > y_c1_p_pwl_WJSP)
821 {
822 if (!form_lin_pwl)
823 {
824 double phi = -pow(1 + 4 * C_pwl_WJSP/pow(D_pwl_WJSP,2) * norme_v_ref_t * y_ref /nu,1/2) - 1;
825 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);
826 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = u_norm * v_ref_t(0,j)/norme_v_ref_t;
827 }
828 else // Formulation lineaire de la loi polynomilale ------------------------------
829 {
830 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = 0 ; //à faire
831 }
832 }
833 else
834 {
835 if (!form_lin_pwl)
836 {
837 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = y_plus * u_tau_ref * v_ref_t(0,j)/norme_v_ref_t ;
838 }
839 else // Formulation lineaire de la loi polynomilale ------------------------------
840 {
841 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = 0 ;
842 }
843 }
844 }
845 else
846 {
847 // En fait, on est en sous-couche visqueuse
848 if (!form_lin_pwl)
849 {
850 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = v_ref_t(0,j) * ( d1 / y_ref ) ;
851 }
852 else
853 {
854 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = v_ref_t(0,j) * (1. - pow(u_tau_ref, 2.)*(y_ref-d1)/(nu *norme_v_ref_t));
855 }
856 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
857 y_ref_p = y_ref * u_tau_ref / nu;
858 if ( y_ref_p > y_c1_p_pwl_WJSP)
859 {
860 // Incoherence : on n utilise pas de lois de paroi
861 itisok = 0;
862 Cerr << "Incoherence" << finl;
863 }
864 }
865 }
866 // Cerr<<"u_tau d1 nu ="<<u_tau<<" "<<d1<<" "<<nu<<finl;;
867
868 // 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
869
870 // Traitement des exceptions
871 if (itisok == 0) //si non on affecte la vitesse paroi
872 {
873 for(int j = 0; j < nb_comp; j++) vitesse_imposee_sommet(i,j) = vitesse_imposee_mod(i,j);
874
875 // Cerr << "erreur" << finl;
876 itisok = 0;
877 }
878 else
879 {
880 tab_u_star_ibm_(i) = u_tau_ref;
881 tab_y_plus_ibm_(i) = y_plus;
882 }
883 if (impr_yplus && itisok && (indicateur_nodal_champ_aire_(i)==1.))
884 {
885 if (d1 > d1_max) d1_max = d1;
886 if (d1 < d1_min) d1_min = d1;
887 d1_mean += d1;
888 if (y_plus > yplus_max) yplus_max = y_plus;
889 if (y_plus < yplus_min) yplus_min = y_plus;
890 yplus_mean += y_plus;
891 if (u_tau_ref > u_tau_max) u_tau_max = u_tau_ref;
892 if (u_tau_ref < u_tau_min) u_tau_min = u_tau_ref;
893 u_tau_mean += u_tau_ref;
894 if (y_ref_p > yplus_ref_max) yplus_ref_max = y_ref_p;
895 if (y_ref_p < yplus_ref_min) yplus_ref_min = y_ref_p;
896 yplus_ref_mean += y_ref_p;
897 if (u_tau_ref > u_tau_ref_max) u_tau_ref_max = u_tau_ref;
898 if (u_tau_ref < u_tau_ref_min) u_tau_ref_min = u_tau_ref;
899 u_tau_ref_mean += u_tau_ref;
900 // Distribution des y+ au voisinage des parois
901 if (y_plus > h_yplus_max) h_yplus_max = y_plus;
902 if (y_plus < h_yplus_min) h_yplus_min = y_plus;
903 h_yplus_mean += y_plus;
904 tab_h(0,yplus_count) = y_plus;
905 yplus_count += 1;
906 }
907 }
908 }
909 }
910 }
911 get_champ("u_star_ibm");
912 get_champ("y_plus_ibm");
913 for (int f = 0; f < nb_faces; f++)
914 {
915 int compteur = 0;
916 int som_f = 0;
917 while ((som_f < nb_som_face) and (sommet_interp(faces_sommets(f,som_f))==1))
918 {
919 compteur++;
920 som_f++;
921 }
922 if (compteur == nb_som_face)
923 {
924 int ori = domaine_VDF.orientation(f);
925 for (int som_=0; som_ < nb_som_face; som_++)
926 {
927 int i = faces_sommets(f,som_);
928 vitesse_imposee_calculee(f,0) += vitesse_imposee_sommet(i,ori)/nb_som_face;
929 }
930 }
931 }
932
933 if (impr_yplus && (yplus_count >= 1) )
934 {
935 d1_mean /= yplus_count;
936 yplus_mean /= yplus_count;
937 yplus_ref_mean /= yplus_count;
938 u_tau_mean /= yplus_count;
939 u_tau_ref_mean /= yplus_count;
940 Cerr<<"min mean max y = "<<d1_min<<" "<<d1_mean<<" "<<d1_max<<finl;
941 Cerr<<"min mean max y+ = "<<yplus_min<<" "<<yplus_mean<<" "<<yplus_max<<finl;
942 Cerr<<"min mean u_tau = "<<u_tau_min<<" "<<u_tau_mean<<" "<<u_tau_max<<finl;
943 Cerr<<"min mean max y+_ref = "<<yplus_ref_min<<" "<<yplus_ref_mean<<" "<<yplus_ref_max<<finl;
944 Cerr<<"min mean u_tau_ref = "<<u_tau_ref_min<<" "<<u_tau_ref_mean<<" "<<u_tau_ref_max<<finl;
945
946 h_yplus_mean /= yplus_count;
947 double range = ( h_yplus_max - h_yplus_min)/N;
948 for (int k = 0; k < N+1; k++) abs_h(0,k) = (h_yplus_min + k*range);
949 for (int i=0; i < yplus_count; i++)
950 {
951 for (int j = 0; j < N; j++)
952 {
953 if ( abs_h(0,j) < tab_h(0,i) && tab_h(0,i) <= abs_h(0,j+1) ) compteur_h(0,j) +=1;
954 }
955 }
956 Cerr<<"histogramme y+ compteur =";
957 for (int j = 0; j < N; j++) Cerr<<" "<<compteur_h(0,j)<<" ";
958 Cerr<<finl;
959 Cerr<<"histogramme y+ abscisse =";
960 for (int j = 0; j < N+1; j++) Cerr<<" "<<abs_h(0,j)<<" ";
961 Cerr<<finl;
962 Cerr<<"histogramme y+ : min = "<<h_yplus_min<<" - mean = "<<h_yplus_mean<<" - max = "<<h_yplus_max<<finl;
963
964 Cerr<<"Moyenne sur "<<yplus_count<<" points"<<finl;
965 }
966}
967
969{
970 Cerr<<"Source_PDF_VDF::calculer_variable_imposee_power_law_tbl_u_star not implemented for VDF"<<finl;
971 exit();
972}
973
974/*##################################################################################################
975####################################################################################################
976################################# Pression #########################################################
977####################################################################################################
978##################################################################################################*/
979
980void Source_PDF_VDF::correct_incr_pressure(const DoubleTab& coeff_node, DoubleTab& correction_en_pression) const
981{
982 const DoubleTab& aire=champ_aire_->valeurs();
983 // int nb_elem = correction_en_pression.size();
984 const Domaine_VDF& domaine_VDF = le_dom_VDF.valeur();
985 const IntTab& elems= domaine_VDF.elem_faces();
986 int nb_face_elem=domaine_VDF.domaine().nb_faces_elem();
987 int nb_elems=domaine_VDF.domaine().nb_elem_tot();
988 int ncomp = coeff_node.dimension(1) ;
989 Cerr << ncomp << finl;
990 DoubleTrav coef_elem(nb_elems);
991
992 // Filtre par face
993 DoubleTrav flag_cl(coeff_node);
994 filtre_CLD(flag_cl);
995 // int nb_face=domaine_VDF.domaine().nb_faces();
996 // for(int face=0; face<nb_face; face++)Cerr<<"face flag_c = "<<face<<" "<<flag_cl(face,0)<<" "<<flag_cl(face,1)<<" "<<flag_cl(face,2)<<finl;
997
998 for(int num_elem=0; num_elem<nb_elems; num_elem++)
999 {
1000 if (aire(num_elem)>0.)
1001 {
1002 correction_en_pression(num_elem) = 0.;
1003 }
1004 else
1005 {
1006 coef_elem(num_elem) = 0. ;
1007 for (int i=0; i<nb_face_elem; i++)
1008 {
1009 int sii=elems(num_elem,i);
1010 for (int comp=0; comp<ncomp; comp++)
1011 {
1012 if ((coeff_node(sii,comp)!= 1.0) || (flag_cl(sii,comp) != 1.0)) coef_elem(num_elem) += 1. ;
1013 }
1014 }
1015 if (coef_elem(num_elem) == (ncomp*nb_face_elem)) correction_en_pression(num_elem) = 0.;
1016 }
1017 }
1018}
1019
1020void Source_PDF_VDF::correct_pressure(const DoubleTab& coeff_node, DoubleTab& pression, const DoubleTab& correction_en_pression) const
1021{
1022 const DoubleTab& aire=champ_aire_->valeurs();
1023 //int nb = pression.size();
1024 //Cerr << pression << finl;
1025 //Cerr << nb << finl;
1026 const Domaine_VDF& domaine_VDF = le_dom_VDF.valeur();
1027 const IntTab& elems= domaine_VDF.elem_faces();
1028 int nb_face_elem=domaine_VDF.domaine().nb_faces_elem();
1029 int nb_elem= domaine_VDF.domaine().nb_elem_tot();
1030 int ncomp = coeff_node.dimension(1) ;
1031 DoubleTrav coef_elem(nb_elem);
1032
1033 DoubleTrav flag_cl(coeff_node);
1034 filtre_CLD(flag_cl);
1035
1036 for(int num_elem=0; num_elem<nb_elem; num_elem++)
1037 {
1038 if (aire(num_elem)<=0.)
1039 {
1040 coef_elem(num_elem) = 0. ;
1041 for (int i=0; i<nb_face_elem; i++)
1042 {
1043 int sii=elems(num_elem,i);
1044 for (int comp=0; comp<ncomp; comp++)
1045 {
1046 if ((coeff_node(sii,comp)!= 1.0) || (flag_cl(sii,comp) != 1.0)) coef_elem(num_elem) += 1. ;
1047 }
1048 }
1049 if (coef_elem(num_elem) != (ncomp*nb_face_elem)) pression(num_elem)+=correction_en_pression(num_elem);
1050 }
1051 }
1052}
1053
1054
1055void Source_PDF_VDF::filtre_CLD(DoubleTab& flag_cl) const
1056{
1057 // Filtre et dof par face
1058 const Domaine_Cl_VDF& le_dom_cl = le_dom_Cl_VDF.valeur();
1059 int nb_cond_lim = le_dom_cl.nb_cond_lim();
1060 int nb_comp = flag_cl.dimension(1);
1061 flag_cl = 1.;
1062 for (int ij=0; ij<nb_cond_lim; ij++)
1063 {
1064 const Cond_lim_base& la_cl_base = le_dom_cl.les_conditions_limites(ij).valeur();
1065 const Front_VF& le_bord = ref_cast(Front_VF,le_dom_cl.les_conditions_limites(ij)->frontiere_dis());
1066 int nfaces = le_bord.nb_faces_tot();
1067 if (sub_type(Dirichlet,la_cl_base))
1068 {
1069 for (int ind_face=0; ind_face < nfaces; ind_face++)
1070 {
1071 int face=le_bord.num_face(ind_face);
1072 for (int comp=0; comp<nb_comp; comp++) flag_cl(face,comp) = 0. ;
1073 }
1074 }
1075 }
1076 //vector; NS Attention seulement defini en EF
1077 // if (nb_comp == Objet_U::dimension) le_dom_cl.imposer_symetrie(flag_cl,0);
1078 flag_cl.echange_espace_virtuel();
1079 return;
1080}
1081
1082/*##################################################################################################
1083####################################################################################################
1084################################# Impression #######################################################
1085####################################################################################################
1086##################################################################################################*/
1087
1089{
1090 if (out_=="??")
1091 {
1092 Cerr << __FILE__ << (int)__LINE__ << " ERROR / Source_PDF_VDF::impr" << finl;
1093 Cerr << "No balance printed for " << que_suis_je() << finl;
1094 Cerr << "Because output file name is not specified." << finl;
1095 return 0;
1096 }
1097 else
1098 {
1099 int nb_compo=bilan_.size();
1100 if (nb_compo==0)
1101 {
1102 Cerr << __FILE__ << (int)__LINE__ << " ERROR / Source_PDF_VDF::impr" << finl;
1103 Cerr << "No balance printed for " << que_suis_je() << finl;
1104 Cerr << "Because bilan_ array is not filled." << finl;
1105 return 0;
1106 }
1107 else
1108 {
1110 double temps=sch.temps_courant();
1111 double pdtps = sch.pas_de_temps();
1112 if (temps == pdtps)
1113 {
1114 int flag = Process::je_suis_maitre();
1115 if(flag) ouvrir_fichier(Flux,"",flag);
1116 return 0;
1117 }
1118 const DoubleTab& variable=equation().inconnue().valeurs();
1119 Nom espace=" \t";
1120
1121 int nb_comp = variable.dimension(1);
1122 assert(nb_comp == modele_lu_.dim_variable_);
1123 int pdf_dt_conv = modele_lu_.pdf_bilan();
1124
1125 DoubleTrav secmem_conv(variable);
1126 // defaut pdf_dt_conv = 0
1127 secmem_conv = 0.;
1128 int i_traitement_special = 0;
1129
1130 if (pdf_dt_conv == 1 || pdf_dt_conv == 2)
1131 // pdf_dt_conv = 1 ou 2
1132 {
1133 if (nb_comp == Objet_U::dimension)
1134 {
1135 //vector; NS
1136 Navier_Stokes_std& eq_NS = ref_cast_non_const(Navier_Stokes_std, equation());
1137 int transport_rhou=0;
1138 if (eq_NS.nombre_d_operateurs() > 1)
1139 {
1140 transport_rhou= (eq_NS.vitesse_pour_transport().le_nom()=="rho_u"?1:0);
1141 if (pdf_dt_conv == 2) eq_NS.derivee_en_temps_conv(secmem_conv , variable);
1142 }
1143 i_traitement_special = (transport_rhou==1?2:102);
1144 }
1145 else if (nb_comp == 1)
1146 {
1147 //scalar; temps en rho
1148 Equation_base& eq_Ba = ref_cast_non_const(Equation_base, equation());
1149 if (equation().nombre_d_operateurs() > 1)
1150 {
1151 if (pdf_dt_conv == 2) eq_Ba.derivee_en_temps_conv(secmem_conv , variable);
1152 }
1153 i_traitement_special = 2;
1154 }
1155 else
1156 {
1157 Cerr << "Source_PDF_VDF: for scalar or vector only; dim = " <<nb_comp<< finl;
1158 Process::exit();
1159 }
1160 }
1161 else if(pdf_dt_conv != 0 )
1162 {
1163 Cerr<<"Source_PDF_VDF: Modele pdf_bilan must be 0; 1 or 2 only"<<finl;
1164 Process::exit();
1165 }
1166
1167 Source_PDF_base& my_src = ref_cast_non_const(Source_PDF_base,*this);
1168 my_src.compute_source_term_PDF(i_traitement_special, secmem_conv, bilan_);
1169
1170 int flag = Process::je_suis_maitre();
1171 if(flag)
1172 {
1173 ouvrir_fichier(Flux,"",flag);
1174 if(nb_comp == Objet_U::dimension)
1175 {
1176 // vector
1177 assert(Objet_U::dimension==3);
1178 Flux << temps << espace << bilan_(0) << espace << bilan_(1) << espace << bilan_(2) << finl;
1179 }
1180 else
1181 {
1182 // scalar
1183 Flux << temps << espace << bilan_(0) << finl;
1184 }
1185 }
1186 }
1187 return 1;
1188 }
1189}
1190
1191// void imprimer_ustar_yplus__mean_only(Sortie&, const Nom& ) const override;
1192
1193
1194/*##################################################################################################
1195####################################################################################################
1196################################# POSTRAITEMENT ####################################################
1197####################################################################################################
1198##################################################################################################*/
1199
1201{
1203
1204 if (motlu=="u_star_ibm" && !champ_u_star_ibm_ && imm_wall_law_)
1205 {
1206 int nb_comp = 1;
1207 Noms noms(1);
1208 noms[0]="u_star_ibm";
1209 Noms unites(1);
1210 unites[0] = "m/s";
1211 double temps=0.;
1213 discr.discretiser_champ("champ_sommets",equation().domaine_dis(),scalaire,noms,unites,nb_comp,temps,champ_u_star_ibm_);
1214 champs_compris_.ajoute_champ(champ_u_star_ibm_);
1215 }
1216 else if (motlu=="y_plus_ibm" && !champ_y_plus_ibm_ && imm_wall_law_)
1217 {
1218 int nb_comp = 1;
1219 Noms noms(1);
1220 noms[0]="y_plus_ibm";
1221 Noms unites(1);
1222 unites[0] = "-";
1223 double temps=0.;
1225 discr.discretiser_champ("champ_sommets",equation().domaine_dis(),scalaire,noms,unites,nb_comp,temps,champ_y_plus_ibm_);
1226 champs_compris_.ajoute_champ(champ_y_plus_ibm_);
1227 }
1228}
1229
1230bool Source_PDF_VDF::has_champ(const Motcle& nom, OBS_PTR(Champ_base) &ref_champ) const
1231{
1232 if (Source_PDF_base::has_champ(nom,ref_champ)) return true;
1233
1234 if (nom == "u_star_ibm" && champ_u_star_ibm_)
1235 {
1236 ref_champ = Source_PDF_VDF::get_champ(nom);
1237 return true;
1238 }
1239 else if (nom == "y_plus_ibm" && champ_y_plus_ibm_)
1240 {
1241 ref_champ = Source_PDF_VDF::get_champ(nom);
1242 return true;
1243 }
1244 else if (champs_compris_.has_champ(nom, ref_champ))
1245 return true;
1246 else
1247 return false;
1248}
1249
1250bool Source_PDF_VDF::has_champ(const Motcle& nom) const
1251{
1252 if (Source_PDF_base::has_champ(nom)) return true;
1253
1254 if (nom == "u_star_ibm" && champ_u_star_ibm_)
1255 return true;
1256 else if (nom == "y_plus_ibm" && champ_y_plus_ibm_)
1257 return true;
1258 else
1259 return champs_compris_.has_champ(nom);
1260}
1261
1263{
1265
1266 if (nom=="u_star_ibm")
1267 {
1268 if (!champ_u_star_ibm_)
1269 throw std::runtime_error(std::string("Field ") + nom.getString() + std::string(" not found !"));
1270
1271 // Initialisation a 0 du champ volumique u_star
1272 DoubleTab& valeurs = champ_u_star_ibm_->valeurs();
1273 valeurs=0;
1274 if (tab_u_star_ibm_.size_array()>0)
1275 {
1276 const Domaine_VF& domaine_VF = ref_cast(Domaine_VF,le_dom_VDF.valeur());
1277 int nb_som=domaine_VF.nb_som();
1278 for (int num_node=0; num_node<nb_som; num_node++)
1279 valeurs(num_node)=tab_u_star_ibm_(num_node);
1280 }
1281 valeurs.echange_espace_virtuel();
1282 // Champ_Fonc_base& ch=ref_cast_non_const(Champ_Fonc_base,champ_u_star_ibm_);
1283 champ_u_star_ibm_->mettre_a_jour(equation().probleme().schema_temps().temps_courant());
1284 return champs_compris_.get_champ(nom);
1285 }
1286 else if (nom=="y_plus_ibm")
1287 {
1288 if (!champ_y_plus_ibm_)
1289 throw std::runtime_error(std::string("Field ") + nom.getString() + std::string(" not found !"));
1290
1291 // Initialisation a 0 du champ volumique u_star
1292 DoubleTab& valeurs = champ_y_plus_ibm_->valeurs();
1293 valeurs=0;
1294 if (tab_y_plus_ibm_.size_array()>0)
1295 {
1296 const Domaine_VF& domaine_VF = ref_cast(Domaine_VF,le_dom_VDF.valeur());
1297 int nb_som=domaine_VF.nb_som();
1298 for (int num_node=0; num_node<nb_som; num_node++)
1299 valeurs(num_node)=tab_y_plus_ibm_(num_node);
1300 }
1301 valeurs.echange_espace_virtuel();
1302 // Champ_Fonc_base& ch=ref_cast_non_const(Champ_Fonc_base,champ_y_plus_ibm_);
1303 champ_y_plus_ibm_->mettre_a_jour(equation().probleme().schema_temps().temps_courant());
1304 return champs_compris_.get_champ(nom);
1305 }
1306 else
1307 return champs_compris_.get_champ(nom);
1308}
1309
1311{
1313
1314 Noms noms_compris = champs_compris_.liste_noms_compris();
1315 if(imm_wall_law_)
1316 {
1317 Cerr<<" imm_wall_law_ : "<<finl;
1318 noms_compris.add("u_star_ibm");
1319 noms_compris.add("y_plus_ibm");
1320 }
1321 if (opt==DESCRIPTION)
1322 Cerr<<" Source_PDF_VDF : "<< noms_compris <<finl;
1323 else
1324 nom.add(noms_compris);
1325}
class Champ_Face_VDF Cette classe sert a representer un champ vectoriel dont on ne calcule
double valeur_a_elem_compo(const DoubleVect &position, int le_poly, int ncomp) const override
provoque une erreur ! doit etre surchargee par les classes derivees
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
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_t nb_elem_tot() const
Definition Domaine.h:132
int nb_faces_elem(int=0) const
Renvoie le nombre de face de type i des elements geometriques constituants le domaine.
Definition Domaine.h:484
double coord(int_t i, int j) const
Definition Domaine.h:110
class Domaine_Cl_VDF
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_VDF
Definition Domaine_VDF.h:64
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
class Domaine_VF
Definition Domaine_VF.h:44
int nb_faces() const
renvoie le nombre global de faces.
Definition Domaine_VF.h:471
DoubleVect & volumes_entrelaces()
Definition Domaine_VF.h:99
int face_sommets(int i, int j) const
renvoie le numero du ieme sommet de la face num_face.
Definition Domaine_VF.h:583
int elem_faces(int i, int j) const
renvoie le numero de le ieme face de la maille num_elem la facon dont ces faces sont numerotees est
Definition Domaine_VF.h:543
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_VDF_base Classe de base des operateurs de diffusion VDF
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 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
DoubleTab & ajouter_(const DoubleTab &, DoubleTab &) const override
void calculer_vitesse_imposee_power_law_tbl_u_star() override
void compute_indicateur_nodal_champ_aire() override
void calculer_variable_imposee_elem_fluid() override
void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const override
contribution a la matrice implicite des termes sources par defaut pas de contribution
bool has_champ(const Motcle &nom, OBS_PTR(Champ_base) &ref_champ) const override
DoubleVect tab_u_star_ibm_
valeurs des u* IBM calculees localement
void associer_domaines(const Domaine_dis_base &, const Domaine_Cl_dis_base &) override
void correct_pressure(const DoubleTab &, DoubleTab &, const DoubleTab &) const override
void correct_incr_pressure(const DoubleTab &, DoubleTab &) const override
void calculer_variable_imposee_hybrid() override
void calculer_vitesse_imposee_power_law_tbl() override
void filtre_CLD(DoubleTab &) const override
DoubleVect tab_y_plus_ibm_
valeurs des d+ IBM calculees localement
void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const override
void calculer_variable_imposee_mean_grad() override
void associer_pb(const Probleme_base &) override
void multiply_coeff_volume(DoubleTab &) const override
OBS_PTR(Domaine_VDF) le_dom_VDF
int impr(Sortie &) const override
void creer_champ(const Motcle &motlu) override
const Champ_base & get_champ(const Motcle &nom) const override
void verif_ajouter_contrib(const DoubleTab &variable, Matrice_Morse &matrice) const
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_
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_totale() const
Definition TRUSTVect.tpp:61
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")