TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Navier_Stokes_Turbulent.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 <Navier_Stokes_Turbulent.h>
18#include <Op_Diff_Turbulent_base.h>
19#include <Fluide_Incompressible.h>
20#include <Discretisation_base.h>
21#include <Schema_Temps_base.h>
22#include <Champ_Uniforme.h>
23#include <Probleme_base.h>
24#include <Discret_Thyd.h>
25#include <TRUST_2_PDI.h>
26#include <Domaine.h>
27#include <Avanc.h>
28#include <Param.h>
29
30Implemente_instanciable(Navier_Stokes_Turbulent, "Navier_Stokes_Turbulent", Navier_Stokes_std);
31// XD navier_stokes_turbulent navier_stokes_standard navier_stokes_turbulent INHERITS_BRACE Navier-Stokes equations as
32// XD_CONT well as the associated turbulence model equations.
33// XD attr modele_turbulence modele_turbulence_hyd_deriv modele_turbulence OPT Turbulence model for Navier-Stokes
34// XD_CONT equations.
35
37
39
41{
43 param.ajouter_non_std("modele_turbulence", (this), Param::REQUIRED);
44}
45
47{
48 if (mot == "diffusion")
49 {
50 Cerr << "Reading and typing of the diffusion operator : ";
51 terme_diffusif.associer_diffusivite(diffusivite_pour_transport());
53 terme_diffusif.associer_diffusivite_pour_pas_de_temps(diffusivite_pour_pas_de_temps());
54 return 1;
55 }
56 else if (mot == "modele_turbulence")
57 return typer_lire_mod_turb_hyd(is);
58 else
60}
61
62int Navier_Stokes_Turbulent::typer_lire_mod_turb_hyd(Entree& s)
63{
64 Cerr << "Reading and typing of the turbulence model : ";
65
66 Motcle typ;
67 s >> typ;
68 Motcle nom1("Modele_turbulence_hyd_");
69 nom1 += typ;
70 Nom discr = discretisation().que_suis_je();
71
72 if (typ.debute_par("SOUS_MAILLE") || discr == "VDF_Hyper" || typ.debute_par("LONGUEUR_MELANGE") || (typ == "K_Epsilon_V2"))
73 {
74 if (dimension == 2 && discr != "VDF_Hyper")
75 {
76 Cerr << "You are solving a turbulent case in 2D with a subgrid-scale model" << finl;
77 Cerr << "Be careful with the interpretation of the results !!" << finl;
78 }
79
80 nom1 += "_";
81 // diffusion operators are common to VEF and VEFP1B discretizations
82 if (discr == "VEFPreP1B") discr = "VEF";
83 nom1 += discr;
84 }
85 if (nom1 == "MODELE_TURBULENCE_HYD_SOUS_MAILLE_LM_VEF")
86 {
87 Cerr << "The keyword Sous_maille_LM is now called Longueur_Melange for consistency between VDF and VEF." << finl;
88 Cerr << "Please update your data file." << finl;
90 }
91
92 Cerr << nom1 << finl;
93
94 le_modele_turbulence.typer(nom1);
95 le_modele_turbulence->associer_eqn(*this);
96 le_modele_turbulence->associer(domaine_dis(), domaine_Cl_dis());
97 s >> le_modele_turbulence.valeur(); // on lit !
98
99 le_modele_turbulence->discretiser();
100 RefObjU le_modele;
101 le_modele = le_modele_turbulence.valeur();
102 liste_modeles_.add_if_not(le_modele);
103
104 return 1;
105}
106
111
116
117// Read and type the turbulent diffusion operator.
118// Note: "terme_diffusif.associer_diffusivite" must have been called before entering here.
120{
121 Motcle accouverte = "{", accfermee = "}";
122 Nom type = "Op_Dift_";
123
124 Nom discr = discretisation().que_suis_je();
125 // diffusion operators are common to VEF and VEFP1B discretizations
126 if (discr == "VEFPreP1B") discr = "VEF";
127
128 type += discr;
129
130 Nom nb_inc;
131 if (terme_diffusif.diffusivite().nb_comp() == 1)
132 nb_inc = "_";
133 else
134 nb_inc = "_Multi_inco_";
135 type += nb_inc;
136
137 Nom type_inco = inconnue().que_suis_je();
138 if (type_inco == "Champ_Q1_EF") type += "Q1";
139 else type += (type_inco.suffix("Champ_"));
140
141 if (axi) type += "_Axi";
142
143 Motcle motbidon;
144 is >> motbidon;
145 if (motbidon != accouverte)
146 {
147 Cerr << "A { was expected while reading the turbulent diffusive term" << finl;
149 }
150 is >> motbidon;
151 if (motbidon == "negligeable")
152 {
153 type = "Op_Dift_negligeable";
154 terme_diffusif.typer(type);
155 terme_diffusif.l_op_base().associer_eqn(*this);
156 terme_diffusif->associer_diffusivite(terme_diffusif.diffusivite());
157 is >> motbidon;
158 //read the end of diffusion { }
159 if (motbidon != accfermee)
160 Cerr << " No options can be entered after negligeable " << finl;
161 }
162 else if (motbidon == "tenseur_Reynolds_externe")
163 {
164 terme_diffusif.typer(type);
165 terme_diffusif.l_op_base().associer_eqn(*this);
166 Cerr << terme_diffusif->que_suis_je() << finl;
167 terme_diffusif->associer_diffusivite(terme_diffusif.diffusivite());
168 is >> motbidon;
169 //read the end of diffusion { }
170 if (motbidon != accfermee)
171 Cerr << " No options can be entered after tenseur_Reynolds_externe " << finl;
172 }
173 else if (motbidon == "standard")
174 {
175 type += "_standard";
176 terme_diffusif.typer(type);
177 terme_diffusif.l_op_base().associer_eqn(*this);
178 terme_diffusif->associer_diffusivite(terme_diffusif.diffusivite());
179 is >> terme_diffusif.valeur();
180 }
181 else if (motbidon == accfermee)
182 {
183 terme_diffusif.typer(type);
184 terme_diffusif.l_op_base().associer_eqn(*this);
185 Cerr << terme_diffusif->que_suis_je() << finl;
186 terme_diffusif->associer_diffusivite(terme_diffusif.diffusivite());
187 }
188 else if (motbidon == "stab")
189 {
190 type += "_stab";
191 terme_diffusif.typer(type);
192 terme_diffusif.l_op_base().associer_eqn(*this);
193 terme_diffusif->associer_diffusivite(terme_diffusif.diffusivite());
194 is >> terme_diffusif.valeur();
195 }
196 else if (motbidon == "option")
197 {
198 type += "option";
199 if (discr == "EF")
200 type = "Op_Dift_EF_Q1_option";
201 terme_diffusif.typer(type);
202 Cerr << terme_diffusif->que_suis_je() << finl;
203 terme_diffusif.l_op_base().associer_eqn(*this);
204 terme_diffusif->associer_diffusivite(terme_diffusif.diffusivite());
205 is >> terme_diffusif.valeur();
206 is >> motbidon;
207 //on lit la fin de diffusion { }
208 if (motbidon != accfermee)
209 Cerr << " No options can be entered after option " << finl;
210 }
211 else
212 {
213 type += motbidon;
214 is >> motbidon;
215 if (motbidon != accfermee)
216 Cerr << " No option are now readable for the turbulent diffusive term" << finl;
217
218 if (discr == "VEF")
219 type += "_P1NC";
220 terme_diffusif.typer(type);
221 terme_diffusif.l_op_base().associer_eqn(*this);
222 Cerr << terme_diffusif->que_suis_je() << finl;
223 terme_diffusif->associer_diffusivite(terme_diffusif.diffusivite());
224 }
225 return is;
226}
227
228/*! @brief Prepares the computation.
229 *
230 * Simply calls Modele_turbulence_hyd_base->preparer_calcul() on
231 * the turbulence member.
232 *
233 * @return Always returns 1.
234 */
236{
237
238 Turbulence_paroi_base& loipar = le_modele_turbulence->loi_paroi();
239 if (le_modele_turbulence->has_loi_paroi_hyd())
240 loipar.init_lois_paroi();
241
243 le_modele_turbulence->preparer_calcul();
244 return 1;
245}
246
248{
250 ok = ok && le_modele_turbulence->initTimeStep(dt);
251 return ok;
252}
253
254/*! @brief for PDI IO: retrieve name, type and dimensions of the fields to save/restore
255 *
256 */
258{
259 std::vector<YAML_data> data = Navier_Stokes_std::data_a_sauvegarder();
260 std::vector<YAML_data> mod_turb = le_modele_turbulence->data_a_sauvegarder();
261 data.insert(data.end(), mod_turb.begin(), mod_turb.end());
262 return data;
263}
264
265/*! @brief Saves the equation (and its turbulence model) to an output stream.
266 *
267 * @param os Output stream.
268 * @return Always returns 1.
269 */
271{
272 int bytes = 0;
274 assert(bytes % 4 == 0);
275 bytes += le_modele_turbulence->sauvegarder(os);
276 assert(bytes % 4 == 0);
277 return bytes;
278}
279
280/*! @brief Restores the equation and its turbulence model from an input stream.
281 *
282 * @param is Input stream.
283 * @return Always returns 1.
284 * @throws If end of file is encountered during the restore.
285 */
287{
290 {
291 double temps = schema_temps().temps_courant();
292 Nom ident_modele(le_modele_turbulence->que_suis_je());
293 ident_modele += probleme().domaine().le_nom();
294 ident_modele += Nom(temps, probleme().reprise_format_temps());
295
296 if (probleme().discretisation().is_poly_family())
297 {
298 Nom field_tag_syno = create_polymacfamily_syno(ident_modele);
299 avancer_fichier_with_syno(is,ident_modele,field_tag_syno);
300 }
301 // end of the backward compatibility
302 else
303 avancer_fichier(is,ident_modele);
304 }
305 le_modele_turbulence->reprendre(is);
306
307 return 1;
308}
309
310/*! @brief Successive calls to: Navier_Stokes_std::completer()
311 *
312 * Mod_Turb_Hyd::completer() [on the turbulence member]
313 *
314 */
316{
318 le_modele_turbulence->completer();
319 le_modele_turbulence->loi_paroi().completer();
320}
321
322/*! @brief Performs a time update of the equation.
323 *
324 * @param temps The time to update to.
325 */
327{
329 le_modele_turbulence->mettre_a_jour(temps);
330}
331
332bool Navier_Stokes_Turbulent::has_champ(const Motcle& nom, OBS_PTR(Champ_base)& ref_champ) const
333{
334 if (Navier_Stokes_std::has_champ(nom, ref_champ))
335 return true;
336
337 if (le_modele_turbulence)
338 if (le_modele_turbulence->has_champ(nom, ref_champ))
339 return true;
340
341 return false; /* nothing found */
342}
343
345{
347 return true;
348
349 if (le_modele_turbulence)
350 if (le_modele_turbulence->has_champ(nom))
351 return true;
352
353 return false; /* nothing found */
354}
355
357{
358 OBS_PTR(Champ_base) ref_champ;
359
360 if (Navier_Stokes_std::has_champ(nom, ref_champ))
361 return ref_champ;
362
363 if (le_modele_turbulence)
364 if (le_modele_turbulence->has_champ(nom, ref_champ))
365 return ref_champ;
366
367 throw std::runtime_error(std::string("Field ") + nom.getString() + std::string(" not found !"));
368}
369
371{
373 if (le_modele_turbulence)
374 le_modele_turbulence->get_noms_champs_postraitables(nom, opt);
375}
376
378{
380 le_modele_turbulence->imprimer(os);
381}
382
383const RefObjU& Navier_Stokes_Turbulent::get_modele(Type_modele type) const
384{
385 for (const auto &itr : liste_modeles_)
386 {
387 const RefObjU& mod = itr;
388 if (mod)
389 if ((sub_type(Modele_turbulence_hyd_base, mod.valeur())) && (type == TURBULENCE))
390 return mod;
391 }
392 return Equation_base::get_modele(type);
393}
class Champ_Don_base base class of Given Fields (not calculated)
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual const RefObjU & get_modele(Type_modele type) const
virtual void imprimer(Sortie &os) const
Prints the equation operators if the time scheme indicates it is necessary.
const Discretisation_base & discretisation() const
Returns the discretization associated with the equation.
Nom create_polymacfamily_syno(const Nom &field_tag) const
Create a synonym of a field name in order to ensure backward compatibility with old names of the Poly...
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.
const Champ_Don_base & viscosite_cinematique() const
Definition Fluide_base.h:56
Base class for the turbulence model hierarchy for Navier-Stokes equations.
A character string (Nom) in uppercase.
Definition Motcle.h:26
int debute_par(const char *const n) const override
Definition Motcle.cpp:307
Navier-Stokes equation for a viscous incompressible fluid (div U = 0) with turbulence modelling.
std::vector< YAML_data > data_a_sauvegarder() const override
for PDI IO: retrieve name, type and dimensions of the fields to save/restore
void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const override
const Champ_base & diffusivite_pour_pas_de_temps() const override
const Champ_base & get_champ(const Motcle &nom) const override
void mettre_a_jour(double) override
Performs a time update of the equation.
int sauvegarder(Sortie &) const override
Saves the equation (and its turbulence model) to an output stream.
int preparer_calcul() override
Prepares the computation.
const Champ_Don_base & diffusivite_pour_transport() const override
bool has_champ(const Motcle &nom, OBS_PTR(Champ_base) &ref_champ) const override
int reprendre(Entree &) override
Restores the equation and its turbulence model from an input stream.
bool initTimeStep(double dt) override
Allocation and initialization of the unknown and boundary conditions until present+dt.
void set_param(Param &titi) const override
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
void completer() override
Successive calls to: Navier_Stokes_std::completer().
const RefObjU & get_modele(Type_modele type) const override
void imprimer(Sortie &) const override
Prints the equation operators if the time scheme indicates it is necessary.
Entree & lire_op_diff_turbulent(Entree &is)
Navier_Stokes_std This class carries the terms of the momentum equation.
Operateur_Diff terme_diffusif
int reprendre(Entree &) override
Performs a restart from an input stream.
const Champ_Inc_base & inconnue() const override
Returns the velocity (unknown field of the equation) (const version).
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
const Fluide_base & fluide() const
Returns the incompressible fluid (physical medium of the equation) associated with the equation.
void mettre_a_jour(double temps) override
Performs a time update of the equation.
void completer() override
Completes the base equation, associates the pressure with the equation,.
int sauvegarder(Sortie &) const override
Calls Equation_base::sauvegarder(Sortie&) and saves the pressure to an output stream.
bool initTimeStep(double dt) override
Allocation and initialization of the unknown and boundary conditions until present+dt.
std::vector< YAML_data > data_a_sauvegarder() const override
for PDI IO: retrieve name, type and dimensions of the fields to save/restore
void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const override
void set_param(Param &titi) const override
int preparer_calcul() override
cf Equation_base::preparer_calcul() Assembly of the pressure solver and
OBS_PTR(Fluide_base) le_fluide
bool has_champ(const Motcle &nom, OBS_PTR(Champ_base) &ref_champ) const override
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
Nom & suffix(const char *const)
Suffix extraction: Nom x("azerty");.
Definition Nom.cpp:266
const std::string & getString() const
Definition Nom.h:92
An array of character strings (VECT(Nom)).
Definition Noms.h:26
friend class Entree
Definition Objet_U.h:71
static int dimension
Definition Objet_U.h:94
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 int axi
Definition Objet_U.h:96
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
@ REQUIRED
Definition Param.h:115
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
Definition Param.cpp:489
const Domaine & domaine() const
Returns the domain associated with the problem.
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
double temps_courant() const
Returns the current time.
Base class for output streams.
Definition Sortie.h:52
static int is_PDI_restart()
const Objet_U & valeur() const
Definition TRUST_Ref.h:134
Base class for the hierarchy of wall-law models computing turbulent quantities near walls....
virtual int init_lois_paroi()=0