TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Turbulence_paroi_scal_base.cpp
1/****************************************************************************
2* Copyright (c) 2025, 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_scal_base.h>
17#include <Modele_turbulence_hyd_base.h>
18#include <Turbulence_paroi_scal_base.h>
19#include <Convection_Diffusion_std.h>
20#include <Discretisation_base.h>
21#include <Schema_Temps_base.h>
22#include <Champ_Uniforme.h>
23#include <Probleme_base.h>
24#include <EcrFicPartage.h>
25#include <Domaine_VF.h>
26#include <SFichier.h>
27#include <Dirichlet_paroi_defilante.h>
28#include <Dirichlet_paroi_fixe.h>
29
30Implemente_base_sans_constructeur(Turbulence_paroi_scal_base, "Turbulence_paroi_scal_base", Objet_U);
31
33{
34 return s << que_suis_je() << " " << le_nom();
35}
36
38{
39 return is;
40}
41
45
46/*! @brief Reads the characteristics of the scalar wall law from an input stream.
47 *
48 * Format: type_de_loi_de_paroi
49 * Possible values for the wall law type:
50 * - "loi_standard_hydr"
51 * - "negligeable"
52 * - "loi_VanDriest"
53 * - "loi_standard_hydr_scalaire"
54 *
55 * @param turb_par Scalar wall law object to type and initialize.
56 * @param mod_turb_scal Reference to the scalar turbulence model.
57 * @param s Input stream.
58 */
60{
61 Cerr << "Reading the wall law type " << finl;
62 Motcle typ;
63 s >> typ;
64
65 const Equation_base& eqn = mod_turb_scal.equation().probleme().equation(0); // hydraulic equation
66 const RefObjU& modele_turbulence = eqn.get_modele(TURBULENCE);
67 const Modele_turbulence_hyd_base& mod_turb_hydr = ref_cast(Modele_turbulence_hyd_base, modele_turbulence.valeur());
68 const Turbulence_paroi_base& loi = mod_turb_hydr.loi_paroi();
69
70 if (typ != "negligeable_scalaire")
71 if ((loi.que_suis_je() == "negligeable_VDF") || (loi.que_suis_je() == "negligeable_VEF"))
72 {
73 Cerr << "The wall law of type " << typ << " chosen for the scalar is not compatible with" << finl;
74 Cerr << "the wall law of type " << loi.que_suis_je() << " chosen for the hydraulics" << finl;
75 Cerr << "Use the type 'negligeable_scalaire' for the scalar or use a non-negligible wall law" << finl;
76 Cerr << "for the hydraulics" << finl;
77 exit();
78 }
79 typ += "_";
80
81 Nom discr = eqn.discretisation().que_suis_je();
82
83 // diffusion operators are shared by VEF and VEFP1B discretisations
84 if (discr == "VEFPreP1B")
85 discr = "VEF";
86 typ += discr;
87
88 if (typ == "loi_analytique_scalaire_VDF")
89 {
90 Cerr << "The scalar wall law of type loi_analytique_scalaire" << finl;
91 Cerr << "can only be used with a VEF discretization" << finl;
92 exit();
93 }
94
95 Cerr << "and typing: " << typ << finl;
96 turb_par.typer(typ);
97 turb_par->associer_modele(mod_turb_scal);
98 turb_par->associer(eqn.domaine_dis(), eqn.domaine_Cl_dis());
99}
100
102{
103 return champs_compris_.get_champ(nom);
104}
105
106bool Turbulence_paroi_scal_base::has_champ(const Motcle& nom, OBS_PTR(Champ_base)& ref_champ) const
107{
108 return champs_compris_.has_champ(nom, ref_champ);
109}
111{
112 return champs_compris_.has_champ(nom);
113}
114
116{
117 if (opt == DESCRIPTION)
118 Cerr << "Turbulence_paroi_scal_base : " << champs_compris_.liste_noms_compris() << finl;
119 else
120 nom.add(champs_compris_.liste_noms_compris());
121
122}
123/*! @brief Opens or creates a print file for Face, d_eq, local Nu, h.
124 *
125 * @param Nusselt Shared output file object.
126 * @param extension File extension suffix.
127 */
129{
130 const Probleme_base& pb = mon_modele_turb_scal->equation().probleme();
131 const Schema_Temps_base& sch = pb.schema_temps();
132
133 Nom fichier = Objet_U::nom_du_cas() + "_" + pb.le_nom() + "_" + extension + ".face";
134
135 // Create the file at the first time step if there is no restart
136 if (nb_impr_ == 0 && !pb.reprise_effectuee())
137 Nusselt.ouvrir(fichier);
138 else // Otherwise open in append mode
139 Nusselt.ouvrir(fichier, ios::app);
140
141 if (je_suis_maitre())
142 {
143 EcrFicPartage& fic = Nusselt;
144 fic << "Temps : " << sch.temps_courant();
145 }
146 nb_impr_++;
147}
148
149/*! @brief Opens or creates a file for printing mean values.
150 *
151 * @param fichier Shared output file object.
152 * @param nom_fichier Base filename.
153 * @param extension File extension suffix.
154 */
155void Turbulence_paroi_scal_base::ouvrir_fichier_partage(EcrFicPartage& fichier, const Nom& nom_fichier, const Nom& extension) const
156{
157 const Probleme_base& pb = mon_modele_turb_scal->equation().probleme();
158 Nom nom_fic = nom_fichier + "." + extension;
159
160 // Create the file at the first time step if there is no restart
161 if (nb_impr0_ == 0 && !pb.reprise_effectuee())
162 {
163 fichier.ouvrir(nom_fic);
164 }
165 // Otherwise open in append mode
166 else
167 {
168 fichier.ouvrir(nom_fic, ios::app);
169 }
170 nb_impr0_++;
171}
172
173/*! @brief Give a boolean indicating if we need to use equivant distance by default we consider that we use the equivalent distance
174 *
175 * @return (boolean)
176 */
178{
179 return true;
180}
181
182/**
183 * @brief Writes header line for Nusselt number and heat transfer statistics file
184 *
185 * @param boundaries_ Flag to control boundary selection (0: all boundaries, 1: specified boundaries)
186 * @param boundaries_list List of boundary names to process
187 * @param nom_fichier_ Output filename
188 *
189 * @details Creates header line with column names for thermal statistics including:
190 * - Characteristic distance (m)
191 * - Local Nusselt number
192 * - Convective heat transfer coefficient (W/m²/K)
193 * - Near-wall fluid temperature (K)
194 * - Boundary face temperature (K)
195 * - Equivalent wall temperature (K)
196 *
197 * Format: "Time Mean(field1) Mean(field2) ... [boundary1(field1) boundary1(field2) ...]"
198 * Writes warning messages if specified boundaries are not valid wall types.
199 */
200void Turbulence_paroi_scal_base::imprimer_premiere_ligne_nusselt(int boundaries_, const LIST(Nom) &boundaries_list, const Nom& nom_fichier_) const
201{
202 EcrFicPartage fichier;
203 ouvrir_fichier_partage(fichier, nom_fichier_, "out");
204 Nom ligne="", err;
205 err = "";
206 Noms fields(nb_fields_);
207 fields[0] = "dist. carac. (m)";
208 fields[1] = "Nusselt (local)";
209 fields[2] = "h (Conv. W/m2/K)";
210 fields[3] = "Tf cote paroi (K)";
211 fields[4] = "T face de bord (K)";
212 fields[5] = "Tparoi equiv.(K)";
213 for (int i=0; i<nb_fields_; i++)
214 {
215 ligne+="# ";
216 ligne+="field";
217 ligne += (Nom)i;
218 ligne += " : ";
219 ligne += fields[i];
220 ligne += "\n";
221 }
222 ligne += "# Time ";
223 for (int i=0; i<nb_fields_; i++)
224 {
225 ligne += " \tMean(";
226 //ligne += fields[i];
227 ligne += "field";
228 ligne += (Nom)i;
229 ligne += ")";
230 }
231 for (int n_bord = 0; n_bord < le_dom_dis_->nb_front_Cl(); n_bord++)
232 {
233 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
234 const Nom& nom_bord = la_cl->frontiere_dis().le_nom();
235 if (je_suis_maitre() && (boundaries_list.contient(nom_bord) || boundaries_list.size() == 0))
236 {
237 if (sub_type(Dirichlet_paroi_fixe,la_cl.valeur()) || sub_type(Dirichlet_paroi_defilante, la_cl.valeur()))
238 {
239 for (int i=0; i<nb_fields_; i++)
240 {
241 ligne += " \t";
242 ligne += nom_bord;
243 ligne += "(";
244 //ligne += fields[i];
245 ligne += "field";
246 ligne += (Nom)i;
247 ligne += ")";
248 }
249 }
250 else if (boundaries_list.size() > 0)
251 {
252 err += "The boundary named '";
253 err += nom_bord;
254 err += "' is not of type Dirichlet_paroi_fixe or Dirichlet_paroi_defilante.\n";
255 err += "So TRUST will not write Nusselt mean values.\n\n";
256 }
257 }
258 }
259 if (je_suis_maitre())
260 {
261 fichier << err;
262 fichier << ligne;
263 fichier << finl;
264 }
265 fichier.syncfile();
266}
267
268/**
269 * @brief Prints mean Nusselt number and heat transfer statistics to a file for specified boundaries
270 *
271 * @param os Output stream for messages
272 * @param boundaries_ Flag to control boundary selection (0: all boundaries, 1: specified boundaries)
273 * @param boundaries_list List of boundary names to process when boundaries_=1
274 * @param nom_fichier_ Output filename
275 * @details Calculates and writes average values for multiple thermal parameters:
276 * - Characteristic distance
277 * - Nusselt number
278 * - Heat transfer coefficient
279 * - Near-wall temperatures
280 * - Wall temperatures
281 *
282 * Results are written for all boundaries combined and then for each boundary separately.
283 * Only processes fixed walls (Dirichlet_paroi_fixe) and moving walls (Dirichlet_paroi_defilante).
284 * Output format: time [mean_values] [boundary1_values] [boundary2_values] ...
285 */
286void Turbulence_paroi_scal_base::imprimer_nusselt_mean_only(Sortie& os, int boundaries_, const LIST(Nom) &boundaries_list, const Nom& nom_fichier_) const
287{
289 const Probleme_base& pb = mon_modele_turb_scal->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, nb_fields_+1);
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 for (int i=0; i<nb_fields_; i++)
323 {
324 moy_bords(0, i) += aire * tab_(num_face, i);
325 moy_bords(num_bord + 1, i) += aire * tab_(num_face, i);
326 }
327 moy_bords(0, nb_fields_) += aire;
328 moy_bords(num_bord + 1, nb_fields_) += aire;
329 }
330 num_bord += 1;
331 }
332 }
333 }
334 mp_sum_for_each_item(moy_bords);
335
336// print lines to the file
337 if (je_suis_maitre())
338 {
339 fichier << sch.temps_courant();
340 if (moy_bords(0, nb_fields_) != 0)
341 for (int i=0; i<nb_fields_; i++)
342 fichier << " \t" << moy_bords(0, i) / moy_bords(0, nb_fields_);
343 }
344
345 num_bord = 0;
346 for (int n_bord = 0; n_bord < le_dom_dis_->nb_front_Cl(); n_bord++)
347 {
348 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
349 if ((sub_type(Dirichlet_paroi_fixe, la_cl.valeur())) || (sub_type(Dirichlet_paroi_defilante, la_cl.valeur())))
350 {
351 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
352 if (boundaries_ == 0 || (boundaries_ == 1 && boundaries_list.contient(le_bord.le_nom())))
353 {
354 if (je_suis_maitre())
355 {
356 for (int i=0; i<nb_fields_; i++)
357 fichier << " \t" << moy_bords(num_bord + 1, i) / moy_bords(num_bord + 1, nb_fields_);
358 }
359 num_bord += 1;
360 }
361 }
362 }
363
364 if (je_suis_maitre())
365 fichier << finl;
366 fichier.syncfile();
367}
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
bool has_champ(const Motcle &nom, OBS_PTR(FIELD_TYPE)&ref_champ) const
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.
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....
virtual const RefObjU & get_modele(Type_modele type) const
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.
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.
const Turbulence_paroi_base & loi_paroi() const
Base class for scalar turbulence models coupled to a Navier-Stokes convection-diffusion equation.
Convection_Diffusion_std & equation()
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
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.
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
const Objet_U & valeur() const
Definition TRUST_Ref.h:134
Base class for the hierarchy of wall-law models computing turbulent quantities near walls....
Base class for the hierarchy of scalar wall-law models computing turbulent quantities near walls....
virtual bool use_equivalent_distance() const
Give a boolean indicating if we need to use equivant distance by default we consider that we use the ...
void imprimer_premiere_ligne_nusselt(int, const LIST(Nom)&, const Nom &) const
Writes header line for Nusselt number and heat transfer statistics file.
static void typer_lire_turbulence_paroi_scal(OWN_PTR(Turbulence_paroi_scal_base)&, const Modele_turbulence_scal_base &, Entree &)
Reads the characteristics of the scalar wall law from an input stream.
void creer_champ(const Motcle &motlu) override
const Champ_base & get_champ(const Motcle &nom) const override
void imprimer_nusselt_mean_only(Sortie &, int, const LIST(Nom)&, const Nom &) const
Prints mean Nusselt number and heat transfer statistics to a file for specified boundaries.
void associer_modele(const Modele_turbulence_scal_base &)
Associates a turbulence model to the object.
void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const override
virtual void compute_nusselt() const =0
bool has_champ(const Motcle &nom, OBS_PTR(Champ_base) &ref_champ) const override
virtual void associer(const Domaine_dis_base &, const Domaine_Cl_dis_base &)=0
void ouvrir_fichier_partage(EcrFicPartage &, const Nom &) const
Opens or creates a print file for Face, d_eq, local Nu, h.