TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Paroi_std_hyd_VDF.cpp
1/****************************************************************************
2* Copyright (c) 2017, 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
17#include <Dirichlet_paroi_defilante.h>
18#include <Dirichlet_paroi_fixe.h>
19#include <Paroi_std_hyd_VDF.h>
20#include <TRUSTTabs_forward.h>
21#include <Paroi_std_hyd_VDF.h>
22#include <Schema_Temps_base.h>
23#include <Modele_turbulence_hyd_base.h>
24#include <Champ_Uniforme.h>
25#include <Domaine_Cl_VDF.h>
26#include <communications.h>
27#include <EcrFicPartage.h>
28#include <Equation_base.h>
29#include <Fluide_base.h>
30#include <TRUSTTrav.h>
31#include <SFichier.h>
32#include <Param.h>
33
34Implemente_instanciable(Paroi_std_hyd_VDF, "loi_standard_hydr_VDF", Paroi_hyd_base_VDF);
35Implemente_instanciable(Loi_expert_hydr_VDF, "Loi_expert_hydr_VDF", Paroi_std_hyd_VDF);
36// XD Loi_expert_hydr_VDF turbulence_paroi_base Loi_expert_hydr_VDF BRACE Expert wall function for the VDF
37// XD_CONT discretisation.
38// XD_USE_PARAM_FRAGMENT paroi_log_qdm
39
41{
42 return s << que_suis_je() << " " << le_nom();
43}
44
46{
47 return s << que_suis_je() << " " << le_nom();
48}
49
51{
53 return s ;
54}
55
57{
58 Param param(que_suis_je());
60
61 param.lire_avec_accolades_depuis(s);
62
63 return s ;
64}
65
67{
70 param.ajouter("coeff_omega_wall",&coeff_omega_wall_); // XD_ADD_P int
71 // XD_CONT coeff for omega boundary condition
72}
73
74/////////////////////////////////////////////////////////////////////
75//
76// Implementation des fonctions de la classe Paroi_std_hyd_VDF
77//
78/////////////////////////////////////////////////////////////////////
79
80
82{
83 uplus_.resize(le_dom_dis_->nb_faces_bord());
84 init_lois_paroi_(); // dans Paroi_hyd_base_VDF
87}
88
89// Remplissage de la table
91{
92 Cmu_ = mon_modele_turb_hyd->get_Cmu();
93 init_lois_paroi_hydraulique_(); // dans Paroi_log_QDM
94 return 1;
95}
96
97// On annule les valeurs des grandeurs turbulentes qui
98// correspondent aux mailles de paroi
100{
101 int nb_dim = tab.nb_dim();
102 const int nb_comp = tab.line_size();
103 const IntTab& face_voisins = le_dom_dis_->face_voisins();
104 // const IntVect& orientation = le_dom_dis_->orientation();
105 // Boucle sur les bords
106
107 int ndeb, nfin, elem;
108
109 for (int n_bord = 0; n_bord < le_dom_dis_->nb_front_Cl(); n_bord++)
110 {
111 // pour chaque condition limite on regarde son type
112 // On applique les lois de paroi uniquement
113 // aux voisinages des parois
114
115 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
116
117 if ((sub_type(Dirichlet_paroi_fixe, la_cl.valeur()))
118 || (sub_type(Dirichlet_paroi_defilante, la_cl.valeur())))
119 {
120 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
121 ndeb = le_bord.num_premiere_face();
122 nfin = ndeb + le_bord.nb_faces();
123
124 if (nb_dim > 2) // cAlan : à déplacer ? nb_dim est indépendant de la boucle.
125 {
126 Cerr << "Erreur TRUST dans Paroi_std_hyd_VDF::preparer_calculer_hyd" << finl;
127 Cerr << "Le DoubleTab tab ne peut pas avoir plus de 2 entrees" << finl;
129 }
130 else
131 {
132 for (int num_face = ndeb; num_face < nfin; num_face++)
133 if ((elem = face_voisins(num_face, 0)) != -1)
134 for (int k = 0; k < nb_comp; k++)
135 tab(elem, k) = 0;
136 else
137 {
138 elem = face_voisins(num_face, 1);
139 for (int k = 0; k < nb_comp; k++)
140 tab(elem, k) = 0;
141 }
142 }
143 }
144 }
145 return 1;
146}
147
148int Paroi_std_hyd_VDF::calculer_hyd(DoubleTab& tab_2eq)
149{
150 DoubleTab bidon(0);
151 // bidon ne servira pas
152 if (turbulence_model_type_ == 0)
153 return calculer_hyd(tab_2eq, 1, bidon);
154 else
155 return compute_law_komega(tab_2eq);
156}
157
158int Paroi_std_hyd_VDF::calculer_hyd(DoubleTab& tab_nu_t, DoubleTab& tab_k)
159{
160 return calculer_hyd(tab_nu_t, 0, tab_k);
161}
162
163int Paroi_std_hyd_VDF::calculer_hyd(DoubleTab& tab1, int isKeps, DoubleTab& tab2)
164{
165 // si isKeps = 1 tab1=tab_keps
166 // tab2 bidon
167 // si isKeps = 0 tab1=tab_nu_t
168 // tab2=tab_k
169 // Cerr<<" Paroi_std_hyd_VDF::calculer_hyd"<<finl;
170 const Domaine_VDF& domaine_VDF = ref_cast(Domaine_VDF, le_dom_dis_.valeur());
171 const IntVect& orientation = domaine_VDF.orientation();
172 const IntTab& face_voisins = domaine_VDF.face_voisins();
173 const Equation_base& eqn_hydr = mon_modele_turb_hyd->equation();
174 const Fluide_base& le_fluide = ref_cast(Fluide_base, eqn_hydr.milieu());
175 const Champ_Don_base& ch_visco_cin = le_fluide.viscosite_cinematique();
176 const DoubleVect& vit = eqn_hydr.inconnue().valeurs();
177 const DoubleTab& tab_visco = ch_visco_cin.valeurs();
178 double visco = -1;
179 int l_unif {0};
180 if (sub_type(Champ_Uniforme, ch_visco_cin))
181 {
182 visco = std::max(tab_visco(0, 0), DMINFLOAT);
183 l_unif = 1;
184 }
185
186 // preparer_calcul_hyd(tab);
187 if ((!l_unif) && (tab_visco.local_min_vect()<DMINFLOAT))
188 // on ne doit pas changer tab_visco ici !
189 {
190 Cerr << "In Paroi_std_hyd_VDF::calculer_hyd : visco = " << tab_visco.local_min_vect() << " <= 0 ? " << finl;
191 throw;
192 }
193 int ndeb, nfin, elem, ori;
194 double norm_v, dist, u_plus_d_plus, d_visco;
195 //double val,val1,val2;
196
197 //****************************************************************
198 // Modifs du 19/10 pour etre coherent avec la diffusion turbulente
199 double signe;
200 //****************************************************************
201
202 // Boucle sur les bords
203
204 for (int n_bord = 0; n_bord < domaine_VDF.nb_front_Cl(); n_bord++)
205 {
206
207 // pour chaque condition limite on regarde son type
208 // On applique les lois de paroi uniquement
209 // aux voisinages des parois
210
211 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
212 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
213 ndeb = le_bord.num_premiere_face();
214 nfin = ndeb + le_bord.nb_faces();
215
216 if (sub_type(Dirichlet_paroi_fixe, la_cl.valeur()) || sub_type(Dirichlet_paroi_defilante, la_cl.valeur() ))
217 {
218 int isdiri = 0;
219 DoubleTab vitesse_imposee_face_bord(le_bord.nb_faces(), dimension);
220 if (sub_type(Dirichlet_paroi_defilante, la_cl.valeur()))
221 {
222 isdiri = 1;
223 const Dirichlet_paroi_defilante& cl_diri = ref_cast(Dirichlet_paroi_defilante, la_cl.valeur());
224 for (int face = ndeb; face < nfin; face++)
225 for (int k = 0; k < dimension; k++)
226 vitesse_imposee_face_bord(face-ndeb, k) = cl_diri.val_imp(face-ndeb, k);
227 }
228 ArrOfDouble vit_paroi(dimension);
229 ArrOfDouble val(dimension-1);
230
231 for (int num_face = ndeb; num_face < nfin; num_face++)
232 {
233 if (isdiri)
234 {
235 int rang = num_face-ndeb;
236 for (int k = 0; k < dimension; k++)
237 vit_paroi[k] = vitesse_imposee_face_bord(rang, k);
238 }
239 ori = orientation(num_face);
240 if ((elem = face_voisins(num_face, 0)) != -1)
241 {
242 //norm_v=norm_2D_vit(vit,elem,ori,domaine_VDF,val);
243 norm_v = norm_vit(vit, elem, ori, domaine_VDF, vit_paroi, val);
244 signe = -1.;
245 }
246 else
247 {
248 elem = face_voisins(num_face, 1);
249 //norm_v=norm_2D_vit(vit,elem,ori,domaine_VDF,val);
250 norm_v = norm_vit(vit, elem, ori, domaine_VDF, vit_paroi, val);
251 signe = 1.;
252 }
253
254 if (axi)
255 dist = domaine_VDF.dist_norm_bord_axi(num_face);
256 else
257 dist = domaine_VDF.dist_norm_bord(num_face);
258
259 if (l_unif)
260 d_visco = visco;
261 else
262 d_visco = tab_visco(elem, 0);
263
264 u_plus_d_plus = norm_v*dist/d_visco;
265
266 // Calcul de u* et des grandeurs turbulentes:
267 if (isKeps)
268 {
269 //tab1=tab_k_eps
270
271 // calculer_local(u_plus_d_plus,d_visco,tab_k_eps,norm_v,dist,elem,num_face);
272 calculer_local(u_plus_d_plus, d_visco, tab1, norm_v, dist, elem, num_face);
273 }
274 else
275 {
276 // tab1=tab_nu_t
277 // tab2=tab_k
278 //calculer_local(u_plus_d_plus,d_visco,tab_nu_t,tab_k,norm_v,dist,elem,num_face);
279 calculer_local(u_plus_d_plus, d_visco, tab1, tab2, norm_v, dist, elem, num_face);
280 }
281
282 // Calcul de la contrainte tangentielle
283 double vit_frot = tab_u_star(num_face)*tab_u_star(num_face);
284 if (ori == 0)
285 {
286 Cisaillement_paroi_(num_face, 1) = vit_frot*val[0]*signe;
287 if (dimension == 3)
288 Cisaillement_paroi_(num_face, 2) = vit_frot*val[1]*signe;
289 Cisaillement_paroi_(num_face, 0) = 0.;
290 }
291 else if (ori == 1)
292 {
293 Cisaillement_paroi_(num_face, 0) = vit_frot*val[0]*signe;
294 if (dimension == 3)
295 Cisaillement_paroi_(num_face, 2) = vit_frot*val[1]*signe;
296 Cisaillement_paroi_(num_face, 1) = 0.;
297 }
298 else
299 {
300 Cisaillement_paroi_(num_face, 0) = vit_frot*val[0]*signe;
301 Cisaillement_paroi_(num_face, 1) = vit_frot*val[1]*signe;
302 Cisaillement_paroi_(num_face, 2) = 0.;
303 }
304
305 // Calcul de u+ d+
307 num_face, dist, d_visco, norm_v) ;
308 }
309 }
310 }
311 Cisaillement_paroi_.echange_espace_virtuel();
313 if (!isKeps) tab2.echange_espace_virtuel();
314 //////////////////////////////////////////////////////
315
316
317 /////////////////////////////////////////
318 //YB:24/11/04
319 ////////////////////////
320 //Postraitement angles
321 ////////////////////////
322 /* if (dimension==3)
323 {
324 const double& tps = eqn_hydr.schema_temps().temps_courant();
325 const IntTab& elem_faces = domaine_VDF.elem_faces();
326 SFichier fic_angle("angles.dat",ios::app); // impression des faces parietales et leur coordonnees
327 double angle_u;
328 double angle_cis;
329 double cos_angle_u;
330 double cos_angle_cis;
331 double sin_angle_u;
332 double sin_angle_cis;
333 double vit0, vit1;
334 int elem_ndeb = 0;
335 ndeb = 0;
336 //La face ndeb correspond ici a la premiere face parietale du bas
337 const DoubleTab& xp = domaine_VDF.xp();
338
339 for (int n_bord=0; n_bord<domaine_VDF.nb_front_Cl(); n_bord++)
340 {
341 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
342
343 if (sub_type(Dirichlet_paroi_fixe,la_cl.valeur()) )
344 {
345 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
346
347 ndeb = le_bord.num_premiere_face();
348 ement_paroi_(num_face, 0) = vit_frot*va
349 if ((elem_ndeb = face_voisins(ndeb,0)) == -1)
350 {
351 elem_ndeb = face_voisins(ndeb,1);
352 }
353
354 int ori_ndeb=orientation(ndeb);
355
356 if(xp(elem_ndeb,1)<1.) //Channel height=2
357 {
358 // 1er couple de faces perpendiculaires a la paroi
359 int face1 = elem_faces(elem_ndeb ,(ori_ndeb+1));
360 int face2 = elem_faces(elem_ndeb ,(ori_ndeb+4)%6);
361 vit0 = 0.5*(vit(face1)+vit(face2));
362
363 // 2e couple de faces perpendiculaires a la paroi
364 int face3 = elem_faces(elem_ndeb ,(ori_ndeb+2));
365 int face4 = elem_faces(elem_ndeb ,(ori_ndeb+5)%6);
366 vit1 = 0.5*(vit(face3)+vit(face4));
367
368 cos_angle_u = vit1/(sqrt(vit0*vit0+vit1*vit1));
369
370 sin_angle_u = vit0/(sqrt(vit0*vit0+vit1*vit1));
371
372 cos_angle_cis = Cisaillement_paroi_(ndeb,0)
373 /sqrt(Cisaillement_paroi_(ndeb,0)*Cisaillement_paroi_(ndeb,0)
374 +Cisaillement_paroi_(ndeb,2)*Cisaillement_paroi_(ndeb,2));
375
376 sin_angle_cis = Cisaillement_paroi_(ndeb,2)
377 /sqrt(Cisaillement_paroi_(ndeb,0)*Cisaillement_paroi_(ndeb,0)
378 +Cisaillement_paroi_(ndeb,2)*Cisaillement_paroi_(ndeb,2));
379
380 if(sin_angle_u > 0)
381 angle_u = -acos(cos_angle_u);
382 else
383 angle_u = acos(cos_angle_u);
384
385 if(sin_angle_cis > 0)
386 angle_cis = -acos(cos_angle_cis);
387 else
388 angle_cis = acos(cos_angle_cis);
389
390 fic_angle << tps << " " << angle_u << " " << angle_cis << finl;
391 }
392 }
393 }
394 }
395
396 ////////////////////////////////////////////////////////////////////////
397 */
398 return 1;
399}
400
401// For K_Omega model
403{
404 uplus_.resize(le_dom_dis_->nb_faces_bord());
406 Cmu_ = mon_modele_turb_hyd->get_Cmu();
410 return 1;
411}
412
414{
415 // Yplus computation as in OpenFOAM
416 double yplus = 11;
417
418 for (int iter = 0; iter < 10; ++iter)
419 yplus = log(std::max(Erugu*yplus, 1.))/Kappa_;
420
421 ypluslam = yplus;
422}
423
424int Paroi_std_hyd_VDF::compute_law_komega(DoubleTab& field_komega)
425{
426 const Domaine_VDF& domaine_VDF = ref_cast(Domaine_VDF, le_dom_dis_.valeur());
427 const IntVect& orientation = domaine_VDF.orientation();
428 const IntTab& face_voisins = domaine_VDF.face_voisins();
429 const Equation_base& eqn_hydr = mon_modele_turb_hyd->equation();
430 const Fluide_base& le_fluide = ref_cast(Fluide_base, eqn_hydr.milieu());
431 const Champ_Don_base& ch_visco_cin = le_fluide.viscosite_cinematique();
432 const DoubleVect& vit = eqn_hydr.inconnue().valeurs();
433 const DoubleTab& tab_visco = ch_visco_cin.valeurs();
434 double visco = -1;
435
436 // cAlan : devrait pouvoir être fait une seule fois au prépare ?
437 // cAlan : si pas uniforme, on met à jour, sinon inutile de refaire ça.
438 int l_unif {0};
439 if (sub_type(Champ_Uniforme, ch_visco_cin))
440 {
441 visco = std::max(tab_visco(0, 0), DMINFLOAT);
442 l_unif = 1;
443 }
444
445 // preparer_calcul_hyd(tab);
446 if ((!l_unif) && (tab_visco.local_min_vect()<DMINFLOAT))
447 // on ne doit pas changer tab_visco ici !
448 {
449 Cerr << "In Paroi_std_hyd_VDF::compute_law_komega : visco = " << tab_visco.local_min_vect() << " <= 0 ? " << finl;
450 throw;
451 }
452 int ndeb, nfin, elem, ori;
453 //double norm_v, dist, u_plus_d_plus {0}, d_visco;
454 double norm_v, dist, d_visco;
455 //u_plus_d_plus += 1;
456 //double val,val1,val2;
457
458 //****************************************************************
459 // Modifs du 19/10 pour etre coherent avec la diffusion turbulente
460 double signe;
461 //****************************************************************
462
463 // Boucle sur les bords
464 for (int n_bord = 0; n_bord < domaine_VDF.nb_front_Cl(); n_bord++)
465 {
466
467 // pour chaque condition limite on regarde son type
468 // On applique les lois de paroi uniquement
469 // aux voisinages des parois
470
471 // cAlan : remplaçable par un tableau rempli en début de calcul ?
472 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
473 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
474 ndeb = le_bord.num_premiere_face();
475 nfin = ndeb + le_bord.nb_faces();
476
477 if (sub_type(Dirichlet_paroi_fixe, la_cl.valeur()) || sub_type(Dirichlet_paroi_defilante, la_cl.valeur() ))
478 {
479 int isdiri = 0;
480 DoubleTab vitesse_imposee_face_bord(le_bord.nb_faces(), dimension);
481
482 // Text for paroi_defilante
483 if (sub_type(Dirichlet_paroi_defilante, la_cl.valeur()))
484 {
485 isdiri = 1;
487 la_cl.valeur());
488 for (int face = ndeb; face < nfin; face++)
489 for (int k = 0; k < dimension; k++)
490 vitesse_imposee_face_bord(face - ndeb, k) = cl_diri.val_imp(face - ndeb, k);
491 }
492
493 ArrOfDouble vit_paroi (dimension);
494 ArrOfDouble val (dimension - 1);
495 for (int num_face = ndeb; num_face < nfin; num_face++)
496 {
497 if (isdiri) // for cl paroi_defilante uniquement
498 for (int k = 0; k < dimension; k++)
499 vit_paroi[k] = vitesse_imposee_face_bord(num_face - ndeb, k);
500
501 ori = orientation(num_face);
502 if ((elem = face_voisins(num_face, 0)) != -1)
503 {
504 //norm_v=norm_2D_vit(vit,elem,ori,domaine_VDF,val);
505 norm_v = norm_vit(vit, elem, ori, domaine_VDF, vit_paroi, val);
506 signe = -1.;
507 }
508 else
509 {
510 elem = face_voisins(num_face, 1);
511 //norm_v=norm_2D_vit(vit,elem,ori,domaine_VDF,val);
512 norm_v = norm_vit(vit, elem, ori, domaine_VDF, vit_paroi, val);
513 signe = 1.;
514 }
515
516 // Axisymmetric treatment
517 if (axi)
518 dist = domaine_VDF.dist_norm_bord_axi(num_face);
519 else
520 dist = domaine_VDF.dist_norm_bord(num_face);
521
522 // Get viscosity
523 if (l_unif)
524 d_visco = visco;
525 else
526 d_visco = tab_visco(elem, 0);
527
528 const double u_plus_d_plus = norm_v*dist/d_visco;
529
530 compute_layer_selection(u_plus_d_plus, d_visco, field_komega,norm_v, dist, elem, num_face);
531
532 // Calcul de la contrainte tangentielle
533 double vit_frot = tab_u_star(num_face)*tab_u_star(num_face);
534 if (ori == 0)
535 {
536 Cisaillement_paroi_(num_face, 1) = vit_frot*val[0]*signe;
537 if (dimension == 3)
538 Cisaillement_paroi_(num_face, 2) = vit_frot*val[1]*signe;
539 Cisaillement_paroi_(num_face, 0) = 0.;
540 }
541 else if (ori == 1)
542 {
543 Cisaillement_paroi_(num_face, 0) = vit_frot*val[0]*signe;
544 if (dimension == 3)
545 Cisaillement_paroi_(num_face, 2) = vit_frot*val[1]*signe;
546 Cisaillement_paroi_(num_face, 1) = 0.;
547 }
548 else
549 {
550 Cisaillement_paroi_(num_face, 0) = vit_frot*val[0]*signe;
551 Cisaillement_paroi_(num_face, 1) = vit_frot*val[1]*signe;
552 Cisaillement_paroi_(num_face, 2) = 0.;
553 }
554
555 // Calcul de u+ d+
557 num_face, dist, d_visco, norm_v) ;
558 }
559 }
560 }
561 Cisaillement_paroi_.echange_espace_virtuel();
562 field_komega.echange_espace_virtuel();
563
564 return 1;
565}
566
567int Paroi_std_hyd_VDF::compute_layer_selection(double u_plus_d_plus, double d_visco,
568 DoubleTab& field_komega, double norm_vit,
569 double dist, int elem, int num_face)
570{
571 double valmin = table_hyd.val(5); // y+=5, the upper bound of the viscous layer
572 double valmax = table_hyd.val(30); // y+=30, the lower bound of the inertial sub-layer
573
574 if (u_plus_d_plus <= valmin)
575 {
576 // Viscours sub-layer
577 calculer_u_star_sous_couche_visq(norm_vit, d_visco, dist, num_face);
578 compute_viscous_layer(field_komega, dist, d_visco, elem);
579 }
580 else if ((u_plus_d_plus > valmin) && (u_plus_d_plus < valmax))
581 {
582 // Buffer layer
583 double d_plus;
584 calculer_u_star_sous_couche_tampon(d_plus, u_plus_d_plus, d_visco, dist, num_face);
585 compute_buffer_layer(field_komega, dist, d_visco, elem, num_face);
586 }
587 else // if (u_plus_d_plus >= valmax)
588 {
589 // Inertial sub-layer
590 calculer_u_star_sous_couche_log(norm_vit, d_visco, dist, num_face);
591 compute_log_layer(field_komega, dist, elem, num_face);
592 }
593 return 1;
594}
595
596int Paroi_std_hyd_VDF::compute_viscous_layer(DoubleTab& field_komega, double dist_y,
597 double viscosity, int elem)
598{
599 field_komega(elem, 0) = 0;
600 field_komega(elem, 1) = 6.*coeff_omega_wall_*viscosity/(BETA1*dist_y*dist_y);
601 return 1;
602}
603
604int Paroi_std_hyd_VDF::compute_buffer_layer(DoubleTab& field_komega, double dist_y,
605 double viscosity, int elem, int face)
606{
607 const double u_star = tab_u_star_(face);
608 //const double u_star_carre = u_star*u_star;
609
610 // TANH mean, as a first test. Other blendings could be
611 // implemented. See OpenFOAM here
612 // (https://www.openfoam.com/documentation/guides/latest/api/omegaWallFunctionFvPatchScalarField_8C_source.html)
613 // for examples
614 const double yPlus = u_star*dist_y/viscosity;
615
616 double lm_plus = calcul_lm_plus(yPlus);
617 double deriv = Fdypar_direct(lm_plus);
618 double x = lm_plus*u_star*deriv;
619
620 field_komega(elem, 0) = x*x/sCmu;//;u_star_carre/sCmu;
621 const double phiTanh = tanh(0.1*0.1*0.1*0.1*yPlus*yPlus*yPlus*yPlus);
622 const double omega_vis = 6.*coeff_omega_wall_*viscosity/(BETA1*dist_y*dist_y);
623 const double omega_log = u_star/(std::sqrt(BETA_K)*Kappa_*dist_y);
624 const double b1 = omega_vis + omega_log;
625 const double b2 = pow(pow(omega_vis, 1.2) + pow(omega_log,1.2), 1.0/1.2);
626
627 field_komega(elem, 1) = phiTanh*b1 + (1 - phiTanh)*b2;
628
629 return 1;
630}
631
632int Paroi_std_hyd_VDF::compute_log_layer(DoubleTab& field_komega, double dist_y, int elem, int face)
633{
634 const double u_star = tab_u_star(face);
635 const double u_star_carre = u_star*u_star;
636
637 field_komega(elem, 0) = u_star_carre/sqrt(Cmu_);
638 field_komega(elem, 1) = u_star/(std::sqrt(BETA_K)*Kappa_*dist_y);
639
640 return 1;
641}
642
643// Calcul de u+ d+
644void Paroi_std_hyd_VDF::calculer_uplus_dplus(DoubleVect& uplus, DoubleVect& dplus,
645 DoubleVect& tab_ustar, int num_face,
646 double dist, double d_visco, double norm_v)
647{
648 double ustar = tab_ustar(num_face);
649 dplus(num_face) = ustar*dist/d_visco;
650 if (ustar != 0)
651 uplus(num_face) = norm_v/ustar;
652}
653
654// Version k_eps
655int Paroi_std_hyd_VDF::calculer_local(double u_plus_d_plus, double d_visco,
656 DoubleTab& k_eps, double norm_vit,
657 double dist, int elem, int num_face)
658{
659 double valmin = table_hyd.val(5); // y+=5, the upper bound of the viscous layer
660 double valmax = table_hyd.val(30); // y+=30, the lower bound of the inertial sub-layer
661
662 if (u_plus_d_plus <= valmin)
663 {
664 // Viscours sub-layer
665 calculer_u_star_sous_couche_visq(norm_vit, d_visco, dist, num_face);
666 calculer_sous_couche_visq(k_eps, dist, elem, d_visco, num_face);
667 }
668
669 else if ((u_plus_d_plus > valmin) && (u_plus_d_plus < valmax))
670 {
671 // Buffer layer
672 double d_plus;
673 calculer_u_star_sous_couche_tampon(d_plus, u_plus_d_plus, d_visco, dist, num_face);
674 calculer_sous_couche_tampon(k_eps, d_visco, d_plus, elem, num_face);
675 }
676
677 else // if (u_plus_d_plus >= valmax)
678 {
679 // Inertial sub-layer
680 calculer_u_star_sous_couche_log(norm_vit, d_visco, dist, num_face);
681 calculer_sous_couche_log(k_eps, dist, elem, num_face);
682 }
683 return 1;
684}
685
686// Version nu_t et tab_k
687int Paroi_std_hyd_VDF::calculer_local(double u_plus_d_plus,double d_visco,
688 DoubleTab& tab_nu_t, DoubleTab& tab_k, double norm_vit,
689 double dist, int elem, int num_face)
690{
691 double valmin = table_hyd.val(5); // y+=5, the upper bound of the viscous layer
692 double valmax = table_hyd.val(30); // y+=30, the lower bound of the inertial sub-layer
693
694 if (u_plus_d_plus <= valmin)
695 {
696 // Viscous sub-layer
697 calculer_u_star_sous_couche_visq(norm_vit, d_visco, dist, num_face);
698 calculer_sous_couche_visq(tab_nu_t, tab_k, elem);
699 }
700
701 else if ((u_plus_d_plus > valmin) && (u_plus_d_plus < valmax))
702 {
703 // Buffer layer
704 double d_plus;
705 calculer_u_star_sous_couche_tampon(d_plus, u_plus_d_plus, d_visco, dist, num_face);
706 calculer_sous_couche_tampon(tab_nu_t, tab_k, d_visco, d_plus, elem, num_face);
707 }
708
709 else if (u_plus_d_plus >= valmax)
710 {
711 // Inertial sub-layer
712 calculer_u_star_sous_couche_log(norm_vit, d_visco, dist, num_face);
713 calculer_sous_couche_log(tab_nu_t, tab_k, dist, elem, num_face);
714 }
715 return 1;
716}
717
718// Return u_star directly
719double Paroi_std_hyd_VDF::calculer_local(double u_plus_d_plus, double d_visco, double norm_vit,
720 double dist, int& type_cou, double& d_plus)
721{
722 double valmin = table_hyd.val(5); // y+=5, the upper bound of the viscous layer
723 double valmax = table_hyd.val(30); // y+=30, the lower bound of the inertial sub-layer
724 double u_star;
725
726 if (u_plus_d_plus <= valmin)
727 {
728 // Viscous layer
729 u_star = calculer_u_star_sous_couche_visq(norm_vit, d_visco, dist);
730 //Cerr << "Premier point dans le sous-couche visqueuse : y+=" << u_star*dist/d_visco << finl;
731 type_cou = 0;
732 }
733
734 else if ((u_plus_d_plus > valmin) && (u_plus_d_plus < valmax))
735 {
736 // Buffer layer
737 u_star = calculer_u_star_sous_couche_tampon(u_plus_d_plus, d_visco, dist, d_plus);
738 //Cerr << "Premier point dans le sous-couche tampon : y+=" << u_star*dist/d_visco << finl;
739 type_cou = 1;
740 }
741
742 else if (u_plus_d_plus >= valmax)
743 {
744 // Inertial sub-layer
745 u_star = calculer_u_star(norm_vit, d_visco, dist);
746 // Cerr << "Premier point dans le sous-couche log : y+=" << u_star*dist/d_visco << finl;
747 type_cou = 2;
748 }
749 else
750 {
751 // cAlan : pourquoi ce bloc ?!
752 //bizarre
753 u_star = 0;
754 assert(0);
756 }
757 return u_star;
758}
759
760// = Viscous layer
761// Avec stockage dans tableau tab_u_star_
762int Paroi_std_hyd_VDF::calculer_u_star_sous_couche_visq(double norm_vit, double d_visco,
763 double dist, int face)
764{
765 // Dans la sous couche visqueuse: u* = sqrt(u*nu/d)
766
767 tab_u_star_(face) = sqrt(norm_vit*d_visco/dist);
768 // Cerr<<" USTA "<<face<<" "<< tab_u_star_(face)<<finl;
769 return 1;
770}
771
772// Retourne la vitesse sans stockage dans le tableau tab_u_star_
773double Paroi_std_hyd_VDF::calculer_u_star_sous_couche_visq(double norm_vit, double d_visco,
774 double dist)
775{
776 // Dans la sous couche visqueuse: u* = sqrt(u*nu/d)
777 return sqrt(norm_vit*d_visco/dist);
778}
779
780// Version K_Eps
781int Paroi_std_hyd_VDF::calculer_sous_couche_visq(DoubleTab& K_eps, double dist,
782 int elem, double d_visco, int face)
783{
784 // Dans la sous couche visqueuse: k = eps = 0
785
786 // cAlan : attention k_eps k-eps k-epsilon !
787 K_eps(elem, 0) = 0.;
788 K_eps(elem, 1) = 0.;
789
790 return 1;
791
792 // cAlan : Tout ce bloc n'est pas appelé ?!
793 double u_star = tab_u_star(face);
794 double d_plus = dist*u_star/d_visco;
795 double u_star_carre = u_star*u_star;
796 double C = 0.08; // cAlan est-ce le Cmu ?!
797 double alpha = 0.06; // cAlan : pourquoi ce changement de valeur de alpha ?!
798 alpha = 0.06550;
799 // f1=f2=fmu=1
800 alpha = 0.3;
801 // f1=f2+1 fmu de LS
802 alpha = 0.05480;
803
804 K_eps(elem, 0) = u_star_carre*d_plus*d_plus*C;
805 //K_eps(elem,1) = u_star_carre*u_star_carre/d_visco*(d_plus*0.005);
806 K_eps(elem, 1) = u_star_carre*u_star_carre/d_visco*(d_plus*d_plus*C)*alpha;
807 //assert(0);
808 //exit();
809 return 1;
810}
811
812// Version nu_t et K
813int Paroi_std_hyd_VDF::calculer_sous_couche_visq(DoubleTab& nu_t, DoubleTab& k, int elem)
814{
815 // Dans la sous couche visqueuse: nu_t = k = 0
816 nu_t(elem) = 0.;
817 k(elem,0) = 0.;
818 return 1;
819}
820
821// = Buffer layer
822int Paroi_std_hyd_VDF::calculer_u_star_sous_couche_tampon(double& d_plus, double u_plus_d_plus,
823 double d_visco, double dist, int face)
824{
825 // Calcul de d_plus solution de table_hyd(inconnue) = u_plus_d_plus
826 // puis calcul de u* dans la sous-couche tampon : u* = nu*d+/dist
827 double d_plus_min = 5; // y+=5, the upper bound of the viscous layer
828 double d_plus_max = 30; // y+=30, the lower bound of the inertial sub-layer
829 double epsilon = 1.e-12;
830 double gauche = table_hyd.val(d_plus_min);
831 double droite = table_hyd.val(d_plus_max);
832
833 if (gauche == droite)
834 d_plus = d_plus_min;
835 else
836 {
837 while(1)
838 {
839 double deriv = (droite - gauche)/(d_plus_max - d_plus_min);
840 d_plus = d_plus_min + (u_plus_d_plus - gauche)/deriv;
841 double valeur = table_hyd.val(d_plus);
842 if (std::fabs(valeur - u_plus_d_plus) < epsilon)
843 {
844 double u_star = (d_visco*d_plus)/dist;
845 tab_u_star_(face) = u_star;
846 return 1;
847 }
848 if (valeur > u_plus_d_plus)
849 {
850 droite = valeur;
851 d_plus_max = d_plus;
852 }
853 else
854 {
855 gauche = valeur;
856 d_plus_min = d_plus;
857 }
858 }
859 }
860 return -1;
861}
862
863// Version avec passage de K_eps
864int Paroi_std_hyd_VDF::calculer_sous_couche_tampon(DoubleTab& K_eps, double d_visco,
865 double d_plus, int elem, int face)
866{
867 // Calcul des grandeurs turbulentes a partir de d_plus et de u_star
868 double u_star = tab_u_star(face);
869 double lm_plus = calcul_lm_plus(d_plus);
870 double deriv = Fdypar_direct(lm_plus);
871 double x = lm_plus*u_star*deriv;
872
873 // Dans la sous couche tampon :
874 //
875 // k = lm+ * u* * derivee(u+d+(d+))/sqrt(Cmu_)
876 //
877 // 2
878 // eps = k * u* * derivee(u+d+(d+))*sqrt(Cmu_)/nu
879 //
880
881 // K_eps(elem,0) = std::max( K_eps(elem,0) , x*x/sqrt(Cmu_) );
882
883 //K_eps(elem,1) = std::max( K_eps(elem,1) , (K_eps(elem,0)*u_star*u_star*deriv)*sqrt(Cmu_)/d_visco );
884
885
886 K_eps(elem,0) = x*x/sqrt(Cmu_) ;
887 K_eps(elem,1) = (K_eps(elem,0)*u_star*u_star*deriv)*sqrt(Cmu_)/d_visco;
888
889 return 1;
890}
891
892// Version avec passage de nu_t et tab_k
893int Paroi_std_hyd_VDF::calculer_sous_couche_tampon(DoubleTab& nu_t,DoubleTab& tab_k,
894 double d_visco,double d_plus,
895 int elem,int face)
896{
897 // Calcul des grandeurs turbulentes a partir de d_plus et de u_star
898
899 double u_star = tab_u_star(face);
900 double lm_plus = calcul_lm_plus(d_plus);
901 double deriv = Fdypar_direct(lm_plus);
902 double x = lm_plus*u_star*deriv;
903
904 // Dans la sous couche tampon :
905 //
906 // k = lm+ * u* * derivee(u+d+(d+))/sqrt(Cmu_)
907 //
908 // 2
909 // eps = k * u* * derivee(u+d+(d+))*sqrt(Cmu_)/nu
910 //
911 // nu_t = Cmu*k*k/eps
912 //
913
914 double k = x*x/sqrt(Cmu_);
915 double eps = (k*u_star*u_star*deriv)*sqrt(Cmu_)/d_visco;
916 tab_k(elem,0) = k;
917 nu_t(elem) = Cmu_*k*k/eps;
918 return 1;
919}
920
921double Paroi_std_hyd_VDF::calculer_u_star_sous_couche_tampon(double u_plus_d_plus, double d_visco,
922 double dist, double& d_plus)
923{
924 // Calcul de d_plus solution de table_hyd(inconnue) = u_plus_d_plus
925 // puis calcul de u* dans la sous-couche tampon : u* = nu*d+/dist
926 double d_plus_min = 5; // y+=5, the upper bound of the viscous layer
927 double d_plus_max = 30; // y+=30, the lower bound of the inertial sub-layer
928 double u_star = 0.;
929 double epsilon = 1.e-12;
930 double gauche = table_hyd.val(d_plus_min);
931 double droite = table_hyd.val(d_plus_max);
932 int atteint = 2;
933
934 if (gauche == droite)
935 d_plus = d_plus_min;
936 else
937 {
938 while(atteint != 1)
939 {
940 double deriv = (droite - gauche)/(d_plus_max - d_plus_min);
941 d_plus = d_plus_min + (u_plus_d_plus - gauche)/deriv;
942 double valeur = table_hyd.val(d_plus);
943 if(std::fabs(valeur - u_plus_d_plus) < epsilon)
944 {
945 u_star = (d_visco*d_plus)/dist;
946 atteint = 1;
947 }
948 if(valeur > u_plus_d_plus)
949 {
950 droite = valeur;
951 d_plus_max = d_plus;
952 }
953 else
954 {
955 gauche = valeur;
956 d_plus_min = d_plus;
957 }
958 }
959 }
960 return u_star;
961}
962
963// = Log layer
964int Paroi_std_hyd_VDF::calculer_u_star_sous_couche_log(double norm_vit, double d_visco,
965 double dist, int face)
966{
967 // Dans la sous couche inertielle u* est solution d'une equation
968 // differentielle resolue de maniere iterative
969
970 const double Xpini = 30.;
971 // const double Xpini = 200.;
972 const int itmax = 25;
973 const double seuil = 0.01;
974 const double c1 = Kappa_*norm_vit;
975 const double c2 = log(Erugu*dist/d_visco); // log = logarithme neperien
976
977 double u_star = Xpini*d_visco/dist;
978 int iter = 0;
979 double u_star1 = 1;
980 while ((iter++ < itmax) && (std::fabs(u_star1) > seuil))
981 {
982 u_star1 = (c1 - u_star*(log(u_star) + c2))/(c1 + u_star);
983 u_star = (1 + u_star1)*u_star;
984 }
985 if (std::fabs(u_star1) >= seuil) erreur_non_convergence();
986 tab_u_star_(face) = u_star;
987 return 1;
988}
989
990// Version avec tableau k_eps
991int Paroi_std_hyd_VDF::calculer_sous_couche_log(DoubleTab& K_eps, double dist,
992 int elem,int face)
993{
994 // K et Eps sont donnes par les formules suivantes:
995 //
996 // 2 3
997 // k = u*/sqrt(Cmu_) et eps = u* / Kd
998 //
999
1000 double u_star = tab_u_star(face);
1001 double u_star_carre = u_star*u_star;
1002
1003 K_eps(elem, 0) = u_star_carre/sqrt(Cmu_);
1004 K_eps(elem, 1) = u_star_carre*u_star/(Kappa_*dist);
1005
1006 return 1;
1007}
1008
1009// Version avec nu_t et tab_k
1010int Paroi_std_hyd_VDF::calculer_sous_couche_log(DoubleTab& nu_t, DoubleTab& tab_k,
1011 double dist, int elem, int face)
1012{
1013 // nu_t = Cmu*k*k/eps
1014 //
1015 // 2 3
1016 // En utilisant k = u*/sqrt(Cmu_) et eps = u* / Kd
1017 //
1018 // on calcule nu_t en fonction de u*
1019
1020 double u_star = tab_u_star(face);
1021
1022 tab_k(elem,0) = u_star*u_star/sqrt(Cmu_);
1023 nu_t(elem) = u_star*Kappa_*dist;
1024
1025 return 1;
1026}
1027// = End of boundary layer functions
1028
1030{
1031 const Domaine_VDF& domaine_VDF = ref_cast(Domaine_VDF, le_dom_dis_.valeur());
1032 int ndeb, nfin;
1033 DoubleVect moy(4);
1034 moy = 0.;
1035 double norme_L2 = 0.;
1036 EcrFicPartage Ustar;
1037 ouvrir_fichier_partage(Ustar, "Ustar");
1038
1039 for (int n_bord = 0; n_bord < domaine_VDF.nb_front_Cl(); n_bord++)
1040 {
1041 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
1042 if ((sub_type(Dirichlet_paroi_fixe, la_cl.valeur())) ||
1043 (sub_type(Dirichlet_paroi_defilante, la_cl.valeur())))
1044 {
1045 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
1046 if(je_suis_maitre())
1047 {
1048 Ustar << finl;
1049 Ustar << "Bord " << le_bord.le_nom() << finl;
1050 if (dimension == 2)
1051 {
1052 Ustar << "-------------------------------------------------------------------------------------------";
1053 Ustar << "--------------------------------------------------------------------------------------------" << finl;
1054 Ustar << "\tFace a\t\t\t\t|\t\t\t\t\t\t\t\t\t| TAU=Nu.Grad(Ut) [m2/s2]" << finl;
1055 Ustar << "----------------------------------------|--------------------------------------------------";
1056 Ustar << "---------------------|----------------------------------------------------------------------" << finl;
1057 Ustar << "X\t\t| Y\t\t\t| u+\t\t\t| d+\t\t\t| u*\t\t\t| ||TAU||_2\t\t| |TAUx|\t\t| |TAUy|" << finl;
1058 Ustar << "----------------|-----------------------|-----------------------|-----------------------|--";
1059 Ustar << "---------------------|-----------------------|-----------------------|----------------------" << finl;
1060 }
1061 if (dimension == 3)
1062 {
1063 Ustar << "-----------------------------------------------------------------------------------------------------------------";
1064 Ustar << "-----------------------------------------------------------------------------------------------------------------" << finl;
1065 Ustar << "\tFace a\t\t\t\t\t\t\t|\t\t\t\t\t\t\t\t\t| TAU=Nu.Grad(Ut) [m2/s2]" << finl;
1066 Ustar << "----------------------------------------------------------------|------------------------------------------------";
1067 Ustar << "-----------------------|-----------------------------------------------------------------------------------------" << finl;
1068 Ustar << "X\t\t| Y\t\t\t| Z\t\t\t| u+\t\t\t| d+\t\t\t| u*\t\t\t| ||TAU||_2\t\t| |TAUx|\t\t| |TAUy|\t\t| |TAUz|" << finl;
1069 Ustar << "----------------|-----------------------|-----------------------|-----------------------|-----------------------|";
1070 Ustar << "-----------------------|-----------------------|-----------------------|-----------------------|-----------------" << finl;
1071 }
1072 }
1073 ndeb = le_bord.num_premiere_face();
1074 nfin = ndeb + le_bord.nb_faces();
1075 for (int num_face = ndeb; num_face < nfin; num_face++)
1076 {
1077 double x = domaine_VDF.xv(num_face,0);
1078 double y = domaine_VDF.xv(num_face,1);
1079 norme_L2 = Cisaillement_paroi_(num_face,0)*Cisaillement_paroi_(num_face,0)
1080 + Cisaillement_paroi_(num_face,1)*Cisaillement_paroi_(num_face,1);
1081
1082 if (dimension == 2)
1083 Ustar << x << "\t| " << y;
1084 if (dimension == 3)
1085 {
1086 double z = domaine_VDF.xv(num_face, 2);
1087 Ustar << x << "\t| " << y << "\t| " << z;
1088 norme_L2 += Cisaillement_paroi_(num_face, 2)*Cisaillement_paroi_(num_face, 2);
1089 }
1090 norme_L2 = sqrt(norme_L2);
1091
1092 Ustar << "\t| " << uplus_(num_face)
1093 << "\t| " << tab_d_plus(num_face)
1094 << "\t| " << tab_u_star(num_face)
1095 << "\t| " << norme_L2
1096 << "\t| " << Cisaillement_paroi_(num_face, 0)
1097 << "\t| " << Cisaillement_paroi_(num_face, 1);
1098 if (dimension == 3)
1099 Ustar << "\t| " << Cisaillement_paroi_(num_face,2);
1100 Ustar << finl;
1101
1102 // PQ : 03/03 : Calcul des valeurs moyennes (en supposant maillage regulier)
1103 moy(0) += uplus_(num_face);
1104 moy(1) += tab_d_plus(num_face);
1105 moy(2) += tab_u_star(num_face);
1106 moy(3) += 1;
1107 }
1108 Ustar.syncfile();
1109 }
1110 }
1112
1113 if (moy(3) && je_suis_maitre())
1114 {
1115 Ustar << finl;
1116 Ustar << "-------------------------------------------------------------" << finl;
1117 Ustar << "Calcul des valeurs moyennes (en supposant maillage regulier):" << finl;
1118 Ustar << "<u+>= " << moy(0)/moy(3)
1119 << " <d+>= " << moy(1)/moy(3)
1120 << " <u*>= " << moy(2)/moy(3)
1121 << finl;
1122 }
1123
1124 if(je_suis_maitre())
1125 Ustar << finl << finl;
1126 Ustar.syncfile();
1127}
1128
1129//
1130// Calcule les vitesses moyennes aux premieres mailles le long des parois
1131// (norme des vitesses)
1132// LIMITATION au cas du CANAL, avec parois en y=0 et y=2
1133//
1135 double& U_moy_2,
1136 double& dist_1,
1137 double& dist_2,
1138 double& visco_1,
1139 double& visco_2)
1140{
1141 const Domaine_VDF& domaine_VDF = ref_cast(Domaine_VDF, le_dom_dis_.valeur());
1142 const IntTab& face_voisins = domaine_VDF.face_voisins();
1143 const IntTab& elem_faces = domaine_VDF.elem_faces();
1144 const Equation_base& eqn_hydr = mon_modele_turb_hyd->equation();
1145 const DoubleTab& vitesse = eqn_hydr.inconnue().valeurs();
1146 const Fluide_base& le_fluide = ref_cast(Fluide_base,eqn_hydr.milieu());
1147 const Champ_Don_base& ch_visco_cin = le_fluide.viscosite_cinematique();
1148 const DoubleTab& tab_visco = ch_visco_cin.valeurs();
1149 const IntVect& orientation = domaine_VDF.orientation();
1150
1151// double u_m1 = 0.; // moyenne des vitesses selon x, a la paroi 1 (y=0)
1152// double u_m2 = 0.; // moyenne des vitesses selon x, a la paroi 2 (y=2)
1153// double w_m1 = 0.; // moyenne des vitesses selon z, a la paroi 1 (y=0)
1154// double w_m2 = 0.; // moyenne des vitesses selon z, a la paroi 2 (y=2)
1155// int nb_1 = 0;
1156// int nb_2 = 0;
1157
1158 DoubleTrav values(5, 2);
1159 values = 0.;
1160 values(0, 0) = visco_1;
1161 values(0, 1) = visco_2;
1162 values(1, 0) = dist_1;
1163 values(1, 1) = dist_2;
1164// u_m1 -> values(2,0) et u_m2 -> values(2,1)
1165// w_m1 -> values(3,0) et w_m2 -> values(3,1)
1166// nb_1 -> values(4,0) et nb_2 -> values(4,1)
1167
1168 int dir_par, dir1, dir2;
1169 int nb_front_Cl = domaine_VDF.nb_front_Cl();
1170 double visco = -1;
1171 int l_unif = 0;
1172
1173 if (sub_type(Champ_Uniforme,ch_visco_cin))
1174 {
1175 visco = std::max(tab_visco(0, 0), DMINFLOAT);
1176 l_unif = 1;
1177 }
1178 else
1179 {
1180 if (tab_visco.local_min_vect()<DMINFLOAT)
1181 // on ne doit pas changer tab_visco ici !
1182 {
1183 Cerr << "In Paroi_std_hyd_VDF::calculer_moyennes_parois : visco = " << tab_visco.local_min_vect() << " <= 0 ? " << finl;
1184 throw;
1185 }
1186 // tab_visco += DMINFLOATBETA_K;
1187 }
1188
1189 for (int n_bord = 0; n_bord < nb_front_Cl; n_bord++)
1190 {
1191 // pour chaque condition limite on regarde son type
1192 // On applique les lois de paroi uniquement
1193 // aux voisinages des parois
1194 // Dans un premier temps on ne traite que les paroi_fixe,
1195 // qui correspondent a une des 2 parois du canal
1196
1197 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
1198
1199 if (sub_type(Dirichlet_paroi_fixe, la_cl.valeur()) )
1200 {
1201 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
1202 int ndeb = le_bord.num_premiere_face();
1203 int nfin = ndeb + le_bord.nb_faces();
1204 int paroi;
1205 int num_elem;
1206
1207 if (nfin == ndeb)
1208 {
1209 // cas ou le bord est nul
1210 dir_par=-1;
1211 dir1 =-1;
1212 dir2=-1;
1213 }
1214 else
1215 {
1216 dir_par = orientation(ndeb);
1217 // Recherche des deux autres orientations (pas dir_par)
1218 switch(dir_par)
1219 {
1220 case 0:
1221 {
1222 dir1 = 1;
1223 dir2 = 2;
1224 break;
1225 }
1226 case 1:
1227 {
1228 dir1 = 0;
1229 dir2 = 2;
1230 break;
1231 }
1232 case 2:
1233 {
1234 dir1 = 0;
1235 dir2 = 1;
1236 break;
1237 }
1238 default:
1239 {
1240 dir1 = dir2=-1;
1241 Cerr << que_suis_je() <<" Aborting during detection of wall orientation."<< finl;
1242 Cerr<<"Please contact TRUST support."<<finl;
1243 Process::exit();
1244 }
1245 }
1246 }
1247
1248 for (int num_face = ndeb; num_face < nfin; num_face++)
1249 {
1250 // Recherche de l'element associe a cette face de la bordure
1251 // Distinction entre la paroi basse et la paroi haute (specifique au CANAL)
1252 num_elem = face_voisins(num_face, 0);
1253 paroi = 2;
1254 if (num_elem == -1)
1255 {
1256 num_elem = face_voisins(num_face, 1); // Alors on est a la paroi basse!!!
1257 paroi = 1;
1258 }
1259
1260 // Calcul des composantes de la vitesse moyenne
1261 if (paroi == 1)
1262 {
1263 values(2,0) += vitesse(elem_faces(num_elem, dir1));
1264 values(3,0) += vitesse(elem_faces(num_elem, dir2));
1265 values(1,0) += domaine_VDF.dim_elem(num_elem, dir_par);
1266 if (l_unif)
1267 values(0,0) += visco;
1268 else
1269 values(0,0) += tab_visco(num_elem);
1270 values(4,0)++;
1271 }
1272 else
1273 {
1274 values(2,1) += vitesse(elem_faces(num_elem, dir1));
1275 values(3,1) += vitesse(elem_faces(num_elem, dir2));
1276 values(1,1) += domaine_VDF.dim_elem(num_elem, dir_par);
1277 if (l_unif)
1278 values(0,1) += visco;
1279 else
1280 values(0,1) += tab_visco(num_elem);
1281 values(4,1)++;
1282 }
1283 }
1284 }
1285 }
1286
1287 values(1,0) *= 0.5;
1288 values(1,1) *= 0.5;
1289 // Somme les contributions de chaque processeur:
1290 mp_sum_for_each_item(values);
1291 U_moy_1 = sqrt( values(2, 0) * values(2, 0) + values(3, 0) * values(3, 0) ) / values(4, 0);
1292 U_moy_2 = sqrt( values(2, 1) * values(2, 1) + values(3, 1) * values(3, 1) ) / values(4, 1);
1293 dist_1 = values(1, 0)/values(4, 0);
1294 dist_2 = values(1, 1)/values(4, 1);
1295 visco_1 = values(0, 0)/values(4, 0);
1296 visco_2 = values(0, 1)/values(4, 1);
1297
1298}
1299
1300void Paroi_std_hyd_VDF::modifs_valeurs_turb(int num_elem, int type_cou,
1301 double u_star, double dist,
1302 double d_visco, double d_plus,
1303 DoubleTab& tab_nu_t, DoubleTab& tab_k)
1304{
1305
1306 if (type_cou == 0)
1307 {
1308 tab_nu_t(num_elem) = 0.;
1309 tab_k(num_elem) = 0.;
1310 }
1311 else if (type_cou == 1)
1312 {
1313 double lm_plus = calcul_lm_plus(d_plus);
1314 double deriv = Fdypar_direct(lm_plus);
1315 double x= lm_plus*u_star*deriv;
1316
1317 // Dans la sous couche tampon :
1318 //
1319 // k = lm+ * u* * derivee(u+d+(d+))/sqrt(Cmu_)
1320 //
1321 // 2
1322 // eps = k * u* * derivee(u+d+(d+))*sqrt(Cmu_)/nu
1323 //
1324 // nu_t = Cmu*k*k/eps
1325
1326 double k = x*x/sqrt(Cmu_);
1327 double eps = (k*u_star*u_star*deriv)*sqrt(Cmu_)/d_visco;
1328 tab_k(num_elem) = k;
1329 tab_nu_t(num_elem) = Cmu_*k*k/eps;
1330 }
1331 else if (type_cou == 2)
1332 {
1333 tab_k(num_elem) = u_star*u_star/sqrt(Cmu_);
1334 tab_nu_t(num_elem) = u_star*Kappa_*dist ;
1335 }
1336 else
1337 {
1338 Cerr << "Il y a un pbl : type_cou doit etre egal a 0, 1, ou 2!!" << finl;
1339 Cerr << "type_cou=" << type_cou << finl;
1340 Process::exit();
1341 }
1342}
1343
1344double Paroi_std_hyd_VDF::calculer_u_star(double& norm_vit, double& visco, double& dist)
1345{
1346 Cerr << "On ne doit pas passer dans Paroi_std_hyd_VDF::calculer_u_star..." << finl;
1347 Process::exit();
1348 return 1;
1349}
1350
1351
1352int Paroi_std_hyd_VDF::calculer_hyd_BiK(DoubleTab& tab_k, DoubleTab& tab_eps)
1353{
1354
1355// keps
1356 const Domaine_VDF& domaine_VDF = ref_cast(Domaine_VDF, le_dom_dis_.valeur());
1357 const IntVect& orientation = domaine_VDF.orientation();
1358 const IntTab& face_voisins = domaine_VDF.face_voisins();
1359 const Equation_base& eqn_hydr = mon_modele_turb_hyd->equation();
1360 const Fluide_base& le_fluide = ref_cast(Fluide_base, eqn_hydr.milieu());
1361 const Champ_Don_base& ch_visco_cin = le_fluide.viscosite_cinematique();
1362 const DoubleVect& vit = eqn_hydr.inconnue().valeurs();
1363 const DoubleTab& tab_visco = ch_visco_cin.valeurs();
1364 double visco = -1;
1365 int l_unif {0};
1366 if (sub_type(Champ_Uniforme, ch_visco_cin))
1367 {
1368 visco = std::max(tab_visco(0, 0), DMINFLOAT);
1369 l_unif = 1;
1370 }
1371
1372 // preparer_calcul_hyd(tab);
1373 if ((!l_unif) && (tab_visco.local_min_vect()<DMINFLOAT))
1374 // on ne doit pas changer tab_visco ici !
1375 {
1376 Cerr << "In Paroi_std_hyd_VDF::calculer_hyd_BiK : visco = " << tab_visco.local_min_vect() << " <= 0 ? " << finl;
1377 throw;
1378 }
1379
1380 int ndeb, nfin;
1381 int elem, ori;
1382 double norm_v;
1383 double dist;
1384 double u_plus_d_plus, d_visco;
1385 //double val,val1,val2;
1386
1387 //****************************************************************
1388 // Modifs du 19/10 pour etre coherent avec la diffusion turbulente
1389 double signe;
1390 //****************************************************************
1391
1392 // Boucle sur les bords
1393 for (int n_bord=0; n_bord<domaine_VDF.nb_front_Cl(); n_bord++)
1394 {
1395
1396 // pour chaque condition limite on regarde son type
1397 // On applique les lois de paroi uniquement
1398 // aux voisinages des parois
1399
1400 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
1401 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
1402 ndeb = le_bord.num_premiere_face();
1403 nfin = ndeb + le_bord.nb_faces();
1404
1405 if (sub_type(Dirichlet_paroi_fixe,la_cl.valeur()) || sub_type(Dirichlet_paroi_defilante,la_cl.valeur() ))
1406 {
1407 int isdiri=0;
1408 DoubleTab vitesse_imposee_face_bord(le_bord.nb_faces(),dimension);
1409 if (sub_type(Dirichlet_paroi_defilante,la_cl.valeur()) )
1410 {
1411 isdiri=1;
1412 const Dirichlet_paroi_defilante& cl_diri = ref_cast(Dirichlet_paroi_defilante,la_cl.valeur());
1413 for (int face=ndeb; face<nfin; face++)
1414 for (int k=0; k<dimension; k++)
1415 vitesse_imposee_face_bord(face-ndeb,k) = cl_diri.val_imp(face-ndeb,k);
1416 }
1417 ArrOfDouble vit_paroi(dimension);
1418 ArrOfDouble val(dimension-1);
1419
1420 for (int num_face=ndeb; num_face<nfin; num_face++)
1421 {
1422 if (isdiri)
1423 {
1424 int rang = num_face-ndeb;
1425 for (int k=0; k<dimension; k++)
1426 vit_paroi[k]=vitesse_imposee_face_bord(rang,k);
1427 }
1428 ori = orientation(num_face);
1429 if ( (elem =face_voisins(num_face,0)) != -1)
1430 {
1431 //norm_v=norm_2D_vit(vit,elem,ori,domaine_VDF,val);
1432 norm_v=norm_vit(vit,elem,ori,domaine_VDF,vit_paroi,val);
1433 signe = -1.;
1434 }
1435 else
1436 {
1437 elem = face_voisins(num_face,1);
1438 //norm_v=norm_2D_vit(vit,elem,ori,domaine_VDF,val);
1439 norm_v=norm_vit(vit,elem,ori,domaine_VDF,vit_paroi,val);
1440 signe = 1.;
1441 }
1442 if (axi)
1443 dist=domaine_VDF.dist_norm_bord_axi(num_face);
1444 else
1445 dist=domaine_VDF.dist_norm_bord(num_face);
1446 if (l_unif)
1447 d_visco = visco;
1448 else
1449 d_visco = tab_visco(elem,0);
1450
1451 u_plus_d_plus = norm_v*dist/d_visco;
1452
1453 // Calcul de u* et des grandeurs turbulentes:
1454
1455 double valmin = table_hyd.val(5);
1456 double valmax = table_hyd.val(30);
1457
1458 if (u_plus_d_plus <= valmin)
1459 {
1460 calculer_u_star_sous_couche_visq(norm_v,d_visco,dist,num_face);
1461
1462 // Dans la sous couche visqueuse: k = eps = 0
1463
1464 tab_k(elem) = 0.;
1465 tab_eps(elem,1) = 0.;
1466 }
1467
1468 else if ((u_plus_d_plus > valmin) && (u_plus_d_plus < valmax))
1469 {
1470 double d_plus;
1471 calculer_u_star_sous_couche_tampon(d_plus,u_plus_d_plus,d_visco,dist,num_face);
1472
1473 // Calcul des grandeurs turbulentes a partir de d_plus et de u_star
1474 double u_star = tab_u_star(num_face);
1475 double lm_plus = calcul_lm_plus(d_plus);
1476 double deriv = Fdypar_direct(lm_plus);
1477 double x= lm_plus*u_star*deriv;
1478
1479 // Dans la sous couche tampon :
1480 //
1481 // k = lm+ * u* * derivee(u+d+(d+))/sqrt(Cmu_)
1482 //
1483 // 2
1484 // eps = k * u* * derivee(u+d+(d+))*sqrt(Cmu_)/nu
1485 //
1486
1487
1488 tab_k(elem,0) = x*x/sqrt(Cmu_) ;
1489 tab_eps(elem,1) = (tab_k(elem)*u_star*u_star*deriv)*sqrt(Cmu_)/d_visco;
1490
1491 }
1492
1493 else // if (u_plus_d_plus >= valmax)
1494 {
1495 calculer_u_star_sous_couche_log(norm_v,d_visco,dist,num_face);
1496
1497 // K et Eps sont donnes par les formules suivantes:
1498 //
1499 // 2 3
1500 // k = u*/sqrt(Cmu_) et eps = u* / Kd
1501 //
1502
1503 double u_star= tab_u_star(num_face);
1504 double u_star_carre = u_star*u_star;
1505
1506 tab_k(elem) = u_star_carre/sqrt(Cmu_);
1507 tab_eps(elem) = u_star_carre*u_star/(Kappa_*dist);
1508 }
1509
1510 // Calcul de la contrainte tangentielle
1511
1512 double vit_frot = tab_u_star(num_face)*tab_u_star(num_face);
1513
1514 if (ori == 0)
1515 {
1516 Cisaillement_paroi_(num_face,1) = vit_frot*val[0]*signe;
1517 if (dimension==3)
1518 Cisaillement_paroi_(num_face,2) = vit_frot*val[1]*signe;
1519 Cisaillement_paroi_(num_face,0) = 0.;
1520 }
1521 else if (ori == 1)
1522 {
1523 Cisaillement_paroi_(num_face,0) = vit_frot*val[0]*signe;
1524 if (dimension==3)
1525 Cisaillement_paroi_(num_face,2) = vit_frot*val[1]*signe;
1526 Cisaillement_paroi_(num_face,1) = 0.;
1527 }
1528 else
1529 {
1530 Cisaillement_paroi_(num_face,0) = vit_frot*val[0]*signe;
1531 Cisaillement_paroi_(num_face,1) = vit_frot*val[1]*signe;
1532 Cisaillement_paroi_(num_face,2) = 0.;
1533 }
1534
1535 // Calcul de u+ d+
1536 calculer_uplus_dplus(uplus_, tab_d_plus_, tab_u_star_, num_face, dist, d_visco, norm_v) ;
1537 }
1538
1539
1540 }
1541 }
1542 Cisaillement_paroi_.echange_espace_virtuel();
1543 tab_k.echange_espace_virtuel();
1544 tab_eps.echange_espace_virtuel();
1545 return 1;
1546}
classe Champ_Don_base classe de base des Champs donnes (non calcules)
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
classe Champ_Uniforme Represente un champ constant dans l'espace et dans le temps.
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
classe Dirichlet_paroi_defilante Impose la vitesse de paroi dnas une equation de type Navier_Stokes.
classe Dirichlet_paroi_fixe Represente une paroi immobile dans une equation de type Navier_Stokes.
virtual double val_imp(int i) const
Renvoie la valeur imposee sur la i-eme composante du champ a la frontiere au temps par defaut du cham...
Definition Dirichlet.cpp:35
class Domaine_VDF
Definition Domaine_VDF.h:64
double dist_norm_bord_axi(int num_face) const
double dim_elem(int, int) const
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
double dist_norm_bord(int num_face) const override
double xv(int num_face, int k) const
Definition Domaine_VF.h:76
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
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
int nb_front_Cl() const
Sortie & syncfile() override
Provoque l'ecriture sur disque des donnees accumulees sur les differents processeurs depuis le dernie...
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....
virtual const Milieu_base & milieu() const =0
virtual const Champ_Inc_base & inconnue() const =0
classe Fluide_base Cette classe represente un d'un fluide incompressible ainsi que
Definition Fluide_base.h:38
const Champ_Don_base & viscosite_cinematique() const
Definition Fluide_base.h:58
class Front_VF
Definition Front_VF.h:36
int nb_faces() const
Definition Front_VF.h:53
int num_premiere_face() const
Definition Front_VF.h:63
const Nom & le_nom() const override
Renvoie le nom de la frontiere geometrique.
cette classe permet de specifier des options a la loi de paroi standard.
virtual void set_param(Param &) const
Definition Objet_U.h:135
static int dimension
Definition Objet_U.h:99
friend class Sortie
Definition Objet_U.h:75
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
static int axi
Definition Objet_U.h:101
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
void init_lois_paroi_hydraulique_()
void set_param(Param &param) const
double calcul_lm_plus(double d_plus)
CLASS: Paroi_std_hyd_VDF.
int calculer_u_star_sous_couche_visq(double, double, double, int)
int compute_buffer_layer(DoubleTab &, double, double, int, int)
int calculer_u_star_sous_couche_log(double, double, double, int)
virtual int initialize_wall_law_komega(DoubleTab &)
int calculer_local(double, double, DoubleTab &, double, double, int, int)
static constexpr double BETA_K
int init_lois_paroi() override
void calculer_moyennes_parois(double &, double &, double &, double &, double &, double &)
virtual double calculer_u_star(double &, double &, double &)
int calculer_sous_couche_tampon(DoubleTab &, double, double, int, int)
int compute_law_komega(DoubleTab &)
void imprimer_ustar(Sortie &) const override
int compute_viscous_layer(DoubleTab &field_komega, double dist_y, double viscosity, int elem)
virtual int preparer_calcul_hyd(DoubleTab &)
static constexpr double BETA1
void check_turbulence_model()
Returns an integer value depending on the turbulence model.
int calculer_sous_couche_visq(DoubleTab &, double, int, double, int)
int calculer_hyd_BiK(DoubleTab &, DoubleTab &) override
void modifs_valeurs_turb(int, int, double, double, double, double, DoubleTab &, DoubleTab &)
virtual int init_lois_paroi_hydraulique()
void calculer_uplus_dplus(DoubleVect &, DoubleVect &, DoubleVect &, int, double, double, double)
void set_param(Param &param) const override
int calculer_u_star_sous_couche_tampon(double &, double, double, double, int)
int compute_log_layer(DoubleTab &, double, int, int)
int calculer_sous_couche_log(DoubleTab &, double, int, int)
int compute_layer_selection(double, double, DoubleTab &, double, double, int, int)
int calculer_hyd(DoubleTab &) override
static void mp_sum_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
Definition Process.cpp:193
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
Classe de base des flux de sortie.
Definition Sortie.h:52
int nb_dim() const
Definition TRUSTTab.h:199
int line_size() const
Definition TRUSTVect.tpp:67
_TYPE_ local_min_vect(Mp_vect_options opt=VECT_REAL_ITEMS) const
Definition TRUSTVect.h:155
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
const DoubleVect & tab_d_plus() const
const DoubleVect & tab_u_star() const
void ouvrir_fichier_partage(EcrFicPartage &, const Nom &) const
Ouverture/creation d'un fichier d'impression de Face, uplus_, dplus_, tab_u_star, Cisaillement_paroi_...