TrioCFD 1.9.9_beta
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++) // search for n_l, n_g: {liquid,gas}_continuous phase in priority
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 // Use "temperature" directive as the discretization is identical
130 dis.discretiser_champ("temperature",domaine_dis(),"interfacial_area","m-1", N,nb_valeurs_temp,temps,l_inco_ch_);//one interfacial area per 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 // Use "temperature" directive as the discretization is identical
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 // For the compilers!!
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 // For the compilers!!
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
Transport equation for the interfacial area.
int nombre_d_operateurs() const override
const Milieu_base & milieu() const override
void mettre_a_jour(double temps) override
The value of the unknown at the time step has been calculated.
void associer_fluide(const Fluide_base &)
void associer_milieu_base(const Milieu_base &) override
void discretiser() override
Discretizes the equation.
int impr(Sortie &os) const override
Prints the equation operators to an output stream, unconditionally.
const Operateur & operateur(int) const override
const Champ_Inc_base & inconnue() const override
const Motcle & domaine_application() const override
Returns "indeterminate" Navier_Stokes_standard for example overrides this method.
DoubleTab & passe(int i=1) override
Returns field values at instant t-i.
virtual DoubleTab & valeurs()=0
virtual DoubleTab & passe(int i=1)
Definition Champ_Proto.h:50
Convection_Diffusion_std This class is the base for equations modelling the transport.
class Discret_Thyd This class is the base class representing a discretization
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_dis_base This class is the base of the hierarchy of discretized domains.
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 const Champ_Inc_base & inconnue() const =0
virtual void mettre_a_jour(double temps)
The value of the unknown at the time step has been calculated.
virtual int impr(Sortie &os) const
Prints the equation operators to an output stream, unconditionally.
Probleme_base & probleme()
Returns the problem associated with the equation.
Schema_Temps_base & schema_temps()
Returns the time scheme associated with the equation.
virtual void discretiser()
Discretizes the equation.
Champs_compris champs_compris_
Domaine_dis_base & domaine_dis()
Returns the discretized domain associated with the equation.
Base class for an incompressible fluid and its properties:
Definition Fluide_base.h:36
DoubleTab & get_sigma_tab()
double sigma(const double T, const double P) const
Milieu_base This class is the base of the (physical) medium hierarchy.
Definition Milieu_base.h:50
virtual const Champ_base & masse_volumique() const
Returns the mass density of the medium (const version).
Composite medium representing a multiphase fluid and its properties:
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
A character string (Nom) in uppercase.
Definition Motcle.h:26
Operateur_Diff & operateur_diff()
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
virtual int finit_par(const char *const n) const
Definition Nom.cpp:319
virtual int debute_par(const char *const n) const
Definition Nom.cpp:314
An array of character strings (VECT(Nom)).
Definition Noms.h:26
friend class Sortie
Definition Objet_U.h:70
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
class Operateur Generic class of the operator hierarchy.
Definition Operateur.h:39
Multiphase thermohydraulics problem of type "3*N equations":
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
Returns the discretized domain associated with the problem (const version).
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
Carries the terms of the momentum equation for multiphase flow without turbulence modelling.
double temps_courant() const
Returns the current time.
virtual int nb_valeurs_temporelles() const =0
Base class for output streams.
Definition Sortie.h:52
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
int line_size() const
Definition TRUSTVect.tpp:67