TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Aire_interfaciale.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 <Transport_turbulent_aire_interfaciale.h>
17#include <EcritureLectureSpecial.h>
18#include <Schema_Implicite_base.h>
19#include <Scalaire_impose_paroi.h>
20#include <Echange_global_impose.h>
21#include <Neumann_sortie_libre.h>
22#include <Op_Conv_negligeable.h>
23#include <Frontiere_dis_base.h>
24#include <Aire_interfaciale.h>
25#include <Navier_Stokes_std.h>
26#include <Champ_Uniforme.h>
27#include <Matrice_Morse.h>
28#include <Pb_Multiphase.h>
29#include <Neumann_paroi.h>
30#include <Discret_Thyd.h>
31#include <Domaine_VF.h>
32#include <TRUSTTrav.h>
33#include <EChaine.h>
34#include <Domaine.h>
35#include <Param.h>
36#include <Avanc.h>
37#include <Debog.h>
38#include <SETS.h>
39
40#include <EChaine.h>
41#include <Neumann_paroi.h>
42#include <Scalaire_impose_paroi.h>
43#include <Echange_global_impose.h>
44#include <Milieu_composite.h>
45#include <math.h>
46
47
48Implemente_instanciable(Aire_interfaciale,"Aire_interfaciale|Interfacial_area",Convection_Diffusion_std);
49
51{
53}
54
56{
57 terme_diffusif.associer_eqn(*this);
58 terme_convectif.associer_eqn(*this);
59
60 assert(l_inco_ch_);
61 assert(le_fluide_);
63
64 terme_convectif.set_fichier("Convection_interfacial_area");
65 terme_convectif.set_description((Nom)"interfacial area transfer rate=Integral(-A*u*ndS) [kg] if SI units used");
66
67 Pb_Multiphase *pbm = sub_type(Pb_Multiphase, probleme()) ? &ref_cast(Pb_Multiphase, probleme()) : nullptr;
68
69 if (!pbm || pbm->nb_phases() == 1) Process::exit(que_suis_je() + " : not needed for single-phase flow!");
70
71 for (int n = 0; n < pbm->nb_phases(); n++) //recherche de n_l, n_g : phase {liquide,gaz}_continu en priorite
72 {
73 if (pbm->nom_phase(n).debute_par("liquide") && (n_l < 0 || pbm->nom_phase(n).finit_par("continu"))) n_l = n;
74 if (( pbm->nom_phase(n).finit_par("group1"))) n_g1 = n;
75 if (( pbm->nom_phase(n).finit_par("group2"))) n_g2 = n;
76 }
77 if (n_l < 0) Process::exit(que_suis_je() + " : liquid phase not found!");
78
79 if (pbm->has_correlation("diametre_bulles")) Process::exit(que_suis_je() + " : the interfacial area equation sets bubble diameter, there cannot be an exterior correlation !");
80
81 if (pbm)
82 {
83 const QDM_Multiphase& qdm = ref_cast(QDM_Multiphase, pbm->equation_qdm());
84
85 if (discretisation().is_vdf())
86 {
87 Cerr << "The turbulent operator of Aire_interfaciale equation is not yet ported to the VDF discretization ..." << finl;
89 }
90
91 if (qdm.operateur_diff()->is_turb() && terme_diffusif->is_turb())
92 {
93 terme_diffusif.set_fichier("Diffusion_interfacial_area");
94 terme_diffusif.set_description((Nom)"interfacial area transfer rate=Integral(mu_t/0.405*grad(ai)*ndS) [W] if SI units used");
95 has_diff_turb_ = true;
96
97 /*
98 * Teste si la corr Transport_turbulent_aire_interfaciale ...
99 */
100 if (terme_diffusif->correlation_viscosite_turbulente())
101 {
102 if (!sub_type(Transport_turbulent_aire_interfaciale, *terme_diffusif->correlation_viscosite_turbulente()))
103 {
104 Cerr << "Error in you Aire_interfaciale::readOn !! \n You can only use the Transport_turbulent_aire_interfaciale correlation for the diffusion operator !" << finl;
106 }
107 }
108 }
109
110 }
111
112 return is;
113}
114
116{
117 const Fluide_base& un_fluide = ref_cast(Fluide_base,un_milieu);
118 associer_fluide(un_fluide);
119}
120
122{
123 int nb_valeurs_temp = schema_temps().nb_valeurs_temporelles();
124 double temps = schema_temps().temps_courant();
125 const Discret_Thyd& dis=ref_cast(Discret_Thyd, discretisation());
126 int N = ref_cast(Pb_Multiphase, probleme()).nb_phases();
127
128 Cerr << "Interfacial area discretization" << finl;
129 //On utilise temperature pour la directive car discretisation identique
130 dis.discretiser_champ("temperature",domaine_dis(),"interfacial_area","m-1", N,nb_valeurs_temp,temps,l_inco_ch_);//une aire interfaciale par phase
131 l_inco_ch_->fixer_nature_du_champ(multi_scalaire);
132 l_inco_ch_->fixer_nom_compo(0, Nom("tau"));
133 champs_compris_.ajoute_champ(l_inco_ch_);
134
135 Cerr << "Bubble diameter discretization" << finl;
136 //On utilise temperature pour la directive car discretisation identique
137 Noms noms(N), unites(N);
138 noms[0] = "diametre_bulles";
139 unites[0] = "m";
140 Motcle typeChamp = "champ_elem" ;
142 dis.discretiser_champ(typeChamp, z, multi_scalaire, noms , unites, N, 0, diametre_bulles_);
143
144 champs_compris_.ajoute_champ(diametre_bulles_);
145
147 Cerr << "Echelle_temporelle_turbulente::discretiser() ok" << finl;
148}
149
151{
152 return le_fluide_.valeur();
153}
154
156{
157 return le_fluide_.valeur();
158}
159
161{
162 return Equation_base::impr(os);
163}
164
166{
167 static Motcle mot("Interfacial_area");
168 return mot;
169}
170
172{
173 le_fluide_ = un_fluide;
174}
175
177{
178 if (!has_diff_turb_)
179 {
180 if (i)
181 {
182 Cerr << "Error for Aire_interfaciale::operateur(int i)" << finl;
183 Cerr << "Aire_interfaciale has " << nombre_d_operateurs() <<" operators "<<finl;
184 Cerr << "and you are trying to access the " << i <<" th one."<< finl;
185 exit();
186 }
187
188 return terme_convectif;
189 }
190
191 switch(i)
192 {
193 case 0:
194 return terme_diffusif;
195 case 1:
196 return terme_convectif;
197 default :
198 Cerr << "Error for Aire_interfaciale::operateur(int i)" << finl;
199 Cerr << "Aire_interfaciale has " << nombre_d_operateurs() <<" operators "<<finl;
200 Cerr << "and you are trying to access the " << i <<" th one."<< finl;
201 exit();
202 }
203 // Pour les compilos!!
204 return terme_diffusif;
205}
206
208{
209 if (!has_diff_turb_)
210 {
211 if (i)
212 {
213 Cerr << "Error for Aire_interfaciale::operateur(int i)" << finl;
214 Cerr << "Aire_interfaciale has " << nombre_d_operateurs() <<" operators "<<finl;
215 Cerr << "and you are trying to access the " << i <<" th one."<< finl;
216 exit();
217 }
218
219 return terme_convectif;
220 }
221
222 switch(i)
223 {
224 case 0:
225 return terme_diffusif;
226 case 1:
227 return terme_convectif;
228 default :
229 Cerr << "Error for Aire_interfaciale::operateur(int i)" << finl;
230 Cerr << "Aire_interfaciale has " << nombre_d_operateurs() <<" operators "<<finl;
231 Cerr << "and you are trying to access the " << i <<" th one."<< finl;
232 exit();
233 }
234 // Pour les compilos!!
235 return terme_diffusif;
236}
237
239{
241
242 int i, n, N = ref_cast(Pb_Multiphase, probleme()).nb_phases(), Np = probleme().get_champ("pression").valeurs().line_size();
243 const Pb_Multiphase& pbm = ref_cast(Pb_Multiphase, probleme());
244
245 const DoubleTab& alpha = probleme().get_champ("alpha").passe();
246 const DoubleTab& a_i = inconnue().passe();
247 const DoubleTab& rho_p = milieu().masse_volumique().passe();
248 const DoubleTab& temp_p = pbm.equation_energie().inconnue().passe();
249 const DoubleTab& press_p = ref_cast(QDM_Multiphase,pbm.equation_qdm()).pression().passe();
250 DoubleTab& d_b = diametre_bulles_->valeurs();
251 double D_crit = 0.011;
252 int cR = (rho_p.dimension_tot(0) == 1);
253 const Milieu_composite& milc = ref_cast(Milieu_composite, milieu());
254
255 diametre_bulles_->mettre_a_jour(temps);
256
257
258 const double void_fraction_threshold = 1e-5; // small void fraction is ignored to avoid numerical problems with group 2
259 const double interfacial_area_threshold = 1e-5; //ai is replaced by this value if too small
260 const double min_diameter = 1e-5; // diameter is replaced by this value if too small
261 for (n = 0; n < N; n++)
262 {
263 for (i = 0; i < d_b.dimension_tot(0); i++)
264 {
265 if (n != n_l)
266 {
267 if (a_i(i, n)<=interfacial_area_threshold)
268 d_b(i, n) = min_diameter;
269 else
270 d_b(i, n) = std::max(min_diameter, 6 * alpha(i, n)/a_i(i, n) );
271 }
272
273 if ( 0. < n_g1 )
274 {
275 if(milc.has_interface(n_g1, n_l))
276 {
277 Interface_base& sat = milc.get_interface(n_l, n_g1);
278 D_crit = 4. * std::sqrt(sat.sigma(temp_p(i,n_l), press_p(i,n_l * (Np > 1))) / g / (rho_p(!cR * i, n_l)-rho_p(!cR * i, n_g1)));
279 }
280 else if (milc.has_saturation(n_g1, n_l))
281 {
282 Saturation_base& z_sat = milc.get_saturation(n_g1, n_l);
283 DoubleTab& sig = z_sat.get_sigma_tab();
284 D_crit = 4. * std::sqrt(sig(i) / g / (rho_p(!cR * i, n_l)-rho_p(!cR * i, n_g1)));
285 }
286 if (n==n_g1)
287 {
288 d_b(i, n_g1) = std::min(std::max(d_b(i, n_g1),min_diameter),D_crit);
289 }
290 if (n==n_g2)
291 {
292 d_b(i, n_g2) = (alpha(i, n_g2)>void_fraction_threshold) ? std::min(std::max(d_b(i, n_g2),D_crit),10.*D_crit) : D_crit ;
293 }
294 }
295 }
296 }
297
298 for (i = 0; i < d_b.dimension_tot(0); i++) d_b(i, n_l) = 0.;
299
300}
301
classe Aire_interfaciale Equation de transport de l'aire interfaciale
int nombre_d_operateurs() const override
const Milieu_base & milieu() const override
void mettre_a_jour(double temps) override
La valeur de l'inconnue sur le pas de temps a ete calculee.
void associer_fluide(const Fluide_base &)
void associer_milieu_base(const Milieu_base &) override
void discretiser() override
Discretise l'equation.
int impr(Sortie &os) const override
Imprime les operateurs de l'equation sur un flot de sortie, de facon inconditionnelle.
const Operateur & operateur(int) const override
const Champ_Inc_base & inconnue() const override
const Motcle & domaine_application() const override
Renvoie "indetermine" Navier_Stokes_standard par exemple surcharge cette methode.
DoubleTab & passe(int i=1) override
Renvoie les valeurs du champs a l'instant t-i.
virtual DoubleTab & valeurs()=0
virtual DoubleTab & passe(int i=1)
Definition Champ_Proto.h:50
classe Convection_Diffusion_std Cette classe est la base des equations modelisant le transport
classe Discret_Thyd Cette classe est la classe de base representant une discretisation
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_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
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 const Champ_Inc_base & inconnue() const =0
virtual void mettre_a_jour(double temps)
La valeur de l'inconnue sur le pas de temps a ete calculee.
virtual int impr(Sortie &os) const
Imprime les operateurs de l'equation sur un flot de sortie, de facon inconditionnelle.
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
virtual void discretiser()
Discretise l'equation.
Champs_compris champs_compris_
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise associe a l'equation.
classe Fluide_base Cette classe represente un d'un fluide incompressible ainsi que
Definition Fluide_base.h:38
DoubleTab & get_sigma_tab()
double sigma(const double T, const double P) const
classe Milieu_base Cette classe est la base de la hierarchie des milieux (physiques)
Definition Milieu_base.h:50
virtual const Champ_base & masse_volumique() const
Renvoie la masse volumique du milieu.
Classe Milieu_composite Cette classe represente un fluide reel ainsi que.
bool has_interface(int k, int l) const
bool has_saturation(int k, int l) const
Interface_base & get_interface(int k, int l) const
Saturation_base & get_saturation(int k, int l) const
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
Operateur_Diff & operateur_diff()
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
virtual int finit_par(const char *const n) const
Definition Nom.cpp:324
virtual int debute_par(const char *const n) const
Definition Nom.cpp:319
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
friend class Sortie
Definition Objet_U.h:75
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
classe Operateur Classe generique de la hierarchie des operateurs.
Definition Operateur.h:39
classe Pb_Multiphase Cette classe represente un probleme de thermohydraulique multiphase de type "3*N...
virtual Equation_base & equation_qdm()
virtual Equation_base & equation_energie()
const Nom & nom_phase(int i) const
int nb_phases() const
const Champ_base & get_champ(const Motcle &nom) const override
int has_correlation(std::string nom_correlation) const
const Domaine_dis_base & domaine_dis() const
Renvoie le domaine discretise associe au probleme.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
classe QDM_Multiphase Cette classe porte les termes de l'equation de la dynamique
double temps_courant() const
Renvoie le temps courant.
virtual int nb_valeurs_temporelles() const =0
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
int line_size() const
Definition TRUSTVect.tpp:67