TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Rupture_bulles_1groupe_PolyMAC_MPFA.cpp
1/****************************************************************************
2* Copyright (c) 2021, 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 <Rupture_bulles_1groupe_PolyMAC_MPFA.h>
17#include <Pb_Multiphase.h>
18#include <Champ_Elem_PolyMAC_MPFA.h>
19#include <Milieu_composite.h>
20#include <Op_Diff_Turbulent_PolyMAC_MPFA_Face.h>
21#include <Viscosite_turbulente_base.h>
22#include <Matrix_tools.h>
23#include <Array_tools.h>
24#include <Rupture_bulles_1groupe_base.h>
25#include <Domaine_PolyMAC_MPFA.h>
26#include <Champ_Face_base.h>
27#include <cmath>
28#include <math.h>
29
30Implemente_instanciable(Rupture_bulles_1groupe_PolyMAC_MPFA, "Rupture_bulles_1groupe_elem_PolyMAC_MPFA", Source_base);
31
33{
34 return os;
35}
36
38{
39 Param param(que_suis_je());
40 param.ajouter("beta_k", &beta_k_);
41 param.lire_avec_accolades_depuis(is);
42
43
44 const Pb_Multiphase *pbm = sub_type(Pb_Multiphase, equation().probleme()) ? &ref_cast(Pb_Multiphase, equation().probleme()) : nullptr;
45
46 if (!pbm || pbm->nb_phases() == 1)
47 Process::exit(que_suis_je() + " : not needed for single-phase flow!");
48
49 for (int n = 0; n < pbm->nb_phases(); n++) //recherche de n_l, n_g : phase {liquide,gaz}_continu en priorite
50 if (pbm->nom_phase(n).debute_par("liquide")
51 && (n_l < 0 || pbm->nom_phase(n).finit_par("continu")))
52 n_l = n;
53
54 if (n_l < 0)
55 Process::exit(que_suis_je() + " : liquid phase not found!");
56
57 if (pbm->has_correlation("Rupture_bulles_1groupe"))
58 correlation_ = pbm->get_correlation("Rupture_bulles_1groupe"); //correlation fournie par le bloc correlation
59 else
60 Correlation_base::typer_lire_correlation(correlation_, *pbm, "Rupture_bulles_1groupe", is); //sinon -> on la lit
61
62 return is;
63}
64
65void Rupture_bulles_1groupe_PolyMAC_MPFA::dimensionner_blocs(matrices_t matrices, const tabs_t& semi_impl) const
66{
67 const Domaine_PolyMAC_MPFA& domaine = ref_cast(Domaine_PolyMAC_MPFA, equation().domaine_dis());
68 const int ne = domaine.nb_elem();
69 const int ne_tot = domaine.nb_elem_tot();
70 const int N = equation().inconnue().valeurs().line_size();
71
72 for (auto &&n_m : matrices)
73 if (n_m.first == "alpha" || n_m.first == "k" || n_m.first == "tau" || n_m.first == "omega" || n_m.first == "interfacial_area")
74 {
75 Matrice_Morse& mat = *n_m.second, mat2;
76 const DoubleTab& dep = equation().probleme().get_champ(n_m.first.c_str()).valeurs();
77 const int nc = dep.dimension_tot(0);
78 const int M = dep.line_size();
79 Stencil sten(0, 2);
80
81 if (n_m.first == "alpha")
82 for (int e = 0; e < ne; e++)
83 for (int n = 0; n < N; n++)
84 {
85 sten.append_line(N * e + n, N * e + n_l);
86 if (n != n_l)
87 sten.append_line(N * e + n, N * e + n);
88 }
89 if (n_m.first == "interfacial_area" ) // N <= M
90 for (int e = 0; e < ne; e++)
91 for (int n = 0; n < N; n++) sten.append_line(N * e + n, M * e + n);
92 if (n_m.first == "k" || n_m.first == "tau" || n_m.first == "omega") // N <= M
93 for (int e = 0; e < ne; e++)
94 for (int n = 0; n < N; n++)
95 sten.append_line(N * e + n, M * e +n_l);
96
97 Matrix_tools::allocate_morse_matrix(N * ne_tot, M * nc, sten, mat2);
98 mat.nb_colonnes() ? mat += mat2 : mat = mat2;
99 }
100}
101
102void Rupture_bulles_1groupe_PolyMAC_MPFA::ajouter_blocs(matrices_t matrices, DoubleTab& secmem, const tabs_t& semi_impl) const
103{
104 const Domaine_PolyMAC_MPFA& domaine = ref_cast(Domaine_PolyMAC_MPFA, equation().domaine_dis());
105 const DoubleVect& pe = equation().milieu().porosite_elem(), &ve = domaine.volumes();
106 const Pb_Multiphase& pbm = ref_cast(Pb_Multiphase, equation().probleme());
107 const DoubleTab& inco = equation().inconnue().valeurs();
108 const DoubleTab& d_bulles = equation().probleme().get_champ("diametre_bulles").passe();
109 const DoubleTab& alpha = pbm.equation_masse().inconnue().valeurs();
110 const DoubleTab& alpha_p = pbm.equation_masse().inconnue().passe();
111 const DoubleTab& press_p = ref_cast(QDM_Multiphase, pbm.equation_qdm()).pression().passe();
112 const DoubleTab& temp_p = pbm.equation_energie().inconnue().passe();
113 const DoubleTab& rho_p = equation().milieu().masse_volumique().passe();
114 const DoubleTab& nu_p = equation().probleme().get_champ("viscosite_cinematique").passe();
115 const DoubleTab *tab_k_p = equation().probleme().has_champ("k") ? &equation().probleme().get_champ("k").passe() : nullptr;
116 const DoubleTab *tab_k = equation().probleme().has_champ("k") ? &equation().probleme().get_champ("k").valeurs() : nullptr;
117 const DoubleTab *tau = equation().probleme().has_champ("tau") ? &equation().probleme().get_champ("tau").valeurs() : nullptr;
118 const DoubleTab *omega = equation().probleme().has_champ("omega") ? &equation().probleme().get_champ("omega").valeurs() : nullptr ;
119
120 const Milieu_composite& milc = ref_cast(Milieu_composite, equation().milieu());
121 const int N = pbm.nb_phases();
122 const int Nk = (tab_k) ? (*tab_k).line_size() : -1;
123 const int Np = equation().probleme().get_champ("pression").valeurs().line_size();
124
125 // Models use epsilon but with omega and tau we induce new variations of tau/omega and k
126 std::string Type_diss = "other"; // omega, tau or other dissipation
127 if (tau)
128 Type_diss = "tau";
129 else if (omega)
130 Type_diss = "omega";
131
132 DoubleTrav epsilon(alpha);
133 const Op_Diff_Turbulent_PolyMAC_MPFA_Face& op_diff = ref_cast(Op_Diff_Turbulent_PolyMAC_MPFA_Face, equation().probleme().equation(0).operateur(0).l_op_base());
134 const Viscosite_turbulente_base& visc_turb = ref_cast(Viscosite_turbulente_base, op_diff.correlation());
135 visc_turb.eps(epsilon); // Epsilon is in the past
136 const double limiter = visc_turb.limiteur();
137 const double dh = 0;
138
139 Matrice_Morse *Ma = matrices.count("alpha") ? matrices.at("alpha") : nullptr;
140 Matrice_Morse *Mk = matrices.count("k") ? matrices.at("k") : nullptr;
141 Matrice_Morse *Mtau = matrices.count("tau") ? matrices.at("tau") : nullptr;
142 Matrice_Morse *Momega = matrices.count("omega") ? matrices.at("omega") : nullptr;
143 Matrice_Morse *Mai = matrices.count("interfacial_area") ? matrices.at("interfacial_area") : nullptr;
144
145 const int cR = (rho_p.dimension_tot(0) == 1);
146 const int cM = (nu_p.dimension_tot(0) == 1);
147 const int D = dimension;
148
149 DoubleTrav a_l(N), p_l(N), T_l(N), rho_l(N), nu_l(N), sigma_l(N,N), dv(N, N), d_bulles_l(N), eps_l(Nk), k_l(Nk), coeff(N, N); //arguments pour coeff
150 const Rupture_bulles_1groupe_base& correlation_rupt = ref_cast(Rupture_bulles_1groupe_base, correlation_.valeur());
151
152 // fill velocity at elem tab
153 DoubleTab pvit_elem(0, N * D);
154 domaine.domaine().creer_tableau_elements(pvit_elem);
155 const Champ_Face_base& ch_vit = ref_cast(Champ_Face_base,ref_cast(Pb_Multiphase, equation().probleme()).equation_qdm().inconnue());
156 ch_vit.get_elem_vector_field(pvit_elem);
157
158 const double fac_sec = 1.e4 ; // numerical security
159 const double alpha_min = 1.e-3 ; // to avoid numerical problems
160
161 /* elements */
162 for (int e = 0; e < domaine.nb_elem(); e++)
163 {
164
165 for (int n = 0; n < N; n++)
166 {
167 a_l(n) = alpha(e, n); // to further implicit the source term
168 p_l(n) = press_p(e, n * (Np > 1));
169 T_l(n) = temp_p(e, n);
170 rho_l(n) = rho_p(!cR * e, n);
171 nu_l(n) = nu_p(!cM * e, n);
172 for (int k = 0; k < N; k++)
173 if(milc.has_interface(n, k))
174 {
175 Interface_base& sat = milc.get_interface(n, k);
176 sigma_l(n, k) = sat.sigma(temp_p(e,n), press_p(e,n * (Np > 1)));
177 }
178 d_bulles_l(n) = d_bulles(e,n);
179 }
180
181 for (int n = 0; n < Nk; n++)
182 {
183 eps_l(n) =epsilon(e, n) ;
184 k_l(n) = (tab_k_p) ? (*tab_k_p)(e,n) : 0;
185 }
186
187 dv = 0;
188 for (int d = 0; d < D; d++)
189 for (int n = 0; n < N; n++)
190 for (int k = 0; k < N; k++)
191 dv(n, k) += (pvit_elem(e, N * d + n) - ((n!=k) ? pvit_elem(e, N * d + k) : 0) ) * (pvit_elem(e, N * d + n) - ((n!=k) ? pvit_elem(e, N * d + k) : 0) ); // nv(n,n) = ||v(n)||, nv(n, k!=n) = ||v(n)-v(k)||
192
193 for (int n = 0; n < N; n++)
194 for (int k = 0; k < N ; k++)
195 dv(n, k) = sqrt(dv(n, k)) ;
196
197 // Get correlations-------------------------------------------------------------------------------------------------------------------------------------------------------
198 correlation_rupt.coefficient(a_l, p_l, T_l, rho_l, nu_l, sigma_l, dh, dv, d_bulles_l, eps_l, k_l, coeff); // Semi-Explicit coeff : alpha is implicit
199
200 for (int k = 0; k < N ; k++)
201 {
202 double eps_valeurs {0.0};
203
204 if (Type_diss == "tau")
205 eps_valeurs = beta_k_ * ((*tab_k)(e, n_l)>1.e-8 ? (*tab_k)(e, n_l)*(*tab_k)(e, n_l)/ std::max((*tab_k)(e, n_l) * (*tau)(e, n_l), limiter * nu_p(e, n_l)) : 0 );
206 else if (Type_diss == "omega")
207 eps_valeurs = beta_k_ * ((*tab_k)(e, n_l)*(*omega)(e, n_l)) ;
208 else
209 eps_valeurs = epsilon(e, n_l);
210
211 // Recuring functions for source terms
212
213 const double cbrt_6 = std::cbrt(6.);
214 const double factor_tmp = M_PI /( 3. * cbrt_6 * cbrt_6 * cbrt_6 * cbrt_6 * cbrt_6 );
215 const double fac = (alpha(e, k)>alpha_min) ? pe(e) * ve(e) * factor_tmp * coeff(k, n_l) : 0. ;
216 const double dalpha_fac = (alpha(e, k)>alpha_min) ? pe(e) * ve(e) * factor_tmp * coeff(n_l, k) : 0.;
217 const double ai = std::max(inco(e, k), 0.) ; //security inco negative
218 const double eps_1_over3 = std::cbrt(eps_valeurs) ;
219 const double ai_5_over3 = std::cbrt(ai) * std::cbrt(ai) * std::cbrt(ai) * std::cbrt(ai) * std::cbrt(ai) ;
220
221 const double cbrt_alpha_ek = std::cbrt(alpha(e, k));
222 const double one_overalpha_2_over3 = (alpha(e, k) > alpha_min) ? 1./std::min(cbrt_alpha_ek * cbrt_alpha_ek, fac_sec) :0. ;
223 const double one_overalpha_5_over3 = (alpha(e, k) > alpha_min) ? 1./std::min(cbrt_alpha_ek * cbrt_alpha_ek * cbrt_alpha_ek * cbrt_alpha_ek * cbrt_alpha_ek, fac_sec) : 0.;
224
225 // Fill the matrix-------------------------------------------------------------------------------------------------------------------------------------------------------------
226
227 secmem(e , k) += (fac > 0. ) ? fac * one_overalpha_2_over3 * alpha_p(e, n_l) * ai_5_over3 * eps_1_over3 : 0. ;// (alpha, ai, epsilon) implicit dependance
228
229 if (Ma)//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
230 (*Ma)(N * e + k , N * e + k) -= (fac > 0. ) ? fac * -2./3.* one_overalpha_5_over3 * alpha_p(e, n_l) * ai_5_over3 * eps_1_over3 + dalpha_fac * one_overalpha_2_over3 * alpha_p(e, n_l) * ai_5_over3 * eps_1_over3 : 0. ;
231
232 if (Mai)//----------------------------------------------------------------------------------------------------------------------------------------------------------------------
233 (*Mai)(N * e + k , N * e + k) -= (fac > 0. ) ? fac * one_overalpha_2_over3 * alpha_p(e, n_l) * 5./3. * std::cbrt(ai) * std::cbrt(ai) * eps_1_over3 : 0. ;
234
235 // Turbulent dissipation
236 if (Type_diss == "tau")
237 {
238 if ((*tab_k)(e, n_l) * (*tau)(e, n_l) > limiter * nu_p(e, n_l)) // derivative according to k due to epsilon
239 {
240 if (Mk)
241 (*Mk)(N * e + k, Nk * e + n_l) -= (fac > 0. ) ? fac * one_overalpha_2_over3 * alpha_p(e, n_l) * ai_5_over3 * 1./3. * std::cbrt(beta_k_) / std::min(std::cbrt((*tab_k)(e, n_l)) * std::cbrt((*tab_k)(e, n_l)),fac_sec) / std::min(std::cbrt((*tau)(e, n_l)),fac_sec) : 0.;
242
243 if (Mtau)
244 (*Mtau)(N * e + k, Nk * e + n_l) -= (fac > 0. ) ? fac * one_overalpha_2_over3 * alpha_p(e, n_l) * ai_5_over3 *-1./3. * std::cbrt(beta_k_) * std::cbrt((*tab_k)(e, n_l)) / std::min(std::cbrt((*tau)(e, n_l)) * std::cbrt((*tau)(e, n_l)) * std::cbrt((*tau)(e, n_l)) * std::cbrt((*tau)(e, n_l)),fac_sec) : 0. ;
245 }
246
247 else
248 {
249 if (Mk)//--------------------------------------------------------------------------------------------------------------------------------------------------------
250 (*Mk)(N * e + k, Nk * e + n_l) -= (fac > 0. ) ? fac * one_overalpha_2_over3 * alpha_p(e, n_l) * ai_5_over3 * 1./3. * std::cbrt(beta_k_) / std::min(std::cbrt((*tab_k)(e, n_l)),fac_sec) / std::min(std::cbrt(limiter * nu_p(e, n_l)),fac_sec) : 0.;
251 }
252 }
253 if (Type_diss == "omega")
254 {
255 if (Momega)
256 (*Momega)(N * e + k , Nk * e + n_l) -= (fac > 0. ) ? fac * one_overalpha_2_over3 * alpha_p(e, n_l) * ai_5_over3 * 1./3. * std::cbrt(beta_k_) * std::cbrt((*tab_k)(e, n_l)) / std::min(std::cbrt((*omega)(e, n_l)) * std::cbrt((*omega)(e, n_l)),fac_sec) : 0.;
257
258 if (Mk)
259 (*Mk)(N * e + k , Nk * e + n_l) -= (fac > 0. ) ? fac * one_overalpha_2_over3 * alpha_p(e, n_l) * ai_5_over3 * 1./3. * std::cbrt(beta_k_) / std::min(std::cbrt((*tab_k)(e, n_l)) * std::cbrt((*tab_k)(e, n_l)) ,fac_sec) * std::cbrt((*omega)(e, n_l)) : 0.;
260 }
261
262 }
263 }
264}
virtual DoubleTab & get_elem_vector_field(DoubleTab &, bool passe=false) const
DoubleTab & passe(int i=1) override
Renvoie les valeurs du champs a l'instant t-i.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual DoubleTab & valeurs()=0
virtual DoubleTab & passe(int i=1)
Definition Champ_Proto.h:50
static void typer_lire_correlation(OWN_PTR(Correlation_base)&, const Probleme_base &, const Nom &, Entree &)
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual const Milieu_base & milieu() const =0
virtual const Champ_Inc_base & inconnue() const =0
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
double sigma(const double T, const double P) const
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
int nb_colonnes() const override
Return local number of columns (=size on the current proc).
static void allocate_morse_matrix(const int nb_lines, const int nb_columns, const Stencil &stencil, Matrice_Morse &matrix, const bool &attach_stencil_to_matrix=false)
DoubleVect & porosite_elem()
Definition Milieu_base.h:58
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
Interface_base & get_interface(int k, int l) const
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
virtual int debute_par(const char *const n) const
Definition Nom.cpp:319
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
: class Op_Diff_Turbulent_PolyMAC_MPFA_Face
const Correlation_base & correlation() const
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
virtual Equation_base & equation_masse()
bool has_champ(const Motcle &nom, OBS_PTR(Champ_base) &ref_champ) const override
const Champ_base & get_champ(const Motcle &nom) const override
int has_correlation(std::string nom_correlation) const
const Correlation_base & get_correlation(std::string nom_correlation) const
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
classe Rupture_bulles_1groupe_PolyMAC_MPFA
void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl={}) const override
void dimensionner_blocs(matrices_t matrices, const tabs_t &semi_impl={}) const override
virtual void coefficient(const DoubleTab &alpha, const DoubleTab &p, const DoubleTab &T, const DoubleTab &rho, const DoubleTab &nu, const DoubleTab &sigma, double Dh, const DoubleTab &ndv, const DoubleTab &d_bulles, const DoubleTab &eps, const DoubleTab &k_turb, DoubleTab &coeff) const =0
Classe de base des flux de sortie.
Definition Sortie.h:52
classe Source_base Un objet Source_base est un terme apparaissant au second membre d'une
Definition Source_base.h:42
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
void append_line(_TYPE_)
Definition TRUSTTab.tpp:213
int line_size() const
Definition TRUSTVect.tpp:67
classe Viscosite_turbulente_base correlations de viscosite turbulente decrivant le tenseur de Reynold...
virtual void eps(DoubleTab &eps) const =0