TrioCFD 1.9.8
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 : On l'a besoin pour initialiser 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_ doit avoir meme dimensions que rho (elem en VDF et faces en 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 // appel a la classe mere
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 : Champs pour WC : comme la temperature car elem en VDF et faces en 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 // Seulement pour multi-especes
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 Calcule la pression utilisee dans les lois d'etat WC
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 : on verra le jour ou on fait du PolyMAC_HFV
317 {
318 // on a P_NS_elem_ aux elems et Pth_tab_ comme rho, i.e aux 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
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
virtual DoubleTab & valeurs()=0
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
virtual Champ_base & affecter_(const Champ_base &)=0
classe Discretisation_base Cette classe represente un schema de discretisation en espace,...
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
classe Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
int nb_faces() const
renvoie le nombre global de faces.
Definition Domaine_VF.h:471
int nb_faces_tot() const
renvoie le nombre total de faces.
Definition Domaine_VF.h:481
double volumes(int i) const
Definition Domaine_VF.h:113
int elem_faces(int i, int j) const
renvoie le numero de le ieme face de la maille num_elem la facon dont ces faces sont numerotees est
Definition Domaine_VF.h:543
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
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
Renvoie la discretisation associee a l'equation.
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limite discretisee associee a l'equation.
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise associe a l'equation.
classe Fluide_Dilatable_base Cette classe represente un d'un fluide dilatable,
const Champ_Don_base & ch_temperature() const
Renvoie le champ de le temperature.
virtual void calculer_pression_tot()
Calcule la pression totale : pression thermodynamique + pression hydrodynamique.
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 &)
Complete le fluide avec les champs inconnus associes au probleme.
classe Fluide_Weakly_Compressible Cette classe represente un d'un fluide faiblement compressible
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:60
virtual const Champ_base & masse_volumique() const
Renvoie la masse volumique du milieu.
Champs_compris champs_compris_
virtual int a_gravite() const
Renvoie 1 si la gravite a ete initialisee.
virtual const Champ_Don_base & gravite() const
Renvoie la gravite du milieu si elle a ete associe provoque une erreur sinon.
static int dimension
Definition Objet_U.h:99
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
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
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
const Schema_Temps_base & schema_temps() const
Renvoie le schema en temps associe au probleme.
virtual const Equation_base & equation(int) const =0
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
Definition SFichier.h:27
double temps_courant() const
Renvoie le temps courant.
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133