TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Injection_QDM_nulle_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 <Injection_QDM_nulle_PolyMAC_MPFA.h>
17#include <Source_Flux_interfacial_base.h>
18#include <Champ_Face_PolyMAC_MPFA.h>
19#include <Champ_Elem_PolyMAC_MPFA.h>
20#include <Domaine_PolyMAC_MPFA.h>
21#include <Masse_ajoutee_base.h>
22#include <Milieu_composite.h>
23#include <Neumann_val_ext.h>
24#include <Saturation_base.h>
25#include <Neumann_paroi.h>
26#include <Pb_Multiphase.h>
27#include <Matrix_tools.h>
28#include <Array_tools.h>
29#include <Conds_lim.h>
30#include <Sources_helpers_Multiphase.h>
31#include <math.h>
32
33Implemente_instanciable(Injection_QDM_nulle_PolyMAC_MPFA, "Injection_QDM_nulle_Face_PolyMAC_MPFA", Source_injection_QDM_base);
34
35
37
39
40void Injection_QDM_nulle_PolyMAC_MPFA::ajouter_blocs(matrices_t matrices, DoubleTab& secmem, const tabs_t& semi_impl) const
41{
42 const Champ_Face_PolyMAC_MPFA& ch = ref_cast(Champ_Face_PolyMAC_MPFA, equation().inconnue());
43 const Champ_Elem_PolyMAC_MPFA& cha= ref_cast(Champ_Elem_PolyMAC_MPFA, equation().probleme().equation(1).inconnue()); // volume fraction
44 const Domaine_PolyMAC_MPFA& domaine = ref_cast(Domaine_PolyMAC_MPFA, equation().domaine_dis());
46 const Milieu_composite& milc = ref_cast(Milieu_composite, equation().milieu());
47
48 const IntTab& fcl = ch.fcl();
49 const IntTab& fcla = cha.fcl();
50 const IntTab& f_e = domaine.face_voisins();
51 const IntTab& e_f = domaine.elem_faces();
52
53 const DoubleVect& vf = domaine.volumes_entrelaces();
54 const DoubleVect& fs = domaine.face_surfaces();
55
56 const DoubleTab& vf_dir = domaine.volumes_entrelaces_dir();
57 const DoubleTab& vit = ch.valeurs();
58 const DoubleTab& rho = equation().milieu().masse_volumique().passe(); // passe car qdm
59 const DoubleTab& alpha = cha.passe();
60
61 Matrice_Morse *mat = matrices.count(ch.le_nom().getString()) ? matrices.at(ch.le_nom().getString()) : nullptr; // Derivee locale/QDM
62
63 const Pb_Multiphase *pbm = sub_type(Pb_Multiphase, equation().probleme()) ? &ref_cast(Pb_Multiphase, equation().probleme()) : nullptr;
64 const Masse_ajoutee_base *corr = pbm && pbm->has_correlation("masse_ajoutee") ? &ref_cast(Masse_ajoutee_base, pbm->get_correlation("masse_ajoutee")) : nullptr;
65
66 const int N = vit.line_size();
67 const int D = dimension;
68 const int nf_tot = domaine.nb_faces_tot();
69 const int nf = domaine.nb_faces();
70 const int ne_tot = domaine.nb_elem_tot();
71
72 // Adiabatic case: bubble injection at the wall (manip de Gabillet et al.)
73 for (int f = 0; f < nf_tot; f ++)
74 if (fcla(f, 0) == 4) // Neumann_paroi
75 {
76 const int e = f_e(f, 0);
77 if (e >= 0)
78 {
79 DoubleTrav f_a_masse(N, N) ;
80 DoubleTrav f_a(1, N);
81 for (int n = 0; n < N; n++)
82 {
83 f_a_masse(n, n) = ref_cast(Neumann_paroi, clsa[fcla(f, 1)].valeur()).flux_impose(fcla(f, 2), n) * rho(e, n) ; // Pas de porosite ; unite : kg/m3 m/s
84 f_a(0, n) = ref_cast(Neumann_paroi, clsa[fcla(f, 1)].valeur()).flux_impose(fcla(f, 2), n) ; // Pas de porosite ; unite : m/s
85 }
86 corr->ajouter_inj(&f_a(0,0), &alpha(e, 0), &rho(e, 0), f_a_masse);
87
88 for (int d = 0; d < D ; d++)
89 for (int n = 0 ; n < N ; n++)
90 for (int m = 0 ; m < N ; m++)
91 {
92 secmem(nf_tot + D * e + d, n) -= fs(f) * f_a_masse(n, m) * vit( nf_tot + D * e + d, m) * beta_; // Force along -vit
93 if (mat)
94 (*mat)( N * (nf_tot + D*e + d) + n , N * (nf_tot + D*e + d) + m ) += fs(f) * f_a_masse(n, m) * beta_ ;
95 }
96
97 for (int i = 0; i < e_f.line_size(); i++)
98 {
99 const int f2 = e_f(e, i);
100 if ((f2 >= 0) && (f2 < nf) && (fcl(f2, 0) < 2)) // Si pas face de bord
101 {
102 const int c = (e == f_e(f2, 0) ) ? 0 : 1; // TODO: explicit name?
103 for (int n = 0; n < N; n++)
104 for (int m = 0; m < N; m++)
105 {
106 secmem(f2, n) -= fs(f) * f_a_masse(n, m) * vf_dir(f2, c) / vf(f2) * vit( f2, m) * beta_;
107 if (mat)
108 (*mat)( N * f2 + n , N * f2 + m ) += fs(f) * f_a_masse(n, m) * vf_dir(f2, c) / vf(f2) * beta_;
109 }
110 }
111 }
112 }
113 }
114
115 // TODO : split in two?
116
117 // Cas bouillant : on passe par qpi
118 if ((pbm) && pbm->has_correlation("flux_parietal"))
119 {
120 const DoubleTab& qpi = ref_cast(Source_Flux_interfacial_base, pbm->equation_energie().sources().dernier().valeur()).qpi();
121 const DoubleTab& press = ref_cast(QDM_Multiphase, pbm->equation_qdm()).pression().passe();
122 const int nb_max_sat = N*(N - 1)/2;
123
124 /* limiteur de changement de phase : pas mis dans la V0 de cette force */
125
126 // We only need phase change enthalpy
127 DoubleTrav Lvap_tab(ne_tot, nb_max_sat);
128 DoubleTrav f_a_masse(N, N);
129 DoubleTrav f_a(1, N);
130
131 for (int k = 0; k < N; k++)
132 for (int l = k + 1; l < N; l++)
133 if (milc.has_saturation(k, l))
134 {
135 Saturation_base& z_sat = milc.get_saturation(k, l);
136 const int ind_trav = sigma_pair_index(k, l, N);
137 assert(press.line_size() == 1);
138
139 z_sat.Lvap(press.get_span_tot(), Lvap_tab.get_span_tot(), nb_max_sat, ind_trav);
140 }
141
142 for (int f = 0 ; f< nf_tot ; f ++)
143 if (f_e(f, 1)<= 0) // Si face de bord
144 {
145 const int e = f_e(f, 0) ;
146 f_a_masse = 0;
147 f_a = 0;
148 double G = 0;
149
150 for (int k = 0; k < N; k++)
151 for (int l = k + 1; l < N; l++)
152 if (milc.has_saturation(k, l)) //flux phase k <-> phase l si saturation
153 {
154 const int i_sat = sigma_pair_index(k, l, N);
155
156 G = qpi(e, k, l) / Lvap_tab(e, i_sat) ; // Flux de matiere de la phase k vers l ; attention : qpi est en W, donc G en kgs-1 : il n'est pas volumique !
157
158 f_a(0, k) -= G/(fs(f)*rho(e, k)) ;
159 f_a_masse(k, k) -= G/fs(f) ;
160 f_a(0, l) += G/(fs(f)*rho(e, l)) ;
161 f_a_masse(l, l) += G/fs(f) ;
162 }
163 corr->ajouter_inj(&f_a(0,0), &alpha(e, 0), &rho(e, 0), f_a_masse);
164
165 for (int d = 0; d < D ; d++)
166 for (int n = 0 ; n < N ; n++)
167 for (int m = 0 ; m < N ; m++)
168 {
169 secmem(nf_tot + D * e + d, n) -= fs(f) * f_a_masse(n, m) * vit( nf_tot + D * e + d, m) * beta_ ; // Force along -vit
170 if (mat)
171 (*mat)( N * (nf_tot + D*e + d) + n , N * (nf_tot + D*e + d) + m ) += fs(f) * f_a_masse(n, m) * beta_ ;
172 }
173
174 for (int i = 0; i < e_f.line_size(); i++)
175 {
176 const int f2 = e_f(e, i);
177 if ((f2 >= 0) && (f2 < nf) && (fcl(f2, 0) < 2)) // Si pas face de bord
178 {
179 const int c = (e == f_e(f2, 0)) ? 0 : 1;
180 for (int n = 0 ; n < N ; n++)
181 for (int m = 0 ; m < N ; m++)
182 {
183 secmem(f2, n) -= fs(f) * f_a_masse(n, m) * vf_dir(f2, c) / vf(f2) * vit( f2, m) * beta_ ;
184 if (mat)
185 (*mat)( N * f2 + n , N * f2 + m ) += fs(f) * f_a_masse(n, m) * vf_dir(f2, c) / vf(f2) * beta_ ;
186 }
187 }
188 }
189 }
190 }
191}
: class Champ_Elem_PolyMAC_MPFA
: class Champ_Face_PolyMAC_MPFA
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 & 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
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
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
Sources & sources()
Renvoie les termes sources asssocies a l'equation.
const Nom & le_nom() const override
Renvoie le nom du champ.
classe Injection_QDM_nulle_PolyMAC_MPFA Correction de la QDM d'un fluide de l'écoulement quand on en ...
void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl={}) const override
classe Masse_ajoutee_base masse ajoutee de la forme
virtual void ajouter_inj(const double *flux_alpha, const double *alpha, const double *rho, DoubleTab &f_a_r) const =0
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
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_saturation(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.
const std::string & getString() const
Definition Nom.h:92
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
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()
int has_correlation(std::string nom_correlation) const
const Correlation_base & get_correlation(std::string nom_correlation) const
classe QDM_Multiphase Cette classe porte les termes de l'equation de la dynamique
void Lvap(const SpanD P, SpanD res, int ncomp=1, int ind=0) const
Classe de base des flux de sortie.
Definition Sortie.h:52
Classe Source_Flux_interfacial_base.
classe Injection_QDM_nulle_VDF Correction de la QDM d'un fluide de l'écoulement quand on en injecte
int line_size() const
Definition TRUSTVect.tpp:67
Span_ get_span_tot() override
Definition TRUSTVect.h:182