TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Navier_Stokes_IBM_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 <Navier_Stokes_IBM_Turbulent.h>
17#include <Modele_turbulence_hyd_base.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_IBM_Turbulent, "Navier_Stokes_IBM_Turbulent", Navier_Stokes_IBM);
31// XD navier_stokes_ibm_turbulent navier_stokes_standard navier_stokes_ibm_turbulent INHERITS_BRACE IBM Navier-Stokes
32// XD_CONT equations as 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_IBM_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 // the diffusion operators are shared between 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(); // read it!
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// Reading and typing of 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 shared between VEF and VEFP1B discretisations
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 closing brace 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 closing brace 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 //read the closing brace of 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 * @brief Simple call to Modele_turbulence_hyd_base->preparer_calcul() on the turbulence member.
231 *
232 * @return Always returns 1.
233 */
235{
236
237 Turbulence_paroi_base& loipar = le_modele_turbulence->loi_paroi();
238 if (le_modele_turbulence->has_loi_paroi_hyd())
239 loipar.init_lois_paroi();
240
242 le_modele_turbulence->preparer_calcul();
243 return 1;
244}
245
247{
249 ok = ok && le_modele_turbulence->initTimeStep(dt);
250 return ok;
251}
252
253/*! @brief for PDI IO: retrieve name, type and dimensions of the fields to save/restore
254 *
255 */
257{
258 std::vector<YAML_data> data = Navier_Stokes_IBM::data_a_sauvegarder();
259 std::vector<YAML_data> mod_turb = le_modele_turbulence->data_a_sauvegarder();
260 data.insert(data.end(), mod_turb.begin(), mod_turb.end());
261 return data;
262}
263
264/*! @brief Saves the equation (and its turbulence model) to an output stream.
265 *
266 * @param os The output stream.
267 * @return Always returns 1.
268 */
270{
271 int bytes = 0;
273 assert(bytes % 4 == 0);
274 bytes += le_modele_turbulence->sauvegarder(os);
275 assert(bytes % 4 == 0);
276 return bytes;
277}
278
279/*! @brief Restores the equation and its turbulence model from an input stream.
280 *
281 * @param is The input stream.
282 * @return Always returns 1.
283 * @throws End of file encountered during restart.
284 */
286{
289 {
290 double temps = schema_temps().temps_courant();
291 Nom ident_modele(le_modele_turbulence->que_suis_je());
292 ident_modele += probleme().domaine().le_nom();
293 ident_modele += Nom(temps, probleme().reprise_format_temps());
294
295 if (probleme().discretisation().is_poly_family())
296 {
297 Nom field_tag_syno = create_polymacfamily_syno(ident_modele);
298 avancer_fichier_with_syno(is,ident_modele,field_tag_syno);
299 }
300 // end of the backward compatibility
301 else
302 avancer_fichier(is,ident_modele);
303 }
304 le_modele_turbulence->reprendre(is);
305
306 return 1;
307}
308
309/*! @brief Successive calls to: Navier_Stokes_IBM::completer()
310 *
311 * Mod_Turb_Hyd::completer() [on the relevant member]
312 *
313 */
315{
317 le_modele_turbulence->completer();
318 le_modele_turbulence->loi_paroi().completer();
319}
320
321/*! @brief Performs a time update of the equation.
322 *
323 * @param temps The update time.
324 */
326{
328 le_modele_turbulence->mettre_a_jour(temps);
329}
330
331bool Navier_Stokes_IBM_Turbulent::has_champ(const Motcle& nom, OBS_PTR(Champ_base)& ref_champ) const
332{
333 if (Navier_Stokes_IBM::has_champ(nom, ref_champ))
334 return true;
335
336 if (le_modele_turbulence)
337 if (le_modele_turbulence->has_champ(nom, ref_champ))
338 return true;
339
340 return false; /* nothing found */
341}
342
344{
346 return true;
347
348 if (le_modele_turbulence)
349 if (le_modele_turbulence->has_champ(nom))
350 return true;
351
352 return false; /* nothing found */
353}
354
356{
357 OBS_PTR(Champ_base) ref_champ;
358
359 if (Navier_Stokes_IBM::has_champ(nom, ref_champ))
360 return ref_champ;
361
362 if (le_modele_turbulence)
363 if (le_modele_turbulence->has_champ(nom, ref_champ))
364 return ref_champ;
365
366 throw std::runtime_error(std::string("Field ") + nom.getString() + std::string(" not found !"));
367}
368
370{
372 if (le_modele_turbulence)
373 le_modele_turbulence->get_noms_champs_postraitables(nom, opt);
374}
375
377{
379 le_modele_turbulence->imprimer(os);
380}
381
382const RefObjU& Navier_Stokes_IBM_Turbulent::get_modele(Type_modele type) const
383{
384 for (const auto &itr : liste_modeles_)
385 {
386 const RefObjU& mod = itr;
387 if (mod)
388 if ((sub_type(Modele_turbulence_hyd_base, mod.valeur())) && (type == TURBULENCE))
389 return mod;
390 }
391 return Equation_base::get_modele(type);
392}
393
395{
397
398 if (le_modele_turbulence) le_modele_turbulence->creer_champ(motlu);
399}
400
405
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
virtual void creer_champ(const Motcle &motlu)=0
virtual void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const =0
virtual bool has_champ(const Motcle &nom, OBS_PTR(Champ_base)&ref_champ) const =0
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
OBS_PTR(Equation_base) eq_IBM_
int reprendre(Entree &) override
We resume the unknown from an input stream.
virtual const RefObjU & get_modele(Type_modele type) const
virtual std::vector< YAML_data > data_a_sauvegarder() const
for PDI IO: retrieve name, type and dimensions of the data to save/restore. This has to be overrode f...
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 void mettre_a_jour(double temps)
The value of the unknown at the time step has been calculated.
virtual void completer()
Completes the construction (initialization) of objects associated with the equation.
virtual void imprime_residu(SFichier &)
int sauvegarder(Sortie &) const override
We save the unknown, then the source terms to an output stream.
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.
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
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.
virtual Nom expression_residu()
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
Turbulent IBM Navier-Stokes equation.
const RefObjU & get_modele(Type_modele type) const override
void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const override
const Champ_base & diffusivite_pour_pas_de_temps() const override
int sauvegarder(Sortie &) const override
Saves the equation (and its turbulence model) to an output stream.
void mettre_a_jour(double) override
Performs a time update of the equation.
void completer() override
Successive calls to: Navier_Stokes_IBM::completer().
std::vector< YAML_data > data_a_sauvegarder() const override
for PDI IO: retrieve name, type and dimensions of the fields to save/restore
const Champ_base & get_champ(const Motcle &nom) const override
void creer_champ(const Motcle &motlu) override
void set_param(Param &titi) const override
int preparer_calcul() override
Prepares the computation.
void imprimer(Sortie &) const override
Prints the equation operators if the time scheme indicates it is necessary.
bool has_champ(const Motcle &nom, OBS_PTR(Champ_base) &ref_champ) const override
bool initTimeStep(double dt) override
Allocation and initialization of the unknown and boundary conditions until present+dt.
const Champ_Don_base & diffusivite_pour_transport() const override
int reprendre(Entree &) override
Restores the equation and its turbulence model from an input stream.
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U 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 preparer_calcul() override
Everything that does not depend on other possible problems.
Operateur_Diff terme_diffusif
const Champ_Inc_base & inconnue() const override
Returns the velocity (unknown field of the equation) (const version).
const Fluide_base & fluide() const
Returns the incompressible fluid (physical medium of the equation) associated with the equation.
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
static int dimension
Definition Objet_U.h:94
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
SFichier is to the C++ ofstream class what Sortie is to the C++ ostream class.
Definition SFichier.h:29
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