TrioCFD 1.9.8
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); //viscosite turbulente
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); //remplissage par la 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 /* calculaiton 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 utilisees dans domaine_PolyMAC_MPFA::fgrad pour le calcul du gradient
100 const DoubleTab& fg_w = ch_a.fgrad_w;
101 const Conds_lim& cls_a = ch_a.domaine_Cl_dis().les_conditions_limites(); // conditions aux limites du champ alpha
102 const IntTab& fcl_a = ch_a.fcl(); // tableaux utilitaires sur les CLs : fcl(f, .) = (type de la CL, no de la CL, indice dans la CL)
103
104 // Et pour les methodes span de la classe Interface pour choper la tension de surface
105 const int nb_max_sat = N * (N-1) /2; // oui !! suite arithmetique !!
106 DoubleTrav Sigma_tab(ne_tot,nb_max_sat);
107
108 // remplir les tabs ...
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); // Et oui ! matrice triang sup !
116 // recuperer 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); // Et oui ! matrice triang sup !
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) //contribution d'un element
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) //Neumann non homogene
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 /* Calcul du grad aux elems */
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 /* arguments de coeff */
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
Renvoie les valeurs du champs a l'instant t-i.
const Domaine_Cl_dis_base & domaine_Cl_dis() const
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
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
Definition Conds_lim.h:32
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
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
classe Dispersion_bulles_base utilitaire pour les operateurs de dispersion turbulente ou la force
virtual void coefficient(const input_t &input, output_t &output) const =0
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
classe Echange_impose_base: Cette condition limite sert uniquement pour l'equation d'energie.
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.
classe Fluide_base Cette classe represente un d'un fluide incompressible ainsi que
Definition Fluide_base.h:38
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
Renvoie la masse volumique du milieu.
DoubleVect & porosite_face()
Definition Milieu_base.h:62
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
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
Classe Neumann_paroi Cette condition limite correspond a un flux impose pour l'equation de.
static int dimension
Definition Objet_U.h:99
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
classe Pb_Multiphase Cette classe represente un probleme de thermohydraulique multiphase de type "3*N...
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)
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 de base des flux de sortie.
Definition Sortie.h:52
Classe Source_Dispersion_bulles_base.
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
classe Viscosite_turbulente_base correlations de viscosite turbulente decrivant le tenseur de Reynold...