TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Dispersion_bulles_PolyMAC_MPFA.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 <Op_Diff_Turbulent_PolyMAC_MPFA_Face.h>
17#include <Dispersion_bulles_PolyMAC_MPFA.h>
18#include <Viscosite_turbulente_base.h>
19#include <Dispersion_bulles_base.h>
20#include <Champ_Face_PolyMAC_MPFA.h>
21#include <Champ_Elem_PolyMAC_MPFA.h>
22#include <Milieu_composite.h>
23#include <Pb_Multiphase.h>
24#include <Neumann_paroi.h>
25
26Implemente_instanciable(Dispersion_bulles_PolyMAC_MPFA,"Dispersion_bulles_Face_PolyMAC_MPFA", Source_Dispersion_bulles_base);
27
29
31{
33 if sub_type(Op_Diff_Turbulent_PolyMAC_MPFA_Face, equation().operateur(0).l_op_base()) is_turb = 1;
34 return is;
35}
36
38{
39 const Champ_Face_PolyMAC_MPFA& ch = ref_cast(Champ_Face_PolyMAC_MPFA, equation().inconnue());
40 const Domaine_PolyMAC_MPFA& domaine = ref_cast(Domaine_PolyMAC_MPFA, equation().domaine_dis());
41 const DoubleTab& inco = ch.valeurs();
42
43 int i, j, e, k, l, N = inco.line_size(), d, db, D = dimension, nf_tot = domaine.nb_faces_tot();
44
45 /* elements */
46 for (e = 0, i = nf_tot; e < domaine.nb_elem_tot(); e++)
47 for (d = 0; d < D; d++, i++)
48 for (db = 0, j = nf_tot + D * e; db < D; db++, j++)
49 for (k = 0; k < N; k++)
50 for (l = 0; l < N; l++) stencil.append_line(N * i + k, N * j + l);
51}
52
53void Dispersion_bulles_PolyMAC_MPFA::ajouter_blocs(matrices_t matrices, DoubleTab& secmem, const tabs_t& semi_impl) const
54{
55 const Pb_Multiphase& pbm = ref_cast(Pb_Multiphase, equation().probleme());
56 const bool res_en_T = pbm.resolution_en_T();
57 if (!res_en_T) Process::exit("Dispersion_bulles_PolyMAC_MPFA::ajouter_blocs NOT YET PORTED TO ENTHALPY EQUATION ! TODO FIXME !!");
58
59 const Champ_Face_PolyMAC_MPFA& ch = ref_cast(Champ_Face_PolyMAC_MPFA, equation().inconnue());
60 const Domaine_PolyMAC_MPFA& domaine = ref_cast(Domaine_PolyMAC_MPFA, equation().domaine_dis());
61 const IntTab& f_e = domaine.face_voisins(), &fcl = ch.fcl(), &e_f = domaine.elem_faces();
62 const DoubleVect& pe = equation().milieu().porosite_elem(), &pf = equation().milieu().porosite_face(), &ve = domaine.volumes(), &vf = domaine.volumes_entrelaces(), &fs = domaine.face_surfaces();
63 const DoubleTab& vf_dir = domaine.volumes_entrelaces_dir(), &xp = domaine.xp(), &xv = domaine.xv();
64 const DoubleTab& pvit = ch.passe(),
65 &alpha = pbm.equation_masse().inconnue().passe(),
66 &press = ref_cast(QDM_Multiphase, pbm.equation_qdm()).pression().passe(),
67 &temp = pbm.equation_energie().inconnue().passe(),
68 &rho = equation().milieu().masse_volumique().passe(),
69 &mu = ref_cast(Fluide_base, equation().milieu()).viscosite_dynamique().passe();
70 const Milieu_composite& milc = ref_cast(Milieu_composite, equation().milieu());
71
72 DoubleTab const * d_bulles = (equation().probleme().has_champ("diametre_bulles")) ? &equation().probleme().get_champ("diametre_bulles").valeurs() : nullptr ;
73 DoubleTab const * k_turb = (equation().probleme().has_champ("k")) ? &equation().probleme().get_champ("k").passe() : nullptr ;
74 DoubleTab const * k_WIT = (equation().probleme().has_champ("k_WIT")) ? &equation().probleme().get_champ("k_WIT").passe() : nullptr ;
75
76 int N = pvit.line_size() ,
77 Np = press.line_size(),
78 D = dimension,
79 nf_tot = domaine.nb_faces_tot(),
80 nf = domaine.nb_faces(),
81 ne_tot = domaine.nb_elem_tot(),
82 cR = (rho.dimension_tot(0) == 1),
83 cM = (mu.dimension_tot(0) == 1),
84 Nk = (k_turb) ? (*k_turb).dimension(1) : 1;
85 DoubleTrav nut(domaine.nb_elem_tot(), N); //turbulent viscosity
86 if (is_turb) ref_cast(Viscosite_turbulente_base, ref_cast(Op_Diff_Turbulent_PolyMAC_MPFA_Face, equation().operateur(0).l_op_base()).correlation()).eddy_viscosity(nut); //filled by the correlation
87
88 // Input-output
89 const Dispersion_bulles_base& correlation_db = ref_cast(Dispersion_bulles_base, correlation_.valeur());
92 in.alpha.resize(N), in.T.resize(N), in.p.resize(N), in.rho.resize(N), in.mu.resize(N), in.sigma.resize(N*(N-1)/2), in.k_turb.resize(N), in.nut.resize(N), in.d_bulles.resize(N), in.nv.resize(N, N);
93 out.Ctd.resize(N, N);
94
95 /* calculation of the gradient of alpha at the face */
97 DoubleTrav grad_f_a(pvit);
98 ch_a.init_grad(0);
99 const IntTab& fg_d = ch_a.fgrad_d, &fg_e = ch_a.fgrad_e; // Tables used in domaine_PolyMAC_MPFA::fgrad for gradient computation
100 const DoubleTab& fg_w = ch_a.fgrad_w;
101 const Conds_lim& cls_a = ch_a.domaine_Cl_dis().les_conditions_limites(); // boundary conditions of the alpha field
102 const IntTab& fcl_a = ch_a.fcl(); // utility arrays for BCs: fcl(f, .) = (BC type, BC index, index within BC)
103
104 // And for the span methods of the Interface class to retrieve the surface tension
105 const int nb_max_sat = N * (N-1) /2; // yes !! arithmetic series !!
106 DoubleTrav Sigma_tab(ne_tot,nb_max_sat);
107
108 // fill the arrays ...
109 for (int k = 0; k < N; k++)
110 for (int l = k + 1; l < N; l++)
111 {
112 if (milc.has_saturation(k, l))
113 {
114 Saturation_base& z_sat = milc.get_saturation(k, l);
115 const int ind_trav = (k*(N-1)-(k-1)*(k)/2) + (l-k-1); // yes !! upper triangular matrix !
116 // retrieve sigma ...
117 const DoubleTab& sig = z_sat.get_sigma_tab();
118 // fill in the good case
119 for (int ii = 0; ii < ne_tot; ii++) Sigma_tab(ii, ind_trav) = sig(ii);
120 }
121 else if (milc.has_interface(k, l))
122 {
123 Interface_base& sat = milc.get_interface(k,l);
124 const int ind_trav = (k*(N-1)-(k-1)*(k)/2) + (l-k-1); // yes !! upper triangular matrix !
125 for (int i = 0 ; i<ne_tot ; i++) Sigma_tab(i,ind_trav) = res_en_T ? sat.sigma(temp(i,k),press(i,k * (Np > 1))) : sat.sigma_h(temp(i,k),press(i,k * (Np > 1))) ;
126 }
127 }
128
129 for (int n = 0; n < N; n++)
130 for (int f = 0; f < nf_tot; f++)
131 {
132 grad_f_a(f, n) = 0;
133 for (int j = fg_d(f); j < fg_d(f+1) ; j++)
134 {
135 int e = fg_e(j);
136 int f_bord;
137 if ( (f_bord = e-ne_tot) < 0) //element contribution
138 grad_f_a(f, n) += fg_w(j) * alpha(e, n);
139 else if (fcl_a(f_bord, 0) == 1 || fcl_a(f_bord, 0) == 2) //Echange_impose_base
140 grad_f_a(f, n) += fg_w(j) ? fg_w(j) * ref_cast(Echange_impose_base, cls_a[fcl_a(f_bord, 1)].valeur()).T_ext(fcl_a(f_bord, 2), n) : 0;
141 else if (fcl_a(f_bord, 0) == 4) //non-homogeneous Neumann
142 grad_f_a(f, n) += fg_w(j) ? fg_w(j) * ref_cast(Neumann_paroi , cls_a[fcl_a(f_bord, 1)].valeur()).flux_impose(fcl_a(f_bord, 2), n) : 0;
143 else if (fcl_a(f_bord, 0) == 6) // Dirichlet
144 grad_f_a(f, n) += fg_w(j) * ref_cast(Dirichlet, cls_a[fcl_a(f_bord, 1)].valeur()).val_imp(fcl_a(f_bord, 2), n);
145 }
146 }
147
148 /* Compute the gradient at elements */
149 for (int n = 0; n < N; n++)
150 for (int e = 0; e < ne_tot; e++)
151 for (int d = 0; d < D; d++)
152 {
153 grad_f_a(nf_tot + D*e +d, n) = 0 ;
154 for (int j = 0, f; j < e_f.dimension(1) && (f = e_f(e, j)) >= 0; j++)
155 grad_f_a(nf_tot + D*e +d, n) += (e == f_e(f, 0) ? 1 : -1) * fs(f) * (xv(f, d) - xp(e, d)) / ve(e) * grad_f_a(f, n);
156 }
157
158 /* faces */
159 for (int f = 0; f < nf; f++)
160 if (fcl(f, 0) < 2)
161 {
162 in.alpha=0., in.T=0., in.p=0, in.rho=0., in.mu=0., in.sigma=0., in.k_turb=0., in.nut=0., in.d_bulles=0., in.nv=0., in.k_WIT=0;
163 int e;
164 for (int c = 0; c < 2 && (e = f_e(f, c)) >= 0; c++)
165 {
166 for (int n = 0; n < N; n++)
167 {
168 in.alpha[n] += vf_dir(f, c)/vf(f) * alpha(e, n);
169 in.p[n] += vf_dir(f, c)/vf(f) * press(e, n * (Np > 1));
170 in.T[n] += vf_dir(f, c)/vf(f) * temp(e, n); // FIXME SI res_en_T
171 in.rho[n] += vf_dir(f, c)/vf(f) * rho(!cR * e, n);
172 in.mu[n] += vf_dir(f, c)/vf(f) * mu(!cM * e, n);
173 in.nut[n] += is_turb ? vf_dir(f, c)/vf(f) * nut(e,n) : 0;
174 in.d_bulles[n] += (d_bulles) ? vf_dir(f, c)/vf(f) * (*d_bulles)(e,n) : 0;
175 for (int k = n+1; k < N; k++)
176 if (milc.has_interface(n,k))
177 {
178 const int ind_trav = (n*(N-1)-(n-1)*(n)/2) + (k-n-1);
179 in.sigma[ind_trav] += vf_dir(f, c) / vf(f) * Sigma_tab(e, ind_trav);
180 }
181 for (int k = 0; k < N; k++)
182 in.nv(k, n) += vf_dir(f, c)/vf(f) * ch.v_norm(pvit, pvit, e, f, k, n, nullptr, nullptr);
183 }
184 for (int n = 0; n <Nk; n++) in.k_turb[n] += (k_turb) ? vf_dir(f, c)/vf(f) * (*k_turb)(e,0) : 0;
185 in.k_WIT += (k_WIT) ? vf_dir(f, c)/vf(f) * (*k_WIT)(e,0) : 0.;
186 in.e = e;
187 }
188
189 correlation_db.coefficient(in, out);
190
191 for (int k = 0; k < N; k++)
192 for (int l = 0; l < N; l++)
193 if (k != l)
194 {
195 double fac = beta_*pf(f) * vf(f);
196 secmem(f, k) += fac * ( - out.Ctd(k, l) * grad_f_a(f, k) + out.Ctd(l, k) * grad_f_a(f, l));
197 }
198 }
199
200 /* elements */
201 for (int e = 0; e < ne_tot; e++)
202 {
203 /* coefficient arguments */
204 for (int n = 0; n < N; n++)
205 {
206 in.alpha[n] = alpha(e, n);
207 in.p[n] = press(e, n * (Np > 1));
208 in.T[n] = temp(e, n); // FIXME SI res_en_T
209 in.rho[n] = rho(!cR * e, n);
210 in.mu[n] = mu(!cM * e, n);
211 in.nut[n] = is_turb ? nut(e,n) : 0;
212 in.d_bulles[n] = (d_bulles) ? (*d_bulles)(e,n) : 0;
213 for (int k = n+1; k < N; k++)
214 if (milc.has_interface(n,k))
215 {
216 const int ind_trav = (n*(N-1)-(n-1)*(n)/2) + (k-n-1);
217 in.sigma[ind_trav] = Sigma_tab(e, ind_trav);
218 }
219 for (int k = 0; k < N; k++)
220 in.nv(k, n) = ch.v_norm(pvit, pvit, e, -1, k, n, nullptr, nullptr);
221 }
222 for (int n = 0; n <Nk; n++) in.k_turb[n] = (k_turb) ? (*k_turb)(e,0) : 0;
223 in.k_WIT = (k_WIT) ? (*k_WIT)(e,0) : 0;
224 in.e = e;
225
226 correlation_db.coefficient(in, out);
227
228 for (int d = 0, i = nf_tot + D * e; d < D; d++, i++)
229 for (int k = 0; k < N; k++)
230 for (int l = 0; l < N; l++)
231 if (k != l)
232 {
233 double fac = beta_*pe(e) * ve(e);
234 secmem(i, k) += fac * ( - out.Ctd(k, l) * grad_f_a(i, k) + out.Ctd(l, k) * grad_f_a(i, l));
235 }
236 }
237}
: class Champ_Elem_PolyMAC_MPFA
void init_grad(int full_stencil) const
: class Champ_Face_PolyMAC_MPFA
double v_norm(const DoubleTab &val, const DoubleTab &val_f, int e, int f, int k, int l, double *v_ext, double *dnv) const
const IntTab & fcl() const
const IntTab & fcl() const
DoubleTab & passe(int i=1) override
Returns field values at instant t-i.
const Domaine_Cl_dis_base & domaine_Cl_dis() const
DoubleTab & valeurs() override
Returns the array of field values at the current time.
virtual DoubleTab & valeurs()=0
virtual DoubleTab & passe(int i=1)
Definition Champ_Proto.h:50
class Conds_lim This class represents a vector of boundary conditions.
Definition Conds_lim.h:32
Dirichlet This class is the base class of the hierarchy of Dirichlet-type boundary conditions.
Definition Dirichlet.h:31
void dimensionner_blocs_aux(Stencil &) const override
void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl={}) const override
Base class for turbulent bubble dispersion operators, where the force.
virtual void coefficient(const input_t &input, output_t &output) const =0
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
Echange_impose_base: This boundary condition is used only for the energy equation.
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()
Returns the problem associated with the equation.
Base class for an incompressible fluid and its properties:
Definition Fluide_base.h:36
double sigma_h(const double h, const double P) const
DoubleTab & get_sigma_tab()
double sigma(const double T, const double P) const
DoubleVect & porosite_elem()
Definition Milieu_base.h:58
virtual const Champ_base & masse_volumique() const
Returns the mass density of the medium (const version).
DoubleVect & porosite_face()
Definition Milieu_base.h:62
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
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
Classe Neumann_paroi This boundary condition corresponds to an imposed flux for the.
static int dimension
Definition Objet_U.h:94
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 Op_Diff_Turbulent_PolyMAC_MPFA_Face
Multiphase thermohydraulics problem of type "3*N equations":
virtual bool resolution_en_T() const
virtual Equation_base & equation_qdm()
virtual Equation_base & equation_energie()
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
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.
Base class for output streams.
Definition Sortie.h:52
Turbulent dispersion operator of the form:
const Correlation_base & correlation() const
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
int line_size() const
Definition TRUSTVect.tpp:67
Turbulent viscosity correlations describing the Reynolds stress tensor R_{ij} = - <u'_i u'_j>.