TRUST 1.9.8
HPC thermohydraulic platform
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 Resoud l'EDO
34 *
35 * @param (double Pth_n) La pression a l'etape precedente
36 * @return (double) La nouvelle valeur de la pression
37 */
39{
40 int traitPth = le_fluide_->getTraitementPth();
41 const DoubleTab& tempnp1 = le_fluide_->inco_chaleur().valeurs(); //actuel
42 if (traitPth == 0)
43 {
44 Cerr << "on choisit le traitement " << 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 << "trait cst" << 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 // ce n'est pas la bonne vitesse mais on essaye
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() << " est incompatible avec le traitement conservation_masse pour l'instant" << 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 // traitement edo ???
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 << " Le codage ici est faux !!!!" << finl;
128 Cerr << " Pour l'instant on bloque" << 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(); //passe
133 const DoubleTab& tab_rho = le_fluide_->masse_volumique().valeurs(); //actuel
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 //calcul de F=Som(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 << "Pression thermo recalculee = " << 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; // rien a faire
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; // rien a faire
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(); //actuel
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 // ce n'est pas la bonne vitesse mais on essaye
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() << " est incompatible avec le traitement conservation_masse pour l'instant" << 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}
classe Cond_lim_base Classe de base pour la hierarchie des classes qui representent les differentes c...
virtual Frontiere_dis_base & frontiere_dis()
Renvoie la frontiere discretisee a laquelle les conditions aux limites s'appliquent.
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
Definition Dirichlet.h:31
virtual double val_imp(int i) const
Renvoie la valeur imposee sur la i-eme composante du champ a la frontiere au temps par defaut du cham...
Definition Dirichlet.cpp:35
classe EDO_Pression_th_VDF_Gaz_Parfait Cette classe represente l'EDO sur la pression associee au sche...
double resoudre(double) override
Resoud l'EDO.
classe EDO_Pression_th_VDF Cette classe represente l'EDO sur la pression associee au schema de
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
classe Loi_Etat_GP_QC Cette classe represente la loi d'etat pour les gaz parfaits.
double R() const
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
classe Navier_Stokes_std Cette classe porte les termes de l'equation de la dynamique
virtual const Champ_Inc_base & vitesse() const
classe Neumann_sortie_libre Cette classe represente une frontiere ouverte sans vitesse imposee
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
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:207
static void abort()
Routine de sortie de Trio-U sur une erreur abort().
Definition Process.cpp:570
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133