TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
EDO_Pression_th_VDF_Gaz_Parfait.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 <EDO_Pression_th_VDF_Gaz_Parfait.h>
17#include <Fluide_Quasi_Compressible.h>
18#include <Neumann_sortie_libre.h>
19#include <Schema_Temps_base.h>
20#include <Navier_Stokes_std.h>
21#include <Domaine_Cl_VDF.h>
22#include <Loi_Etat_GP_QC.h>
23#include <Domaine_VDF.h>
24#include <Dirichlet.h>
25#include <TRUSTTrav.h>
26
27Implemente_instanciable(EDO_Pression_th_VDF_Gaz_Parfait, "EDO_Pression_th_VDF_Gaz_Parfait", EDO_Pression_th_VDF);
28
29Sortie& EDO_Pression_th_VDF_Gaz_Parfait::printOn(Sortie& os) const { return os << que_suis_je() << finl; }
30
32
33/*! @brief Solves the ODE for the thermodynamic pressure.
34 *
35 * @param Pth_n pressure at the previous time step
36 * @return new value of the thermodynamic pressure
37 */
39{
40 int traitPth = le_fluide_->getTraitementPth();
41 const DoubleTab& tempnp1 = le_fluide_->inco_chaleur().valeurs(); //current
42 if (traitPth == 0)
43 {
44 Cerr << "Selecting thermodynamic pressure treatment " << finl;
45 int n_bord;
46 traitPth = 1;
47 for (n_bord = 0; n_bord < le_dom->nb_front_Cl(); n_bord++)
48 {
49 const Cond_lim& la_cl = le_dom_Cl->les_conditions_limites(n_bord);
50 if (sub_type(Neumann_sortie_libre, la_cl.valeur()))
51 {
52 traitPth = 2;
53 return Pth_n;
54 }
55 }
56 }
57
58 double dt = le_fluide_->vitesse().equation().schema_temps().pas_de_temps();
59 if (traitPth == 2) //Cerr << "constant treatment" << finl;
60 {
61 return Pth_n;
62 }
63 else if (traitPth == 1)
64 {
65 const DoubleTab& tempn = le_fluide_->inco_chaleur().passe();
66 double cn1 = 0, cn = 0, v;
67 int elem, nb_elem = le_dom->nb_elem();
68 for (elem = 0; elem < nb_elem; elem++)
69 {
70 v = le_dom->volumes(elem);
71 cn1 += v / tempnp1(elem);
72 cn += v / tempn(elem);
73 }
74 int n_bord;
75
76 double cm = 0;
77 const IntTab& face_voisins = le_dom->face_voisins();
78 const DoubleVect& Surface = le_dom->face_surfaces();
79 // not the correct velocity, but attempting this approximation
80 const IntVect& orientation = le_dom->orientation();
81 for (n_bord = 0; n_bord < le_dom->nb_front_Cl(); n_bord++)
82 {
83 const Cond_lim_base& la_cl = le_dom_Cl->les_conditions_limites(n_bord).valeur();
84 if (sub_type(Dirichlet, la_cl))
85 {
86 const Dirichlet& diri = ref_cast(Dirichlet, la_cl);
87 const Front_VF& la_front_dis = ref_cast(Front_VF, la_cl.frontiere_dis());
88 int ndeb = la_front_dis.num_premiere_face();
89 int nfin = ndeb + la_front_dis.nb_faces();
90 for (int num_face = ndeb; num_face < nfin; num_face++)
91 {
92 int n0 = face_voisins(num_face, 0);
93 double S = Surface(num_face);
94 if (n0 == -1)
95 {
96 n0 = face_voisins(num_face, 1);
97 S *= -1;
98 }
99 cm += S / tempnp1(n0) * diri.val_imp(num_face - ndeb, orientation(num_face));
100 }
101 }
102
103 else if (sub_type(Neumann_sortie_libre, la_cl))
104 {
105 Cerr << la_cl.que_suis_je() << " is incompatible with the conservation_masse treatment for now" << finl;
106 abort();
107 }
108 }
109
110 // Optimization: combine 3 mp_sum into 1 collective call
111 double cnt = cn, cn1t = cn1, cmt = cm;
112 mp_sum_for_each(cnt, cn1t, cmt);
113 double Pt = Pth_n * cnt / cn1t / (1 + dt / cn1t * cmt);
114 return Pt;
115 }
116 Cerr << " Utilisez traitement conservation_masse ou constant " << finl;
117 abort();
118 // ODE treatment ???
119 int n_bord;
120 for (n_bord = 0; n_bord < le_dom->nb_front_Cl(); n_bord++)
121 {
122 const Cond_lim& la_cl = le_dom_Cl->les_conditions_limites(n_bord);
123 if (sub_type(Neumann_sortie_libre, la_cl.valeur()))
124 return Pth_n;
125
126 }
127 Cerr << " The code here is incorrect !!!!" << finl;
128 Cerr << " Blocking for now" << finl;
129 assert(0);
130 exit();
131 const DoubleTab& tab_vit = ref_cast(Navier_Stokes_std,le_fluide_->vitesse().equation()).vitesse().valeurs();
132 const DoubleTab& tempn = le_fluide_->inco_chaleur().passe(); //previous
133 const DoubleTab& tab_rho = le_fluide_->masse_volumique().valeurs(); //current
134
135 Cerr << "---EDO : Tnp1=" << tempnp1(0) << " Tn=" << tempn(0) << finl;
136
137 int elem, nb_elem = le_dom->nb_elem();
138 double V = 0; //mesure du domaine
139 double F = 0; //integrale du gradient de U
140 double S = 0; //second membre
141
142 //double Pth1 = le_fluide_->pression_th1();
143
144 double v;
145
146 const IntTab& elem_faces = le_dom->elem_faces();
147 DoubleTrav divU(tab_vit.dimension(0));
148 ref_cast(Navier_Stokes_std,le_fluide_->vitesse().equation()).operateur_divergence().calculer(tab_vit, divU);
149 DoubleTrav gradT(tab_vit.dimension(0));
150 DoubleTrav Tstar(tab_vit.dimension(0));
151 for (elem = 0; elem < nb_elem; elem++)
152 {
153 Tstar(elem) = .5 * (tempn(elem) + tempnp1(elem));
154 }
155 calculer_grad(Tstar, gradT);
156 DoubleTab u_gradT(nb_elem);
157 int f1, f2, i;
158 for (elem = 0; elem < nb_elem; elem++)
159 {
160 u_gradT(elem) = 0;
161 for (i = 0; i < dimension; i++)
162 {
163 f1 = elem_faces(elem, i);
164 f2 = elem_faces(elem, i + dimension);
165 //u_gradT(elem) += .25* (gradT(f1)+gradT(f2)) * (tab_vit(f1)+tab_vit(f2));
166 u_gradT(elem) += .5 * (gradT(f1) * tab_vit(f1) + gradT(f2) * tab_vit(f2));
167 }
168 }
169
170 for (elem = 0; elem < nb_elem; elem++)
171 {
172 v = le_dom->volumes(elem);
173 V += v;
174
175 S += v * tab_rho(elem) * ((tempnp1(elem) - tempn(elem)) / dt + u_gradT(elem));
176 }
177
178 // int nb_cond_lim = le_dom->nb_front_Cl();
179 int ndeb, nfin, face;
180 double norm;
181 //DoubleVect norme(dimension);
182 for (n_bord = 0; n_bord < le_dom->nb_front_Cl(); n_bord++)
183 {
184 const Cond_lim& la_cl = le_dom_Cl->les_conditions_limites(n_bord);
185 const Front_VF& frontiere_dis = ref_cast(Front_VF,la_cl->frontiere_dis());
186 ndeb = frontiere_dis.num_premiere_face();
187 nfin = ndeb + frontiere_dis.nb_faces();
188 //if (sub_type(Neumann_sortie_libre, la_cl.valeur()) || sub_type(Dirichlet_entree_fluide, la_cl.valeur())) {
189 for (face = ndeb; face < nfin; face++)
190 {
191 elem = le_dom->face_voisins(face, 0);
192 norm = le_dom->face_surfaces(face);
193 if (elem == -1)
194 {
195 elem = le_dom->face_voisins(face, 1);
196 norm *= -1;
197 }
198 //compute F=Sum(div(U))
199 F += tab_vit(face) * norm;
200 //}
201 }
202 }
203 const Loi_Etat_GP_QC& loi_ = ref_cast(Loi_Etat_GP_QC, le_fluide_->loi_etat().valeur());
204 S *= loi_.R();
205
206 double Pth = (1. / (V / dt + F / 2.)) * ((V / dt - F / 2.) * Pth_n + S);
207
208 Cerr << "Recomputed thermodynamic pressure = " << Pth << finl;
209
210 //return Pth1;
211 return Pth;
212}
213
215{
216 const int traitPth = le_fluide_->getTraitementPth();
217 if (traitPth == 2)
218 return; // nothing to do
219 else if (traitPth == 0)
220 {
221 for (int n_bord = 0; n_bord < le_dom->nb_front_Cl(); n_bord++)
222 {
223 const Cond_lim& la_cl = le_dom_Cl->les_conditions_limites(n_bord);
224 if (sub_type(Neumann_sortie_libre, la_cl.valeur()))
225 return; // nothing to do
226 }
227
228 Cerr << "EDO_Pression_th_VDF_Gaz_Parfait::" << __func__ << " not yet coded ! Call the 911 !!" << finl;
230 }
231 else
232 {
233 const DoubleTab& tempnp1 = le_fluide_->inco_chaleur().valeurs(); //current
234 const DoubleTab& tempn = le_fluide_->inco_chaleur().passe();
235 const double dt = le_fluide_->vitesse().equation().schema_temps().pas_de_temps();
236
237 double cn1 = 0., cn = 0., v = -123.;
238
239 for (int elem = 0; elem < le_dom->nb_elem(); elem++)
240 {
241 v = le_dom->volumes(elem);
242 cn1 += v / tempnp1(elem);
243 cn += v / tempn(elem);
244 }
245
246 double cm = 0.;
247 const IntTab& face_voisins = le_dom->face_voisins();
248 const DoubleVect& Surface = le_dom->face_surfaces();
249 // not the correct velocity, but attempting this approximation
250 const IntVect& orientation = le_dom->orientation();
251 for (int n_bord = 0; n_bord < le_dom->nb_front_Cl(); n_bord++)
252 {
253 const Cond_lim_base& la_cl = le_dom_Cl->les_conditions_limites(n_bord).valeur();
254 if (sub_type(Dirichlet, la_cl))
255 {
256 const Dirichlet& diri = ref_cast(Dirichlet, la_cl);
257 const Front_VF& la_front_dis = ref_cast(Front_VF, la_cl.frontiere_dis());
258 int ndeb = la_front_dis.num_premiere_face();
259 int nfin = ndeb + la_front_dis.nb_faces();
260 for (int num_face = ndeb; num_face < nfin; num_face++)
261 {
262 int n0 = face_voisins(num_face, 0);
263 double S = Surface(num_face);
264 if (n0 == -1)
265 {
266 n0 = face_voisins(num_face, 1);
267 S *= -1;
268 }
269 cm += S / tempnp1(n0) * diri.val_imp(num_face - ndeb, orientation(num_face));
270 }
271 }
272
273 else if (sub_type(Neumann_sortie_libre, la_cl))
274 {
275 Cerr << la_cl.que_suis_je() << " is incompatible with the conservation_masse treatment for now" << finl;
277 }
278 }
279
280 // Optimization: combine 3 mp_sum into 1 collective call
281 double cnt = cn, cn1t = cn1, cmt = cm;
282 mp_sum_for_each(cnt, cn1t, cmt);
283
284 for (int elem = 0; elem < le_dom->nb_elem(); elem++)
285 Pth_n(elem) = Pth_n(elem) * cnt / cn1t / (1. + dt / cn1t * cmt);
286 }
287}
class Cond_lim_base Base class for the hierarchy of classes that represent the different boundary con...
virtual Frontiere_dis_base & frontiere_dis()
Returns the discretized boundary to which the boundary conditions apply.
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
Dirichlet This class is the base class of the hierarchy of Dirichlet-type boundary conditions.
Definition Dirichlet.h:31
virtual double val_imp(int i) const
Returns the imposed value on the i-th component of the field at the boundary at the default time of c...
Definition Dirichlet.cpp:35
class EDO_Pression_th_VDF_Gaz_Parfait
double resoudre(double) override
Solves the ODE for the thermodynamic pressure.
class EDO_Pression_th_VDF This class represents the ODE for pressure associated with the
void calculer_grad(const DoubleTab &, DoubleTab &)
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
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
State law class for ideal gases in the quasi-compressible (QC) framework.
double R() const
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
Navier_Stokes_std This class carries the terms of the momentum equation.
virtual const Champ_Inc_base & vitesse() const
Neumann_sortie_libre This class represents an open boundary without imposed velocity.
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
static void mp_sum_for_each(T &arg1, T &arg2)
C++14 compatible mp_sum_for_each: combine multiple mp_sum calls into one collective operation Usage: ...
Definition Process.cpp:208
static void abort()
Abort routine for TRUST on a fatal error.
Definition Process.cpp:573
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
Base class for output streams.
Definition Sortie.h:52
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133