TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Turbulence_paroi_base.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_base.h>
17#include <Turbulence_paroi_base.h>
18#include <Discretisation_base.h>
19#include <Schema_Temps_base.h>
20#include <Probleme_base.h>
21#include <Equation_base.h>
22#include <EcrFicPartage.h>
23#include <SFichier.h>
24#include <Front_VF.h>
25#include <Param.h>
26#include <Noms.h>
27#include <Dirichlet_paroi_defilante.h>
28#include <Dirichlet_paroi_fixe.h>
29
30
31Implemente_base(Turbulence_paroi_base, "Turbulence_paroi_base", Objet_U);
32// XD turbulence_paroi_base objet_u turbulence_paroi_base INHERITS_BRACE Basic class for wall laws for Navier-Stokes
33// XD_CONT equations.
34
35// XD negligeable turbulence_paroi_base negligeable NO_BRACE Keyword to suppress the calculation of a law of the wall
36// XD_CONT with a turbulence model. The wall stress is directly calculated with the derivative of the velocity, in the
37// XD_CONT direction perpendicular to the wall (tau_tan /rho= nu dU/dy). NL2 Warning: This keyword is not available for
38// XD_CONT k-epsilon models. In that case you must choose a wall law.
39// XD negligeable_scalaire turbulence_paroi_scalaire_base negligeable_scalaire NO_BRACE Keyword to suppress the
40// XD_CONT calculation of a law of the wall with a turbulence model for thermohydraulic problems. The wall stress is
41// XD_CONT directly calculated with the derivative of the velocity, in the direction perpendicular to the wall.
42
44{
45 return s << que_suis_je() << " " << le_nom();
46}
47
49{
50 return is;
51}
52
53/*! @brief Lit les caracteristques de la loi de parois a partir d'un flot d'entree.
54 *
55 * Format:
56 * type_de_loi_de_paroi
57 * Les valeurs possibles du type de loi de paroi sont:
58 * - "loi_standard_hydr"
59 * - "negligeable"
60 * - "loi_VanDriest"
61 *
62 */
64{
65 Cerr << "Lecture du type de loi de parois " << finl;
66 Motcle typ;
67 s >> typ;
68
69 const Equation_base& eqn = mod_turb_hyd.equation();
70 if (typ == "loi_standard_hydr_scalaire" || typ == "loi_paroi_2_couches_scalaire" || typ == "negligeable_scal")
71 {
72 Cerr << "Le format du jeu de donnees a change:" << finl;
73 Cerr << "Chaque modele de turbulence doit avoir sa loi de paroi specifiee." << finl;
74 Cerr << "Ainsi par exemple, loi_standard_hydr sera pour le modele de turbulence de l'equation de qdm" << finl;
75 Cerr << "et loi_standard_hydr_scalaire pour le modele de turbulence de l'equation d'energie." << typ << finl;
77 }
78 typ += "_";
79
80 Nom discr = eqn.discretisation().que_suis_je();
81
82 // les operateurs de diffusion sont communs aux discretisations VEF et VEFP1B
83 if (discr == "VEFPreP1B") discr = "VEF";
84 typ += discr;
85
86 Cerr << "et typage : " << typ << finl;
87 loi_par.typer(typ);
88 loi_par->associer_modele(mod_turb_hyd);
89 loi_par->associer(eqn.domaine_dis(), eqn.domaine_Cl_dis());
90}
91
93{
94 if (motlu == "u_star" && !champ_u_star_)
95 {
96 int nb_comp = 1;
97 Noms noms(1);
98 noms[0] = "u_star";
99 Noms unites(1);
100 unites[0] = "m2/s2";
101 double temps = 0.;
102 const Equation_base& equation = mon_modele_turb_hyd->equation();
103 const Discretisation_base& discr = equation.probleme().discretisation();
104 discr.discretiser_champ("champ_face", equation.domaine_dis(), scalaire, noms, unites, nb_comp, temps, champ_u_star_);
105 champs_compris_.ajoute_champ(champ_u_star_);
106 }
107}
108
109bool Turbulence_paroi_base::has_champ(const Motcle& nom, OBS_PTR(Champ_base)& ref_champ) const
110{
111 if (champ_u_star_ && (nom == champ_u_star_->le_nom()))
112 {
113 ref_champ = Turbulence_paroi_base::get_champ(nom);
114 return true;
115 }
116 else
117 return champs_compris_.has_champ(nom, ref_champ);
118}
119
121{
122 if (champ_u_star_ && (nom == champ_u_star_->le_nom()))
123 return true;
124 else
125 return champs_compris_.has_champ(nom);
126}
127
129{
130 if (champ_u_star_ && nom == champ_u_star_->le_nom())
131 {
132 // Initialisation a 0 du champ volumique u_star
133 DoubleTab& valeurs = champ_u_star_->valeurs();
134 valeurs = 0;
135 const Equation_base& my_eqn = mon_modele_turb_hyd->equation();
136 if (tab_u_star_.size_array() > 0)
137 {
138 // Boucle sur les frontieres pour recuperer u_star si tab_u_star dimensionne
139 int nb_front = my_eqn.domaine_dis().nb_front_Cl();
140 for (int n_bord = 0; n_bord < nb_front; n_bord++)
141 {
142 const Cond_lim& la_cl = my_eqn.domaine_Cl_dis().les_conditions_limites(n_bord);
143 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
144 int ndeb = le_bord.num_premiere_face();
145 int nfin = ndeb + le_bord.nb_faces();
146 for (int num_face = ndeb; num_face < nfin; num_face++)
147 valeurs(num_face) = tab_u_star_(num_face);
148 }
149 }
150 valeurs.echange_espace_virtuel();
151 // Met a jour le temps du champ:
152 champ_u_star_->mettre_a_jour(my_eqn.schema_temps().temps_courant());
153 return champs_compris_.get_champ(nom);
154 }
155 else
156 return champs_compris_.get_champ(nom);
157}
158
160{
161 Noms noms_compris = champs_compris_.liste_noms_compris();
162 noms_compris.add("u_star");
163 if (opt == DESCRIPTION)
164 Cerr << que_suis_je() << " : " << noms_compris << finl;
165 else
166 nom.add(noms_compris);
167}
168
169/*! @brief Ouverture/creation d'un fichier d'impression de Face, uplus_, dplus_, tab_u_star, Cisaillement_paroi_
170 *
171 */
173{
174
175 const Probleme_base& pb = mon_modele_turb_hyd->equation().probleme();
176 const Schema_Temps_base& sch = pb.schema_temps();
177
178 Nom fichier = Objet_U::nom_du_cas() + "_" + pb.le_nom() + "_" + extension + ".face";
179
180 // On cree le fichier au premier pas de temps si il n'y a pas reprise
181 if (nb_impr_ == 0 && !pb.reprise_effectuee())
182 {
183 Ustar.ouvrir(fichier);
184 }
185 // Sinon on l'ouvre
186 else
187 {
188 Ustar.ouvrir(fichier, ios::app);
189 }
190
191 if (je_suis_maitre())
192 {
193 EcrFicPartage& fic = Ustar;
194 fic << "Temps : " << sch.temps_courant();
195 }
196
197 nb_impr_++;
198}
199
200/*! @brief Ouverture/creation d'un fichier d'impression de moyennes de uplus_, dplus_, tab_u_star
201 *
202 */
203void Turbulence_paroi_base::ouvrir_fichier_partage(EcrFicPartage& fichier, const Nom& nom_fichier, const Nom& extension) const
204{
205 const Probleme_base& pb = mon_modele_turb_hyd->equation().probleme();
206 Nom nom_fic = nom_fichier + "." + extension;
207
208 // On cree le fichier nom_fichier au premier pas de temps si il n'y a pas reprise
209 if (nb_impr0_ == 0 && !pb.reprise_effectuee())
210 {
211 fichier.ouvrir(nom_fic);
212 }
213 // Sinon on l'ouvre
214 else
215 {
216 fichier.ouvrir(nom_fic, ios::app);
217 }
218 nb_impr0_++;
219}
220
221/**
222 * @brief Writes header line for u* (friction velocity) statistics file
223 *
224 * @param boundaries_ Flag to control boundary selection (0: all boundaries, 1: specified boundaries)
225 * @param boundaries_list List of boundary names to process
226 * @param nom_fichier_ Output filename
227 *
228 * @details Creates header line with column names for u* and d+ statistics.
229 * Format: "Time Mean(u*) Mean(d+) [boundary1(u*) boundary1(d+) ...]"
230 * Writes warning messages if specified boundaries are not of correct wall type
231 * (Dirichlet_paroi_fixe or Dirichlet_paroi_defilante).
232 */
233void Turbulence_paroi_base::imprimer_premiere_ligne_ustar(int boundaries_, const LIST(Nom) &boundaries_list, const Nom& nom_fichier_) const
234{
235 EcrFicPartage fichier;
236 ouvrir_fichier_partage(fichier, nom_fichier_, "out");
237 Nom ligne, err;
238 err = "";
239 ligne = "# Time \tMean(u*) \tMean(d+)";
240
241 for (int n_bord = 0; n_bord < le_dom_dis_->nb_front_Cl(); n_bord++)
242 {
243 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
244 const Nom& nom_bord = la_cl->frontiere_dis().le_nom();
245 if (je_suis_maitre() && (boundaries_list.contient(nom_bord) || boundaries_list.size() == 0))
246 {
247 if ( sub_type(Dirichlet_paroi_fixe,la_cl.valeur()) || sub_type(Dirichlet_paroi_defilante, la_cl.valeur()))
248 {
249 ligne += " \t";
250 ligne += nom_bord;
251 ligne += "(u*)";
252 ligne += " \t";
253 ligne += nom_bord;
254 ligne += "(d+)";
255 }
256 else if (boundaries_list.size() > 0)
257 {
258 err += "The boundary named '";
259 err += nom_bord;
260 err += "' is not of type Dirichlet_paroi_fixe or Dirichlet_paroi_defilante.\n";
261 err += "So TRUST will not write his u_star and d_plus means.\n\n";
262 }
263 }
264 }
265 if (je_suis_maitre())
266 {
267 fichier << err;
268 fichier << ligne;
269 fichier << finl;
270 }
271 fichier.syncfile();
272}
273
274/**
275 * @brief Prints mean friction velocity (u*) statistics to a file for specified boundaries
276 *
277 * @param os Output stream for messages
278 * @param boundaries_ Flag to control boundary selection (0: all boundaries, 1: specified boundaries)
279 * @param boundaries_list List of boundary names to process when boundaries_=1
280 * @param nom_fichier_ Output filename
281 *
282 * @details Calculates and writes average u* (friction velocity) and d+ values for wall boundaries.
283 * Results are written for all boundaries combined and then for each boundary separately.
284 * Only processes fixed walls (Dirichlet_paroi_fixe) and moving walls (Dirichlet_paroi_defilante).
285 * Output format: time mean_u* mean_d+ [boundary1_u* boundary1_d+ boundary2_u* boundary2_d+ ...]
286 */
287void Turbulence_paroi_base::imprimer_ustar_mean_only(Sortie& os, int boundaries_, const LIST(Nom) &boundaries_list, const Nom& nom_fichier_) const
288{
289 const Probleme_base& pb = mon_modele_turb_hyd->equation().probleme();
290 const Schema_Temps_base& sch = pb.schema_temps();
291 int ndeb, nfin, size0, num_bord;
292 num_bord = 0;
293
294 if (boundaries_list.size() != 0)
295 {
296 size0 = boundaries_list.size();
297 }
298 else
299 {
300 size0 = le_dom_dis_->nb_front_Cl();
301 }
302 DoubleTrav moy_bords(size0 + 1, 3);
303 moy_bords = 0.;
304
305 EcrFicPartage fichier;
306 ouvrir_fichier_partage(fichier, nom_fichier_, "out");
307
308 for (int n_bord = 0; n_bord < le_dom_dis_->nb_front_Cl(); n_bord++)
309 {
310 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
311 if ((sub_type(Dirichlet_paroi_fixe, la_cl.valeur())) || (sub_type(Dirichlet_paroi_defilante, la_cl.valeur())))
312 {
313 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
314 ndeb = le_bord.num_premiere_face();
315 nfin = ndeb + le_bord.nb_faces();
316 if (boundaries_ == 0 || (boundaries_ == 1 && boundaries_list.contient(le_bord.le_nom())))
317 {
318 for (int num_face = ndeb; num_face < nfin; num_face++)
319 {
320 // surface-averaged values:
321 double aire = le_dom_dis_->face_surfaces(num_face);
322 moy_bords(0, 0) += aire * tab_u_star(num_face);
323 moy_bords(0, 1) += aire;
324 moy_bords(0, 2) += aire * tab_d_plus(num_face);
325 moy_bords(num_bord + 1, 0) += aire * tab_u_star(num_face);
326 moy_bords(num_bord + 1, 1) += aire;
327 moy_bords(num_bord + 1, 2) += aire * tab_d_plus(num_face);
328 }
329 num_bord += 1;
330 }
331 }
332 }
333 mp_sum_for_each_item(moy_bords);
334
335// affichages des lignes dans le fichier
336 if (je_suis_maitre() && moy_bords(0, 1) != 0)
337 {
338 fichier << sch.temps_courant() << " \t" << moy_bords(0, 0) / moy_bords(0, 1) << " \t" << moy_bords(0, 2) / moy_bords(0, 1);
339 }
340
341 num_bord = 0;
342 for (int n_bord = 0; n_bord < le_dom_dis_->nb_front_Cl(); n_bord++)
343 {
344 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
345 if ((sub_type(Dirichlet_paroi_fixe, la_cl.valeur())) || (sub_type(Dirichlet_paroi_defilante, la_cl.valeur())))
346 {
347 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
348 if (boundaries_ == 0 || (boundaries_ == 1 && boundaries_list.contient(le_bord.le_nom())))
349 {
350 if (je_suis_maitre())
351 {
352 fichier << " \t" << moy_bords(num_bord + 1, 0) / moy_bords(num_bord + 1, 1) << " \t" << moy_bords(num_bord + 1, 2) / moy_bords(num_bord + 1, 1);
353 }
354 num_bord += 1;
355 }
356 }
357 }
358
359 if (je_suis_maitre())
360 fichier << finl;
361 fichier.syncfile();
362}
363
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
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.
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
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
int nb_front_Cl() const
int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out) override
Ouvre le fichier avec les parametres mode et prot donnes Ces parametres sont les parametres de la met...
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....
const Discretisation_base & discretisation() const
Renvoie la discretisation associee a l'equation.
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limite discretisee associee a l'equation.
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise associe a l'equation.
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.
Classe Modele_turbulence_hyd_base Cette classe sert de base a la hierarchie des classes.
Equation_base & equation()
Renvoie l'equation associee au modele de turbulence.
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
bool contient(const Nom &nom) const
Definition Nom.h:86
const Nom & le_nom() const override
Renvoie *this;.
Definition Nom.cpp:563
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
classe Objet_U Cette classe est la classe de base des Objets de TRUST
Definition Objet_U.h:73
friend class Entree
Definition Objet_U.h:76
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
static const Nom & nom_du_cas()
Renvoie une reference constante vers le nom du cas.
Definition Objet_U.cpp:146
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
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Probleme_U.h:109
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.
bool & reprise_effectuee()
const Schema_Temps_base & schema_temps() const
Renvoie le schema en temps associe au probleme.
virtual const Equation_base & equation(int) const =0
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
class Schema_Temps_base
double temps_courant() const
Renvoie le temps courant.
Classe de base des flux de sortie.
Definition Sortie.h:52
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
Classe Turbulence_paroi_base Classe de base pour la hierarchie des classes representant les modeles.
virtual void imprimer_premiere_ligne_ustar(int, const LIST(Nom)&, const Nom &) const
Writes header line for u* (friction velocity) statistics file.
const DoubleVect & tab_d_plus() const
const DoubleVect & tab_u_star() const
virtual void imprimer_ustar_mean_only(Sortie &, int, const LIST(Nom)&, const Nom &) const
Prints mean friction velocity (u*) statistics to a file for specified boundaries.
void ouvrir_fichier_partage(EcrFicPartage &, const Nom &) const
Ouverture/creation d'un fichier d'impression de Face, uplus_, dplus_, tab_u_star, Cisaillement_paroi_...
const Champ_base & get_champ(const Motcle &nom) const override
void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const override
bool has_champ(const Motcle &nom, OBS_PTR(Champ_base) &ref_champ) const override
OWN_PTR(Champ_Fonc_base) champ_u_star_
void creer_champ(const Motcle &motlu) override
virtual void associer(const Domaine_dis_base &, const Domaine_Cl_dis_base &)=0
void associer_modele(const Modele_turbulence_hyd_base &)
Associe un modele de turbulence a l'objet.
static void typer_lire_turbulence_paroi(OWN_PTR(Turbulence_paroi_base)&, const Modele_turbulence_hyd_base &, Entree &)
Lit les caracteristques de la loi de parois a partir d'un flot d'entree.