TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Fluide_Weakly_Compressible.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 <Fluide_Weakly_Compressible.h>
17#include <Loi_Etat_Multi_GP_WC.h>
18#include <Neumann_sortie_libre.h>
19#include <Domaine_Cl_dis_base.h>
20#include <Champ_Fonc_Fonction.h>
21#include <Discretisation_base.h>
22#include <Schema_Temps_base.h>
23
24#include <Probleme_base.h>
25#include <Equation_base.h>
26#include <Domaine_VF.h>
27#include <Param.h>
28
29Implemente_instanciable(Fluide_Weakly_Compressible,"Fluide_Weakly_Compressible",Fluide_Dilatable_base);
30// XD fluide_weakly_compressible fluide_base fluide_weakly_compressible INHERITS_BRACE Weakly-compressible flow with a
31// XD_CONT low mach number assumption; this means that the thermo-dynamic pressure (used in state law) can vary in
32// XD_CONT space.
33// XD attr loi_etat loi_etat_base loi_etat OPT The state law that will be associated to the Weakly-compressible fluid.
34// XD attr sutherland bloc_sutherland sutherland OPT Sutherland law for viscosity and for conductivity.
35// XD attr traitement_pth chaine(into=["constant"]) traitement_pth OPT Particular treatment for the thermodynamic
36// XD_CONT pressure Pth ; there is currently one possibility: NL2 1) the keyword \'constant\' makes it possible to have
37// XD_CONT a constant Pth but not uniform in space ; it\'s the good choice when the flow is open (e.g. with pressure
38// XD_CONT boundary conditions).
39// XD attr lambda field_base lambda_u OPT Conductivity (W.m-1.K-1).
40// XD attr mu field_base mu OPT Dynamic viscosity (kg.m-1.s-1).
41
43
45{
46 traitement_PTh_ = 2; /* par default */
48}
49
51{
53 param.ajouter("pression_thermo", &Pth_); // XD_ADD_P double
54 // XD_CONT Initial thermo-dynamic pressure used in the assosciated state law.
55 param.ajouter("pression_xyz", &ch_Pth_xyz_); // XD_ADD_P field_base
56 // XD_CONT Initial thermo-dynamic pressure used in the assosciated state law. It should be defined with as a
57 // XD_CONT Champ_Fonc_xyz.
58 param.ajouter("use_total_pressure", &use_total_pressure_); // XD_ADD_P entier
59 // XD_CONT Flag (0 or 1) used to activate and use the total pressure in the assosciated state law. The default value
60 // XD_CONT of this Flag is 0.
61 param.ajouter("use_hydrostatic_pressure", &use_hydrostatic_pressure_); // XD_ADD_P entier
62 // XD_CONT Flag (0 or 1) used to activate and use the hydro-static pressure in the assosciated state law. The default
63 // XD_CONT value of this Flag is 0.
64 param.ajouter("use_grad_pression_eos", &use_grad_pression_eos_); // XD_ADD_P entier
65 // XD_CONT Flag (0 or 1) used to specify whether or not the gradient of the thermo-dynamic pressure will be taken into
66 // XD_CONT account in the source term of the temperature equation (case of a non-uniform pressure). The default value
67 // XD_CONT of this Flag is 1 which means that the gradient is used in the source.
68 param.ajouter("time_activate_ptot", &time_activate_ptot_); // XD_ADD_P double
69 // XD_CONT Time (in seconds) at which the total pressure will be used in the assosciated state law.
70}
71
72/*! @brief Complete le fluide avec les champs inconnus associes au probleme
73 *
74 * @param (Pb_Thermohydraulique& pb) le probleme a resoudre
75 */
77{
78 Cerr << "Fluide_Weakly_Compressible::completer";
79
80 if (Pth_ > -1.)
81 Cerr << " Pth = " << Pth_ << finl;
82 else
83 Cerr << finl;
84
87
88 if (ch_Pth_xyz_)
89 {
90 if (ch_Pth_xyz_->que_suis_je() != "Champ_Fonc_xyz") // TODO : check if it is generic
91 {
92 Cerr << "Error in your data file : This is not allowed !" << finl;
93 Cerr << "Pression_xyz should be defined with Champ_Fonc_xyz !" << finl;
95 }
96 if (Pth_ > -1. || Pth_n_ > -1.)
97 {
98 Cerr << "Error in your data file : This is not allowed !" << finl;
99 Cerr << "You can not specify both pression_xyz and pression_thermo !" << finl;
101 }
103 {
104 Cerr << "Error in your data file : This is not allowed !" << finl;
105 Cerr << "You need to define pression_thermo when using the flags use_total_pressure or use_hydrostatic_pressure !" << finl;
107 }
108 }
109 else // pression_xyz not specified in data file
110 {
111 if (Pth_ > -1.)
112 Pth_n_ = Pth_;
113 else
114 {
115 Cerr << "Error in your data file : This is not allowed !" << finl;
116 Cerr << "You need to specify either pression_xyz or pression_thermo !" << finl;
118 }
119
121 {
122 Cerr << "Error in your data file : This is not allowed !" << finl;
123 Cerr << "You should define time_activate_ptot when using the flag use_total_pressure !" << finl;
125 }
126
128 {
129 Cerr << "Error in your data file : This is not allowed !" << finl;
130 Cerr << "Not possible to activate the two flags use_total_pressure and use_hydrostatic_pressure at same time !" << finl;
132 }
133
135 {
136 Cerr << "Error in your data file : This is not allowed !" << finl;
137 Cerr << "Not possible to activate the flag use_hydrostatic_pressure without defining a gravity vector !" << finl;
139 }
140 }
141
142 // XXX: needed to initialize rho ...
143 if (!use_saved_data())
144 {
145 if (use_pth_xyz())
146 {
147 Cerr << "Initializing the thermo-dynamic pressure Pth_xyz ..." << finl;
148 int isVDF = 0; // VDF or VEF ??
149 if (pb.equation(0).discretisation().que_suis_je() == "VDF")
150 isVDF = 1;
151
152 // We know that mu is always stored on elems and that OWN_PTR(Champ_Don_base) rho_xyz_ is evaluated on elements
153 assert(ch_Pth_xyz_->valeurs().size() == viscosite_dynamique().valeurs().size());
154
155 if (isVDF) // Disc VDF => Pth_xyz_ on elems => we do nothing
156 Pth_tab_ = Pth_n_tab_ = ch_Pth_xyz_->valeurs();
157 else
158 {
159 // we use rho for affecter because the field is on the faces in VEF (as rho)
160 Champ_base& ch_rho = masse_volumique();
161 ch_rho.affecter_(ch_Pth_xyz_);
162 Pth_tab_ = Pth_n_tab_ = ch_rho.valeurs();
163 }
164 }
165 else
166 {
167 Cerr << "Initializing the thermo-dynamic pressure ..." << finl;
168 // Pth_tab_ must have the same dimensions as rho (element in VDF and face in VEF)
170 const int n = Pth_tab_.dimension_tot(0);
171 for (int i = 0; i < n; i++)
172 Pth_tab_(i) = Pth_;
174 }
175 }
176
177 ch_pression_eos_->valeurs() = Pth_tab_;
178
180
181 // le bon temps
182 assert(ch_pression_eos_);
183 ch_pression_eos_->mettre_a_jour(le_probleme_->schema_temps().temps_courant());
184
186 ch_pression_hydro_->mettre_a_jour(le_probleme_->schema_temps().temps_courant());
187
189 ch_unsolved_species_->mettre_a_jour(le_probleme_->schema_temps().temps_courant());
190}
191
193{
194 if (traitement_PTh_ == 0)
195 {
196 Cerr << "The EDO option for the pressure treatment is not yet supported for the Weakly_Compressible module !" << finl;
197 Cerr << "Please use either conservation_masse or constant options !" << finl;
199 }
200 // call to the parent class
202}
203
205{
206 const Domaine_dis_base& domaine_dis = pb.equation(0).domaine_dis();
207 double temps = pb.schema_temps().temps_courant();
208
209 // In *_Melange_Binaire_WC we do not even have a temperature variable ...
210 // it is the species mass fraction Y1... Although named ch_temperature
211 if (pb.que_suis_je() == "Pb_Hydraulique_Melange_Binaire_WC" || pb.que_suis_je() == "Pb_Hydraulique_Melange_Binaire_Turbulent_WC")
212 dis.discretiser_champ("temperature", domaine_dis, "fraction_massique", "neant", 1, temps, loi_etat_->temperature_);
213 else
214 dis.discretiser_champ("temperature", domaine_dis, "temperature", "K", 1, temps, loi_etat_->temperature_);
215
216 if (type_fluide() != "Gaz_Parfait")
217 loi_etat()->champs_compris().ajoute_champ(ch_temperature());
218
220
221 // XXX XXX: WC fields: like temperature, element in VDF and face in VEF
222 dis.discretiser_champ("temperature", domaine_dis, "pression_hydro", "Pa", 1, temps, ch_pression_hydro_);
223 champs_compris_.ajoute_champ(ch_pression_hydro_.valeur());
224
225 dis.discretiser_champ("temperature", domaine_dis, "pression_eos", "Pa", 1, temps, ch_pression_eos_);
226 champs_compris_.ajoute_champ(ch_pression_eos_.valeur());
227
228 // Only for multi-species
229 if (pb.que_suis_je() == "Pb_Thermohydraulique_Especes_WC")
230 {
231 dis.discretiser_champ("temperature", domaine_dis, "fraction_massique_nonresolue", "neant", 1, temps, ch_unsolved_species_);
232 champs_compris_.ajoute_champ(ch_unsolved_species_.valeur());
233 }
234}
235
242
244{
246 if (a_gravite())
247 {
248 calculer_pression_hydro();
249 ch_pression_hydro_->mettre_a_jour(temps);
250 }
251 // for post-processing
252 ch_pression_eos_->valeurs() = Pth_tab_;
253 ch_pression_eos_->mettre_a_jour(temps);
254}
255
256/*! @brief Calcule la pression totale : pression thermodynamique + pression hydrodynamique
257 *
258 */
265
266void Fluide_Weakly_Compressible::remplir_champ_pression_tot(int n, const DoubleTab& PHydro, DoubleTab& PTot)
267{
268 P_NS_elem_ = PHydro; // pressure on elem for vdf & vef ...
269 if (use_pth_xyz())
270 for (int i = 0; i < n; i++)
271 PTot(i, 0) = PHydro(i, 0) + Pth_tab_(i, 0);
272 else
273 for (int i = 0; i < n; i++)
274 PTot(i, 0) = PHydro(i, 0) + Pth_;
275}
276
277/*! @brief Calcule la pression hydrostatique = rho*g*z
278 *
279 */
280void Fluide_Weakly_Compressible::calculer_pression_hydro()
281{
282 DoubleTab& tab_Phydro = ch_pression_hydro_->valeurs();
283 const Domaine_dis_base& domaine_dis= ch_pression_->domaine_dis_base();
284 const Domaine_VF& domaine = ref_cast(Domaine_VF, domaine_dis);
285 int is_VDF = domaine_dis.que_suis_je() == "Domaine_VDF" ? 1 : 0;
286 const DoubleTab& centres_de_gravites = is_VDF ? domaine.xp() : domaine.xv();
287 const DoubleTab& tab_rho = rho_np1(), grav = gravite().valeurs();
288 const int n = tab_Phydro.dimension_tot(0);
289 assert(n == tab_rho.dimension_tot(0) && a_gravite());
290 for (int i = 0; i < n; i++)
291 {
292 double gz = 0.;
293 for (int dir = 0; dir < dimension; dir++)
294 gz += centres_de_gravites(i, dir) * grav(0, dir);
295
296 tab_Phydro(i) = tab_rho(i) * gz;
297 }
299 remplir_champ_pression_for_EOS();
300}
301
302/*! @brief Computes the pressure used in the WC equation of state
303 *
304 */
305void Fluide_Weakly_Compressible::remplir_champ_pression_for_EOS()
306{
307 if (use_total_pressure())
308 {
309 double t0 = le_probleme_->schema_temps().temps_courant(), t1 = le_probleme_->schema_temps().temps_futur(1);
310 // time to activate ptot and change the eos pressure
311 if (t0 < time_activate_ptot_ && t1 > time_activate_ptot_)
312 {
313 if (Pth_tab_.dimension_tot(0) == P_NS_elem_.dimension_tot(0)) // VDF
314 for (int i = 0; i < Pth_tab_.dimension_tot(0); i++)
315 Pth_tab_(i, 0) = P_NS_elem_(i, 0) + Pth_;
316 else // VEF: to be handled when PolyMAC_HFV support is added
317 {
318 // P_NS_elem_ is at elements and Pth_tab_ is like rho, i.e. at faces
319 const Domaine_VF& zvf = ref_cast(Domaine_VF, inco_chaleur().domaine_dis_base());
320 assert(Pth_tab_.dimension_tot(0) == zvf.nb_faces_tot());
321
322 const IntTab& elem_faces = zvf.elem_faces();
323 const DoubleVect& volumes = zvf.volumes();
324 const int nb_face_elem = elem_faces.dimension(1), nb_elem_tot = zvf.nb_elem_tot();
325
326 Pth_tab_ = 0.;
327 DoubleTab vol_tot(Pth_tab_);
328 for (int ele = 0; ele < nb_elem_tot; ele++)
329 for (int s = 0; s < nb_face_elem; s++)
330 {
331 Pth_tab_(elem_faces(ele, s)) += P_NS_elem_(ele, 0) * volumes(ele);
332 vol_tot(elem_faces(ele, s)) += volumes(ele);
333 }
334 for (int f = 0; f < zvf.nb_faces(); f++)
335 Pth_tab_(f) /= vol_tot(f);
336
337 // enfin ajoute Pth_ !
338 Pth_tab_ += Pth_;
339 }
340 }
341 }
342 else if (use_hydrostatic_pressure())
343 {
344 if (le_probleme_->schema_temps().nb_pas_dt() == 0 && use_saved_data())
345 { /* do nothing & use saved data */ }
346 else
347 {
348 Pth_tab_ = ch_pression_hydro_->valeurs();
349 const int n = Pth_tab_.dimension_tot(0);
350 for (int i = 0; i < n; i++)
351 Pth_tab_(i) += Pth_; // present dt
352 }
353 }
354 else
355 {
356 Cerr << "The method Fluide_Weakly_Compressible::remplir_champ_pression_for_EOS() should not be called !" << finl;
358 }
359}
360
362{
363 if (je_suis_maitre())
364 {
367 fic << "# Time sum(T*dv)/sum(dv)[K] sum(rho*dv)/sum(dv)[kg/m3] Pth[Pa]" << finl;
368 else
369 fic << "# Time sum(T*dv)/sum(dv)[K] sum(rho*dv)/sum(dv)[kg/m3] Mean_Pth[Pa]" << finl;
370 }
371}
372
374{
375 const double Ch_m = eos_tools_->moyenne_vol(ch_inco_chaleur_->valeurs());
376 const double rhom = eos_tools_->moyenne_vol(ch_rho_->valeurs());
377
378 if (je_suis_maitre() && traitement_PTh_ != 2)
379 {
380 SFichier fic(output_file_, ios::app);
382 fic << temps << " " << Ch_m << " " << rhom << " " << Pth_ << finl;
383 else
384 fic << temps << " " << Ch_m << " " << rhom << " " << eos_tools_->moyenne_vol(Pth_tab_) << finl;
385 }
386}
DoubleTab & valeurs() override
Overrides Champ_base::valeurs() Returns the array of values.
virtual DoubleTab & valeurs()=0
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
virtual Champ_base & affecter_(const Champ_base &)=0
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
class Domaine_Cl_dis_base Domaine_Cl_dis_base objects represent discretized boundary conditions
int nb_faces() const
Returns the total number of faces.
Definition Domaine_VF.h:471
int nb_faces_tot() const
Returns the total number of faces.
Definition Domaine_VF.h:481
double volumes(int i) const
Definition Domaine_VF.h:113
int elem_faces(int i, int j) const
Returns the index of the i-th face of element num_elem; the face numbering convention is.
Definition Domaine_VF.h:542
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
int nb_elem_tot() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
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.
Domaine_dis_base & domaine_dis()
Returns the discretized domain associated with the equation.
Base class for a dilatable fluid, inheriting from Fluide_base.
const Champ_Don_base & ch_temperature() const
Returns the temperature field.
virtual void calculer_pression_tot()
Computes the total pressure: thermodynamic pressure + hydrodynamic pressure.
virtual void checkTraitementPth(const Domaine_Cl_dis_base &)
const Champ_Inc_base & inco_chaleur() const
virtual void update_pressure_fields(double)
void discretiser(const Probleme_base &pb, const Discretisation_base &dis) override
const DoubleTab & rho_np1() const
void set_param(Param &param) const override
const Nom type_fluide() const
virtual void completer(const Probleme_base &)
Completes the fluid with the unknown fields associated with the problem.
Fluide_Weakly_Compressible class This class represents a weakly compressible fluid,...
void set_param(Param &param) const override
void discretiser(const Probleme_base &pb, const Discretisation_base &dis) override
void calculer_pression_tot() override
Calcule la pression totale : pression thermodynamique + pression hydrodynamique.
void completer(const Probleme_base &) override
Complete le fluide avec les champs inconnus associes au probleme.
void checkTraitementPth(const Domaine_Cl_dis_base &) override
const Champ_Don_base & viscosite_dynamique() const
Definition Fluide_base.h:58
virtual const Champ_base & masse_volumique() const
Returns the mass density of the medium (const version).
Champs_compris champs_compris_
virtual int a_gravite() const
Returns 1 if gravity has been initialized.
virtual const Champ_Don_base & gravite() const
Returns the gravity of the medium if it has been associated, raises an error otherwise (const version...
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
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
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
class Probleme_base It is a Probleme_U that is not a coupling.
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 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
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
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133