TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Modele_turbulence_hyd_Longueur_Melange_VEF.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 <Modele_turbulence_hyd_Longueur_Melange_VEF.h>
17#include <EcritureLectureSpecial.h>
18#include <VEF_discretisation.h>
19#include <Champ_Uniforme.h>
20#include <Postraitement.h>
21#include <LecFicDiffuse.h>
22#include <Fluide_base.h>
23#include <Champ_P1NC.h>
24#include <Motcle.h>
25#include <Debog.h>
26#include <Param.h>
27
28Implemente_instanciable(Modele_turbulence_hyd_Longueur_Melange_VEF, "Modele_turbulence_hyd_Longueur_Melange_VEF", Modele_turbulence_hyd_Longueur_Melange_base);
29// XD longueur_melange mod_turb_hyd_ss_maille longueur_melange INHERITS_BRACE This model is based on mixing length
30// XD_CONT modelling. For a non academic configuration, formulation used in the code can be expressed basically as : NL2
31// XD_CONT $nu_t=(Kappa.y)^2$.dU/dy NL2 Till a maximum distance (dmax) set by the user in the data file, y is set equal
32// XD_CONT to the distance from the wall (dist_w) calculated previously and saved in file Wall_length.xyz. [see
33// XD_CONT Distance_paroi keyword] NL2 Then (from y=dmax), y decreases as an exponential function :
34// XD_CONT y=dmax*exp[-2.*(dist_w-dmax)/dmax]
35// XD attr canalx floattant canalx OPT [height] : plane channel according to Ox direction (for the moment, formulation
36// XD_CONT in the code relies on fixed heigh : H=2).
37// XD attr tuyauz floattant tuyauz OPT [diameter] : pipe according to Oz direction (for the moment, formulation in the
38// XD_CONT code relies on fixed diameter : D=2).
39// XD attr dmax floattant dmax OPT Maximum distance.
40// XD attr fichier chaine fichier OPT not_set
41// XD attr fichier_ecriture_K_Eps chaine fichier_ecriture_K_Eps OPT When a resume with k-epsilon model is envisaged,
42// XD_CONT this keyword allows to generate external MED-format file with evaluation of k and epsilon quantities (based
43// XD_CONT on eddy turbulent viscosity and turbulent characteristic length returned by mixing length model). The
44// XD_CONT frequency of the MED file print is set equal to dt_impr_ustar. Moreover, k-eps MED field is automatically
45// XD_CONT saved at the last time step. MED file is then used for resuming a K-Epsilon calculation with the
46// XD_CONT Champ_Fonc_Med keyword.
48{
49 return s << que_suis_je() << " " << le_nom();
50}
51
53{
54 Param param(que_suis_je());
55 set_param(param);
56 param.lire_avec_accolades_depuis(is);
57 const LIST(Nom) &params_lu = param.get_list_mots_lus();
58 if (params_lu.contient(Motcle("canalx")))
59 cas_ = 1;
60 else if (params_lu.contient(Motcle("tuyauz")))
61 cas_ = 2;
62 else if (params_lu.contient(Motcle("tuyaux")))
63 cas_ = 21;
64 else if (params_lu.contient(Motcle("tuyauy")))
65 cas_ = 22;
66 else if ((params_lu.contient(Motcle("dmax"))) || (params_lu.contient(Motcle("fichier"))))
67 cas_ = 4;
68 else
69 {
70 Cerr << " Error while reading the Longueur_Melange turbulence model. " << finl;
71 Cerr << " Case not selected, choose among : canalx tuyauz dmax fichier " << finl;
72 Cerr << " Please refer to the reference manual for a detailed documentation. " << finl;
73 exit();
74 }
75
76 return is;
77}
78
80{
82 param.ajouter("canalx", &hauteur_);
83 param.ajouter_condition("value_of_canalx_eq_2", " canalx has been coded presently only for h=2.");
84 param.ajouter("tuyauz", &diametre_);
85 param.ajouter("tuyaux", &diametre_);
86 param.ajouter("tuyauy", &diametre_);
87 param.ajouter_condition("value_of_tuyauz_eq_2", " tuyauz has been coded presently only for d=2.");
88 param.ajouter_condition("value_of_tuyaux_eq_2", " tuyaux has been coded presently only for d=2.");
89 param.ajouter_condition("value_of_tuyauy_eq_2", " tuyauy has been coded presently only for d=2.");
90 param.ajouter("dmax", &dmax_);
91 param.ajouter("fichier", &nom_fic_);
92}
93
98
100{
101 const double Kappa = 0.415;
102 double Cmu = CMU;
103
104 double temps = mon_equation_->inconnue().temps();
105 const Domaine_VEF& domaine_VEF = ref_cast(Domaine_VEF, le_dom_VF_.valeur());
106 DoubleTab& visco_turb = la_viscosite_turbulente_->valeurs();
107 DoubleVect& k = energie_cinetique_turb_->valeurs();
108 const int nb_elem = domaine_VEF.nb_elem();
109 const int nb_elem_tot = domaine_VEF.nb_elem_tot();
110 const DoubleTab& xp = domaine_VEF.xp();
111
112 Sij2_.resize(nb_elem_tot);
113
115
116 if (visco_turb.size() != nb_elem)
117 {
118 Cerr << "Size error for the array containing the values of the turbulent viscosity." << finl;
119 exit();
120 }
121
122 Debog::verifier("Modele_turbulence_hyd_Longueur_Melange_VEF::calculer_viscosite_turbulente visco_turb 0", visco_turb);
123
124 if (k.size() != nb_elem)
125 {
126 Cerr << "Size error for the array containing the values of the turbulent kinetic energy." << finl;
127 exit();
128 }
129
130 // CANAL PLAN suivant (Ox - h=2) **********************************
131 if (cas_ == 1)
132 {
133 for (int elem = 0; elem < nb_elem; elem++)
134 {
135 double y = xp(elem, 1);
136 if (y > 1.)
137 y = 2. - y;
138
139 visco_turb(elem) = Kappa * Kappa * y * y * (1. - y) * sqrt(2. * Sij2_[elem]);
140 k(elem) = pow(visco_turb(elem) / (Cmu * y), 2);
141 }
142 }
143 else
144 // CYLINDRE suivant (D=2) ************************************
145
146 if ((cas_ == 2) || (cas_ == 21) || (cas_ == 22))
147 {
148 int dir1;
149 int dir2;
150
151 if (cas_ == 2)
152 {
153 dir1 = 0; //Tuyau suivant z
154 dir2 = 1;
155 }
156 else if (cas_ == 21)
157 {
158 dir1 = 1; //Tuyau suivant x
159 dir2 = 2;
160 }
161 else
162 {
163 dir1 = 0; //Tuyau suivant y
164 dir2 = 2;
165 }
166
167 for (int elem = 0; elem < nb_elem; elem++)
168 {
169 double x = xp(elem, dir1);
170 double y = xp(elem, dir2);
171 double r = sqrt(x * x + y * y);
172
173 visco_turb(elem) = Kappa * Kappa * (1. - r) * (1. - r) * (1. - r) * sqrt(2. * Sij2_[elem]);
174 k(elem) = pow(visco_turb(elem) / (Cmu * (1. - r)), 2);
175 }
176 }
177 // CAS NON TYPE ***************************************************
178 else if (cas_ == 4)
179 {
181
182 const DoubleTab& wall_length = wall_length_->valeurs();
183
184 for (int elem = 0; elem < nb_elem; elem++)
185 {
186 double f_vd = f_amortissement_(elem);
187 double wl = wall_length(elem);
188 double lm = (wl <= dmax_) ? wl : dmax_ * exp(-2. * (wl - dmax_) / dmax_);
189
190 visco_turb(elem) = pow(f_vd * f_vd * Kappa * lm, 2) * sqrt(2. * Sij2_[elem]);
191 k(elem) = pow(visco_turb(elem) / (Cmu * lm), 2);
192 }
193 }
194 else
195 {
196 Cerr << cas_ << " non prevu " << que_suis_je() << finl;
197 Cerr << que_suis_je() << " Case " << cas_ << " not known." << finl;
198 exit();
199 }
200
201 Debog::verifier("Modele_turbulence_hyd_Longueur_Melange_VEF::calculer_viscosite_turbulente visco_turb 1", visco_turb);
202
203 la_viscosite_turbulente_->changer_temps(temps);
204
205 wall_length_->changer_temps(temps);
206 return la_viscosite_turbulente_;
207}
208
210{
211 const DoubleTab& la_vitesse = mon_equation_->inconnue().valeurs();
212 const Champ_P1NC& ch = ref_cast(Champ_P1NC, mon_equation_->inconnue());
213 const Domaine_Cl_VEF& domaine_Cl_VEF = ref_cast(Domaine_Cl_VEF, le_dom_Cl_.valeur());
214 const Domaine_VEF& domaine_VEF = ref_cast(Domaine_VEF, le_dom_VF_.valeur());
215 const int nb_elem = domaine_VEF.nb_elem_tot();
216
217 DoubleTab duidxj(nb_elem, dimension, dimension);
218 int i, j;
219 double Sij;
220
221 Sij2_ = 0.;
222
223 DoubleTab ubar(la_vitesse);
224 // ch.filtrer_L2(ubar); // Patrick : on travaille sur le champ filtre.
225
226 ch.calcul_gradient(ubar, duidxj, domaine_Cl_VEF);
227
228 for (int elem = 0; elem < nb_elem; elem++)
229 {
230 for (i = 0; i < dimension; i++)
231 for (j = 0; j < dimension; j++)
232 {
233 //Deplacement du calcul de Sij
234 Sij = 0.5 * (duidxj(elem, i, j) + duidxj(elem, j, i));
235 Sij2_(elem) += Sij * Sij;
236 }
237 }
238}
239
241{
242
243 // PQ : 25/02/04 recuperation de la distance a la paroi dans Wall_length.xyz
244
245 const Domaine_VEF& domaine_VEF = ref_cast(Domaine_VEF, le_dom_VF_.valeur());
246 DoubleTab& wall_length = wall_length_->valeurs();
247 wall_length = -1.;
248
249 LecFicDiffuse fic;
250 fic.set_bin(1);
251 if (!fic.ouvrir(nom_fic_))
252 {
253 Cerr << " File " << nom_fic_ << " doesn't exist. To generate it, please, refer to html.doc (Distance_paroi) " << finl;
254 exit();
255 }
256
257 Noms nom_paroi;
258
259 fic >> nom_paroi;
260
261 if (je_suis_maitre())
262 {
263
264 Cerr << "Recall : " << nom_fic_ << " obtained from boundaries nammed : " << finl;
265 for (int b = 0; b < nom_paroi.size(); b++)
266 {
267 Cerr << nom_paroi[b] << finl;
268 //test pour s'assurer de la coherence de Wall_length.xyz avec le jeu de donnees :
269 domaine_VEF.rang_frontiere(nom_paroi[b]);
270 }
271 }
272 EcritureLectureSpecial::lecture_special(domaine_VEF, fic, wall_length);
273}
274
276{
277 const double Kappa = 0.415;
278 const double A_plus = 26.;
279
280 // PQ : 23/02/04 calcul de la fonction d'amortissement de Van Driest
281 // a partir de la distance a la paroi et d'une approximation
282 // du frottement
283
284 // la fonction d'amortissement f_vd = 1 - exp(-y+/A+) intervient dans le calcul de nu_t
285 // la puissance 4 (calibrage issu d'un canal plan donnant les "meilleurs" resultats).
286 //
287 // on restreint le calcul de f_vd qu'aux valeurs de y+ t.q. : f_vd^4 < 0.99
288 // soit : y+ < -A+. ln(1-0.99^(1/4)) = 155
289 // soit, encore d'apres la loi de Reichard u+ < 17.96
290 // d'ou :
291 // f_vd^4 < 0.99 => u+.y+ < 2784
292 //
293
294 const Domaine_VEF& domaine_VEF = ref_cast(Domaine_VEF, le_dom_VF_.valeur());
295 const int nb_elem = domaine_VEF.nb_elem();
296 DoubleTab& wall_length = wall_length_->valeurs();
297 int nb_face_elem = domaine_VEF.domaine().nb_faces_elem();
298 const IntTab& elem_faces = domaine_VEF.elem_faces();
299
300 const Fluide_base& le_fluide = ref_cast(Fluide_base, mon_equation_->milieu());
301 const Champ_Don_base& ch_visco_cin = le_fluide.viscosite_cinematique();
302 const DoubleTab& tab_visco = ch_visco_cin.valeurs();
303 const DoubleTab& vit = mon_equation_->inconnue().valeurs();
304
305 f_amortissement_.resize(nb_elem);
306 f_amortissement_ = 1.;
307
308 ArrOfDouble vc(dimension);
309 double dist, d_visco, norm_v, u_plus_d_plus, dp, up1, up2, r, y_plus;
310 int iter;
311 const int itmax = 25;
312 double seuil = 0.001;
313
314 double visco = -1;
315 int l_unif;
316
317 if (sub_type(Champ_Uniforme, ch_visco_cin))
318 {
319 visco = std::max(tab_visco(0, 0), DMINFLOAT);
320 l_unif = 1;
321 }
322 else
323 l_unif = 0;
324
325 if ((!l_unif) && (tab_visco.local_min_vect() < DMINFLOAT))
326 // on ne doit pas changer tab_visco ici !
327 {
328 Cerr << "In Modele_turbulence_hyd_Longueur_Melange_VEF::calculer_f_amortissement : visco = " << tab_visco.local_min_vect() << " <= 0 ? " << finl;
329 exit();
330 }
331 //tab_visco+=DMINFLOAT;
332
333 for (int elem = 0; elem < nb_elem; elem++)
334 {
335 vc = 0.;
336 dist = wall_length(elem);
337
338 if (l_unif)
339 d_visco = visco;
340 else
341 d_visco = tab_visco[elem];
342
343 for (int i = 0; i < nb_face_elem; i++)
344 {
345 int face = elem_faces(elem, i);
346
347 for (int comp = 0; comp < dimension; comp++)
348 vc[comp] += vit(face, comp);
349 }
350
351 vc /= dimension;
352 norm_v = norme_array(vc);
353
354 u_plus_d_plus = norm_v * dist / d_visco;
355
356 if (u_plus_d_plus < 1.) // pour eviter de faire tourner la procedure iterative
357 {
358 y_plus = sqrt(u_plus_d_plus);
359 f_amortissement_(elem) -= exp(-y_plus / A_plus);
360 }
361 else if (u_plus_d_plus < 2784.) // cf. explication plus haut
362 {
363 up1 = u_plus_d_plus / 100.;
364 iter = 0;
365 r = 1.;
366
367 while ((iter++ < itmax) && (r > seuil))
368 {
369 dp = u_plus_d_plus / up1;
370 up2 = ((1 / Kappa) * log(1 + Kappa * dp)) + 7.8 * (1 - exp(-dp / 11.) - exp(-dp / 3.) * dp / 11.); // Equation de Reichardt
371 up1 = 0.5 * (up1 + up2);
372 r = std::fabs(up1 - up2) / up1;
373 }
374 if (iter >= itmax)
375 erreur_non_convergence();
376
377 y_plus = u_plus_d_plus / up1;
378 f_amortissement_(elem) -= exp(-y_plus / A_plus);
379 }
380 }
381}
382
384{
385 // On ne doit pas lire_distance_paroi dans le cas ou on post-traite le champs Distance_paroi
386 // car c'est deja fait dans la classe mere Modele_turbulence_hyd_base
387 bool contient_distance_paroi = false;
388 for (auto &itr : equation().probleme().postraitements())
389 if (!contient_distance_paroi)
390 {
391 if (sub_type(Postraitement, itr.valeur()))
392 {
393 Postraitement& post = ref_cast(Postraitement, itr.valeur());
394 for (int i = 0; i < post.noms_champs_a_post().size(); i++)
395 {
396 if (post.noms_champs_a_post()[i].contient("DISTANCE_PAROI"))
397 {
398 contient_distance_paroi = true;
399 break;
400 }
401 }
402 }
403 }
404 if (!contient_distance_paroi && cas_ == 4)
407 mettre_a_jour(0.);
408
409 return 1;
410}
classe Champ_Don_base classe de base des Champs donnes (non calcules)
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
classe Champ_Fonc_base Classe de base des champs qui sont fonction d'une grandeur calculee
static DoubleTab & calcul_gradient(const DoubleTab &, DoubleTab &, const Domaine_Cl_VEF &)
classe Champ_Uniforme Represente un champ constant dans l'espace et dans le temps.
double temps() const
Renvoie le temps du champ.
static void verifier(const char *const msg, double)
Definition Debog.cpp:21
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
class Domaine_VEF
Definition Domaine_VEF.h:54
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
double xp(int num_elem, int k) const
Definition Domaine_VF.h:77
int nb_elem_tot() const
int rang_frontiere(const Nom &)
const Domaine & domaine() const
static void lecture_special(Champ_base &ch, Entree &fich)
simple appel a EcritureLectureSpecial::lecture_special (const Domaine_VF& zvf,Entree& fich,...
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
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
Cette classe implemente les operateurs et les methodes virtuelles de la classe EFichier de la facon s...
int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::in) override
Ouverture du fichier.
void set_bin(bool bin) override
appelle get_entree_master().
classe Turbulence_hyd_Longueur_Melange_VEF Cette classe correspond a la mise en oeuvre du modele de l...
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
Classe Modele_turbulence_hyd_Longueur_Melange_base Classe representant le modele de turbulence Longue...
LIST(Nom) boundaries_list_
virtual int preparer_calcul()
Prepare le calcul.
Equation_base & equation()
Renvoie l'equation associee au modele de turbulence.
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
virtual void set_param(Param &) const
Definition Objet_U.h:135
virtual int lire_motcle_non_standard(const Motcle &motlu, Entree &is)
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
Definition Objet_U.cpp:115
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
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter_condition(const char *condition, const char *message, const char *name=0)
Declare a post-read logical condition that must hold on the parameter values.
Definition Param.cpp:496
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
classe Postraitement La classe est dotee -d une liste de champs generiques champs_post_complet_ qui c...
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
_SIZE_ size() const
Definition TRUSTVect.tpp:45
_TYPE_ local_min_vect(Mp_vect_options opt=VECT_REAL_ITEMS) const
Definition TRUSTVect.h:155