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// XD Injection_QDM_nulle source_base Injection_QDM_nulle BRACE not_set
35
36
38
40
41void Injection_QDM_nulle_PolyMAC_MPFA::ajouter_blocs(matrices_t matrices, DoubleTab& secmem, const tabs_t& semi_impl) const
42{
43 const Champ_Face_PolyMAC_MPFA& ch = ref_cast(Champ_Face_PolyMAC_MPFA, equation().inconnue());
44 const Champ_Elem_PolyMAC_MPFA& cha= ref_cast(Champ_Elem_PolyMAC_MPFA, equation().probleme().equation(1).inconnue()); // volume fraction
45 const Domaine_PolyMAC_MPFA& domaine = ref_cast(Domaine_PolyMAC_MPFA, equation().domaine_dis());
47 const Milieu_composite& milc = ref_cast(Milieu_composite, equation().milieu());
48
49 const IntTab& fcl = ch.fcl();
50 const IntTab& fcla = cha.fcl();
51 const IntTab& f_e = domaine.face_voisins();
52 const IntTab& e_f = domaine.elem_faces();
53
54 const DoubleVect& vf = domaine.volumes_entrelaces();
55 const DoubleVect& fs = domaine.face_surfaces();
56
57 const DoubleTab& vf_dir = domaine.volumes_entrelaces_dir();
58 const DoubleTab& vit = ch.valeurs();
59 const DoubleTab& rho = equation().milieu().masse_volumique().passe(); // passe car qdm
60 const DoubleTab& alpha = cha.passe();
61
62 Matrice_Morse *mat = matrices.count(ch.le_nom().getString()) ? matrices.at(ch.le_nom().getString()) : nullptr; // Derivee locale/QDM
63
64 const Pb_Multiphase *pbm = sub_type(Pb_Multiphase, equation().probleme()) ? &ref_cast(Pb_Multiphase, equation().probleme()) : nullptr;
65 const Masse_ajoutee_base *corr = pbm && pbm->has_correlation("masse_ajoutee") ? &ref_cast(Masse_ajoutee_base, pbm->get_correlation("masse_ajoutee")) : nullptr;
66
67 const int N = vit.line_size();
68 const int D = dimension;
69 const int nf_tot = domaine.nb_faces_tot();
70 const int nf = domaine.nb_faces();
71 const int ne_tot = domaine.nb_elem_tot();
72
73 // Adiabatic case: bubble injection at the wall (manip de Gabillet et al.)
74 for (int f = 0; f < nf_tot; f ++)
75 if (fcla(f, 0) == 4) // Neumann_paroi
76 {
77 const int e = f_e(f, 0);
78 if (e >= 0)
79 {
80 DoubleTrav f_a_masse(N, N) ;
81 DoubleTrav f_a(1, N);
82 for (int n = 0; n < N; n++)
83 {
84 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
85 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
86 }
87 corr->ajouter_inj(&f_a(0,0), &alpha(e, 0), &rho(e, 0), f_a_masse);
88
89 for (int d = 0; d < D ; d++)
90 for (int n = 0 ; n < N ; n++)
91 for (int m = 0 ; m < N ; m++)
92 {
93 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
94 if (mat)
95 (*mat)( N * (nf_tot + D*e + d) + n , N * (nf_tot + D*e + d) + m ) += fs(f) * f_a_masse(n, m) * beta_ ;
96 }
97
98 for (int i = 0; i < e_f.line_size(); i++)
99 {
100 const int f2 = e_f(e, i);
101 if ((f2 >= 0) && (f2 < nf) && (fcl(f2, 0) < 2)) // Si pas face de bord
102 {
103 const int c = (e == f_e(f2, 0) ) ? 0 : 1; // TODO: explicit name?
104 for (int n = 0; n < N; n++)
105 for (int m = 0; m < N; m++)
106 {
107 secmem(f2, n) -= fs(f) * f_a_masse(n, m) * vf_dir(f2, c) / vf(f2) * vit( f2, m) * beta_;
108 if (mat)
109 (*mat)( N * f2 + n , N * f2 + m ) += fs(f) * f_a_masse(n, m) * vf_dir(f2, c) / vf(f2) * beta_;
110 }
111 }
112 }
113 }
114 }
115
116 // TODO : split in two?
117
118 // Cas bouillant : on passe par qpi
119 if ((pbm) && pbm->has_correlation("flux_parietal"))
120 {
121 const DoubleTab& qpi = ref_cast(Source_Flux_interfacial_base, pbm->equation_energie().sources().dernier().valeur()).qpi();
122 const DoubleTab& press = ref_cast(QDM_Multiphase, pbm->equation_qdm()).pression().passe();
123 const int nb_max_sat = N*(N - 1)/2;
124
125 /* limiteur de changement de phase : pas mis dans la V0 de cette force */
126
127 // We only need phase change enthalpy
128 DoubleTrav Lvap_tab(ne_tot, nb_max_sat);
129 DoubleTrav f_a_masse(N, N);
130 DoubleTrav f_a(1, N);
131
132 for (int k = 0; k < N; k++)
133 for (int l = k + 1; l < N; l++)
134 if (milc.has_saturation(k, l))
135 {
136 Saturation_base& z_sat = milc.get_saturation(k, l);
137 const int ind_trav = sigma_pair_index(k, l, N);
138 assert(press.line_size() == 1);
139
140 z_sat.Lvap(press.get_span_tot(), Lvap_tab.get_span_tot(), nb_max_sat, ind_trav);
141 }
142
143 for (int f = 0 ; f< nf_tot ; f ++)
144 if (f_e(f, 1)<= 0) // Si face de bord
145 {
146 const int e = f_e(f, 0) ;
147 f_a_masse = 0;
148 f_a = 0;
149 double G = 0;
150
151 for (int k = 0; k < N; k++)
152 for (int l = k + 1; l < N; l++)
153 if (milc.has_saturation(k, l)) //flux phase k <-> phase l si saturation
154 {
155 const int i_sat = sigma_pair_index(k, l, N);
156
157 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 !
158
159 f_a(0, k) -= G/(fs(f)*rho(e, k)) ;
160 f_a_masse(k, k) -= G/fs(f) ;
161 f_a(0, l) += G/(fs(f)*rho(e, l)) ;
162 f_a_masse(l, l) += G/fs(f) ;
163 }
164 corr->ajouter_inj(&f_a(0,0), &alpha(e, 0), &rho(e, 0), f_a_masse);
165
166 for (int d = 0; d < D ; d++)
167 for (int n = 0 ; n < N ; n++)
168 for (int m = 0 ; m < N ; m++)
169 {
170 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
171 if (mat)
172 (*mat)( N * (nf_tot + D*e + d) + n , N * (nf_tot + D*e + d) + m ) += fs(f) * f_a_masse(n, m) * beta_ ;
173 }
174
175 for (int i = 0; i < e_f.line_size(); i++)
176 {
177 const int f2 = e_f(e, i);
178 if ((f2 >= 0) && (f2 < nf) && (fcl(f2, 0) < 2)) // Si pas face de bord
179 {
180 const int c = (e == f_e(f2, 0)) ? 0 : 1;
181 for (int n = 0 ; n < N ; n++)
182 for (int m = 0 ; m < N ; m++)
183 {
184 secmem(f2, n) -= fs(f) * f_a_masse(n, m) * vf_dir(f2, c) / vf(f2) * vit( f2, m) * beta_ ;
185 if (mat)
186 (*mat)( N * f2 + n , N * f2 + m ) += fs(f) * f_a_masse(n, m) * vf_dir(f2, c) / vf(f2) * beta_ ;
187 }
188 }
189 }
190 }
191 }
192}
: 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