TrioCFD 1.9.9_beta
TrioCFD documentation
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 Reads the characteristics of the wall law from an input stream.
54 *
55 * Format:
56 * type_de_loi_de_paroi
57 * Possible values for the wall law type:
58 * - "loi_standard_hydr"
59 * - "negligeable"
60 * - "loi_VanDriest"
61 *
62 * @param loi_par Wall law object to type and initialize.
63 * @param mod_turb_hyd Reference to the hydraulic turbulence model.
64 * @param s Input stream.
65 */
67{
68 Cerr << "Reading the wall law type " << finl;
69 Motcle typ;
70 s >> typ;
71
72 const Equation_base& eqn = mod_turb_hyd.equation();
73 if (typ == "loi_standard_hydr_scalaire" || typ == "loi_paroi_2_couches_scalaire" || typ == "negligeable_scal")
74 {
75 Cerr << "The data file format has changed:" << finl;
76 Cerr << "Each turbulence model must have its wall law specified." << finl;
77 Cerr << "For example, loi_standard_hydr is for the turbulence model of the momentum equation" << finl;
78 Cerr << "and loi_standard_hydr_scalaire for the turbulence model of the energy equation." << typ << finl;
80 }
81 typ += "_";
82
83 Nom discr = eqn.discretisation().que_suis_je();
84
85 // diffusion operators are shared by VEF and VEFP1B discretisations
86 if (discr == "VEFPreP1B") discr = "VEF";
87 typ += discr;
88
89 Cerr << "and typing: " << typ << finl;
90 loi_par.typer(typ);
91 loi_par->associer_modele(mod_turb_hyd);
92 loi_par->associer(eqn.domaine_dis(), eqn.domaine_Cl_dis());
93}
94
96{
97 if (motlu == "u_star" && !champ_u_star_)
98 {
99 int nb_comp = 1;
100 Noms noms(1);
101 noms[0] = "u_star";
102 Noms unites(1);
103 unites[0] = "m2/s2";
104 double temps = 0.;
105 const Equation_base& equation = mon_modele_turb_hyd->equation();
106 const Discretisation_base& discr = equation.probleme().discretisation();
107 discr.discretiser_champ("champ_face", equation.domaine_dis(), scalaire, noms, unites, nb_comp, temps, champ_u_star_);
108 champs_compris_.ajoute_champ(champ_u_star_);
109 }
110}
111
112bool Turbulence_paroi_base::has_champ(const Motcle& nom, OBS_PTR(Champ_base)& ref_champ) const
113{
114 if (champ_u_star_ && (nom == champ_u_star_->le_nom()))
115 {
116 ref_champ = Turbulence_paroi_base::get_champ(nom);
117 return true;
118 }
119 else
120 return champs_compris_.has_champ(nom, ref_champ);
121}
122
124{
125 if (champ_u_star_ && (nom == champ_u_star_->le_nom()))
126 return true;
127 else
128 return champs_compris_.has_champ(nom);
129}
130
132{
133 if (champ_u_star_ && nom == champ_u_star_->le_nom())
134 {
135 // Initialise the u_star volumetric field to 0
136 DoubleTab& valeurs = champ_u_star_->valeurs();
137 valeurs = 0;
138 const Equation_base& my_eqn = mon_modele_turb_hyd->equation();
139 if (tab_u_star_.size_array() > 0)
140 {
141 // Loop over boundaries to retrieve u_star if tab_u_star is allocated
142 int nb_front = my_eqn.domaine_dis().nb_front_Cl();
143 for (int n_bord = 0; n_bord < nb_front; n_bord++)
144 {
145 const Cond_lim& la_cl = my_eqn.domaine_Cl_dis().les_conditions_limites(n_bord);
146 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
147 int ndeb = le_bord.num_premiere_face();
148 int nfin = ndeb + le_bord.nb_faces();
149 for (int num_face = ndeb; num_face < nfin; num_face++)
150 valeurs(num_face) = tab_u_star_(num_face);
151 }
152 }
153 valeurs.echange_espace_virtuel();
154 // Update the field time:
155 champ_u_star_->mettre_a_jour(my_eqn.schema_temps().temps_courant());
156 return champs_compris_.get_champ(nom);
157 }
158 else
159 return champs_compris_.get_champ(nom);
160}
161
163{
164 Noms noms_compris = champs_compris_.liste_noms_compris();
165 noms_compris.add("u_star");
166 if (opt == DESCRIPTION)
167 Cerr << que_suis_je() << " : " << noms_compris << finl;
168 else
169 nom.add(noms_compris);
170}
171
172/*! @brief Opens or creates a print file for Face, uplus_, dplus_, tab_u_star, Cisaillement_paroi_.
173 *
174 */
176{
177
178 const Probleme_base& pb = mon_modele_turb_hyd->equation().probleme();
179 const Schema_Temps_base& sch = pb.schema_temps();
180
181 Nom fichier = Objet_U::nom_du_cas() + "_" + pb.le_nom() + "_" + extension + ".face";
182
183 // Create the file at the first time step if no restart
184 if (nb_impr_ == 0 && !pb.reprise_effectuee())
185 {
186 Ustar.ouvrir(fichier);
187 }
188 // Otherwise open in append mode
189 else
190 {
191 Ustar.ouvrir(fichier, ios::app);
192 }
193
194 if (je_suis_maitre())
195 {
196 EcrFicPartage& fic = Ustar;
197 fic << "Temps : " << sch.temps_courant();
198 }
199
200 nb_impr_++;
201}
202
203/*! @brief Opens or creates a file for printing mean values of uplus_, dplus_, tab_u_star.
204 *
205 */
206void Turbulence_paroi_base::ouvrir_fichier_partage(EcrFicPartage& fichier, const Nom& nom_fichier, const Nom& extension) const
207{
208 const Probleme_base& pb = mon_modele_turb_hyd->equation().probleme();
209 Nom nom_fic = nom_fichier + "." + extension;
210
211 // Create the file at the first time step if no restart
212 if (nb_impr0_ == 0 && !pb.reprise_effectuee())
213 {
214 fichier.ouvrir(nom_fic);
215 }
216 // Otherwise open in append mode
217 else
218 {
219 fichier.ouvrir(nom_fic, ios::app);
220 }
221 nb_impr0_++;
222}
223
224/**
225 * @brief Writes header line for u* (friction velocity) statistics file
226 *
227 * @param boundaries_ Flag to control boundary selection (0: all boundaries, 1: specified boundaries)
228 * @param boundaries_list List of boundary names to process
229 * @param nom_fichier_ Output filename
230 *
231 * @details Creates header line with column names for u* and d+ statistics.
232 * Format: "Time Mean(u*) Mean(d+) [boundary1(u*) boundary1(d+) ...]"
233 * Writes warning messages if specified boundaries are not of correct wall type
234 * (Dirichlet_paroi_fixe or Dirichlet_paroi_defilante).
235 */
236void Turbulence_paroi_base::imprimer_premiere_ligne_ustar(int boundaries_, const LIST(Nom) &boundaries_list, const Nom& nom_fichier_) const
237{
238 EcrFicPartage fichier;
239 ouvrir_fichier_partage(fichier, nom_fichier_, "out");
240 Nom ligne, err;
241 err = "";
242 ligne = "# Time \tMean(u*) \tMean(d+)";
243
244 for (int n_bord = 0; n_bord < le_dom_dis_->nb_front_Cl(); n_bord++)
245 {
246 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
247 const Nom& nom_bord = la_cl->frontiere_dis().le_nom();
248 if (je_suis_maitre() && (boundaries_list.contient(nom_bord) || boundaries_list.size() == 0))
249 {
250 if ( sub_type(Dirichlet_paroi_fixe,la_cl.valeur()) || sub_type(Dirichlet_paroi_defilante, la_cl.valeur()))
251 {
252 ligne += " \t";
253 ligne += nom_bord;
254 ligne += "(u*)";
255 ligne += " \t";
256 ligne += nom_bord;
257 ligne += "(d+)";
258 }
259 else if (boundaries_list.size() > 0)
260 {
261 err += "The boundary named '";
262 err += nom_bord;
263 err += "' is not of type Dirichlet_paroi_fixe or Dirichlet_paroi_defilante.\n";
264 err += "So TRUST will not write his u_star and d_plus means.\n\n";
265 }
266 }
267 }
268 if (je_suis_maitre())
269 {
270 fichier << err;
271 fichier << ligne;
272 fichier << finl;
273 }
274 fichier.syncfile();
275}
276
277/**
278 * @brief Prints mean friction velocity (u*) statistics to a file for specified boundaries
279 *
280 * @param os Output stream for messages
281 * @param boundaries_ Flag to control boundary selection (0: all boundaries, 1: specified boundaries)
282 * @param boundaries_list List of boundary names to process when boundaries_=1
283 * @param nom_fichier_ Output filename
284 *
285 * @details Calculates and writes average u* (friction velocity) and d+ values for wall boundaries.
286 * Results are written for all boundaries combined and then for each boundary separately.
287 * Only processes fixed walls (Dirichlet_paroi_fixe) and moving walls (Dirichlet_paroi_defilante).
288 * Output format: time mean_u* mean_d+ [boundary1_u* boundary1_d+ boundary2_u* boundary2_d+ ...]
289 */
290void Turbulence_paroi_base::imprimer_ustar_mean_only(Sortie& os, int boundaries_, const LIST(Nom) &boundaries_list, const Nom& nom_fichier_) const
291{
292 const Probleme_base& pb = mon_modele_turb_hyd->equation().probleme();
293 const Schema_Temps_base& sch = pb.schema_temps();
294 int ndeb, nfin, size0, num_bord;
295 num_bord = 0;
296
297 if (boundaries_list.size() != 0)
298 {
299 size0 = boundaries_list.size();
300 }
301 else
302 {
303 size0 = le_dom_dis_->nb_front_Cl();
304 }
305 DoubleTrav moy_bords(size0 + 1, 3);
306 moy_bords = 0.;
307
308 EcrFicPartage fichier;
309 ouvrir_fichier_partage(fichier, nom_fichier_, "out");
310
311 for (int n_bord = 0; n_bord < le_dom_dis_->nb_front_Cl(); n_bord++)
312 {
313 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
314 if ((sub_type(Dirichlet_paroi_fixe, la_cl.valeur())) || (sub_type(Dirichlet_paroi_defilante, la_cl.valeur())))
315 {
316 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
317 ndeb = le_bord.num_premiere_face();
318 nfin = ndeb + le_bord.nb_faces();
319 if (boundaries_ == 0 || (boundaries_ == 1 && boundaries_list.contient(le_bord.le_nom())))
320 {
321 for (int num_face = ndeb; num_face < nfin; num_face++)
322 {
323 // surface-averaged values:
324 double aire = le_dom_dis_->face_surfaces(num_face);
325 moy_bords(0, 0) += aire * tab_u_star(num_face);
326 moy_bords(0, 1) += aire;
327 moy_bords(0, 2) += aire * tab_d_plus(num_face);
328 moy_bords(num_bord + 1, 0) += aire * tab_u_star(num_face);
329 moy_bords(num_bord + 1, 1) += aire;
330 moy_bords(num_bord + 1, 2) += aire * tab_d_plus(num_face);
331 }
332 num_bord += 1;
333 }
334 }
335 }
336 mp_sum_for_each_item(moy_bords);
337
338// print lines to the file
339 if (je_suis_maitre() && moy_bords(0, 1) != 0)
340 {
341 fichier << sch.temps_courant() << " \t" << moy_bords(0, 0) / moy_bords(0, 1) << " \t" << moy_bords(0, 2) / moy_bords(0, 1);
342 }
343
344 num_bord = 0;
345 for (int n_bord = 0; n_bord < le_dom_dis_->nb_front_Cl(); n_bord++)
346 {
347 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
348 if ((sub_type(Dirichlet_paroi_fixe, la_cl.valeur())) || (sub_type(Dirichlet_paroi_defilante, la_cl.valeur())))
349 {
350 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
351 if (boundaries_ == 0 || (boundaries_ == 1 && boundaries_list.contient(le_bord.le_nom())))
352 {
353 if (je_suis_maitre())
354 {
355 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);
356 }
357 num_bord += 1;
358 }
359 }
360 }
361
362 if (je_suis_maitre())
363 fichier << finl;
364 fichier.syncfile();
365}
366
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
Dirichlet_paroi_defilante Imposes the wall velocity in an equation of type Navier_Stokes.
Dirichlet_paroi_fixe Represents a fixed wall in a Navier-Stokes type equation.
class Discretisation_base This class represents a spatial discretization scheme, which
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
Returns the i-th boundary condition.
int nb_front_Cl() const
int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out) override
Opens the file with the given mode and prot parameters. These parameters are the parameters of the st...
Sortie & syncfile() override
Triggers writing to disk of the data accumulated on the different processors since the last call to s...
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Equation_base The role of an equation is the calculation of one or more fields....
const Discretisation_base & discretisation() const
Returns the discretization associated with the equation.
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Returns the discretized boundary condition domain associated with the equation.
Probleme_base & probleme()
Returns the problem associated with the equation.
Schema_Temps_base & schema_temps()
Returns the time scheme associated with the equation.
Domaine_dis_base & domaine_dis()
Returns the discretized domain associated with the 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
Returns the name of the geometric boundary.
Base class for the turbulence model hierarchy for Navier-Stokes equations.
Equation_base & equation()
Returns the equation associated with the turbulence model.
A character string (Nom) in uppercase.
Definition Motcle.h:26
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
bool contient(const Nom &nom) const
Definition Nom.h:86
const Nom & le_nom() const override
Returns *this.
Definition Nom.cpp:555
An array of character strings (VECT(Nom)).
Definition Noms.h:26
Base class for TRUST objects (Objet_U).
Definition Objet_U.h:68
friend class Entree
Definition Objet_U.h:71
friend class Sortie
Definition Objet_U.h:70
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
static const Nom & nom_du_cas()
Returns a constant reference to the case name. This method is static.
Definition Objet_U.cpp:145
virtual const Nom & le_nom() const
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Definition Objet_U.cpp:317
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Definition Probleme_U.h:109
class Probleme_base It is a Probleme_U that is not a coupling.
const Discretisation_base & discretisation() const
Returns the discretization associated with the problem.
bool & reprise_effectuee()
const Schema_Temps_base & schema_temps() const
Returns the time scheme associated with the problem.
virtual const Equation_base & equation(int) const =0
static void mp_sum_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
Definition Process.cpp:194
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
static int je_suis_maitre()
Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
Definition Process.cpp:82
class Schema_Temps_base
double temps_courant() const
Returns the current time.
Base class for output streams.
Definition Sortie.h:52
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
Base class for the hierarchy of wall-law models computing turbulent quantities near walls....
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
Opens or creates a print file for 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 &)
Associates a turbulence model to the object.
static void typer_lire_turbulence_paroi(OWN_PTR(Turbulence_paroi_base)&, const Modele_turbulence_hyd_base &, Entree &)
Reads the characteristics of the wall law from an input stream.