TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Iterateur_VDF_Elem_Multiphase_Parietal.tpp
1/****************************************************************************
2* Copyright (c) 2025, 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#ifndef Iterateur_VDF_Elem_Multiphase_Parietal_TPP_included
17#define Iterateur_VDF_Elem_Multiphase_Parietal_TPP_included
18
19#include <Source_Flux_interfacial_base.h>
20#include <Flux_parietal_base.h>
21#include <Milieu_composite.h>
22#include <Pb_Multiphase.h>
23
24template<class _TYPE_> template<typename Type_Double, typename BC>
25void Iterateur_VDF_Elem<_TYPE_>::ajouter_blocs_bords_flux_parietal_(const BC& cl, const int ndeb, const int nfin, const int N,
26 const DoubleTab& donnee, DoubleTab& resu, Matrice_Morse *mat, VectorDeriv& d_cc, const tabs_t& semi_impl) const
27{
28 assert (is_pb_multi);
29 Type_Double flux(N);
30
31 constexpr bool is_Temp_impose_flux_parietal = std::is_same<BC, Scalaire_impose_paroi>::value,
32 is_Neumann_flux_parietal = std::is_same<BC, Neumann_paroi>::value,
33 is_paroi_contact_flux_parietal = std::is_same<BC, Echange_global_impose>::value;
34
35 const Flux_parietal_base& corr = ref_cast(Flux_parietal_base, corr_flux_parietal_.valeur());
36 const Pb_Multiphase& pbm = ref_cast(Pb_Multiphase, op_base->equation().probleme());
37
38 const DoubleTab& alpha = pbm.equation_masse().inconnue().passe(),
40 &press = ref_cast(QDM_Multiphase, pbm.equation_qdm()).pression().passe(),
41 &lambda = pbm.milieu().conductivite().passe(),
42 &mu = ref_cast(Fluide_base, pbm.milieu()).viscosite_dynamique().passe(),
43 &rho = pbm.milieu().masse_volumique().passe(),
44 &Cp = pbm.milieu().capacite_calorifique().passe();
45
46 const DoubleVect& fs = le_dom->face_surfaces(), &pf = pbm.milieu().porosite_face();
47
50
51 DoubleTrav qpk(N), dTp_qpk(N), dTf_qpk(N, N), qpi(N, N), dTp_qpi(N, N), dTf_qpi(N, N, N), d_nuc(N);
52
53 out.qpk = &qpk;
54 out.dTf_qpk = &dTf_qpk;
55 out.qpi = &qpi;
56 out.dTf_qpi = &dTf_qpi;
57 out.d_nuc = &d_nuc;
58
59 if (is_Neumann_flux_parietal)
60 {
61 out.dTp_qpk = &dTp_qpk;
62 out.dTp_qpi = &dTp_qpi;
63 }
64
65 // Vitesse passee aux elems
66 const Champ_Face_VDF& ch = ref_cast(Champ_Face_VDF, pbm.equation_qdm().inconnue());
67 DoubleTrav pvit_elem(0, N * dimension);
68 le_dom->domaine().creer_tableau_elements(pvit_elem);
69 ch.get_elem_vector_field(pvit_elem, true /* passe */ );
70
72 op_base->equation().sources().size() && sub_type(Source_Flux_interfacial_base, op_base->equation().sources().dernier().valeur()) ?
73 &ref_cast(Source_Flux_interfacial_base, op_base->equation().sources().dernier().valeur()) : nullptr;
74
75 DoubleTab *pqpi = sss ? &(sss->qpi()) : nullptr;
76 DoubleTab *pdTf_qpi = sss ? &(sss->dT_qpi()) : nullptr;
77
78 if (pqpi)
79 *pqpi = 0.;
80
81 if (pdTf_qpi)
82 *pdTf_qpi = 0.;
83
84 DoubleTrav Ts_tab, Sigma_tab, Lvap_tab;
85 if (corr.needs_saturation())
86 {
87 const Milieu_composite& milc = ref_cast(Milieu_composite, op_base->equation().milieu());
88 const int nbelem_tot = le_dom->nb_elem_tot(), nb_max_sat = N * (N - 1) / 2; // oui !! suite arithmetique !!
89 Ts_tab.resize(nbelem_tot, nb_max_sat), Sigma_tab.resize(nbelem_tot, nb_max_sat), Lvap_tab.resize(nbelem_tot, nb_max_sat);
90
91 for (int k = 0; k < N; k++)
92 for (int l = k + 1; l < N; l++)
93 if (milc.has_saturation(k, l))
94 {
95 Saturation_base& z_sat = milc.get_saturation(k, l);
96 const int ind_trav = (k * (N - 1) - (k - 1) * (k) / 2) + (l - k - 1); // Et oui ! matrice triang sup !
97 assert(press.line_size() == 1);
98
99 // recuperer Tsat et sigma ...
100 const DoubleTab& sig = z_sat.get_sigma_tab(), &tsat = z_sat.get_Tsat_tab();
101
102 // fill in the good case
103 for (int ii = 0; ii < nbelem_tot; ii++)
104 {
105 Ts_tab(ii, ind_trav) = tsat(ii);
106 Sigma_tab(ii, ind_trav) = sig(ii);
107 }
108
109 z_sat.Lvap(press.get_span_tot() /* elem reel */, Lvap_tab.get_span_tot(), nb_max_sat, ind_trav);
110 z_sat.Tsat(press.get_span_tot() /* elem reel */, Ts_tab.get_span_tot(), nb_max_sat, ind_trav); // Tentative avec pression passee
111 }
112 }
113
114 DoubleTrav Tf(N), nv(N);
115 for (int face = ndeb; face < nfin; face++)
116 {
117 Tf = 0.;
118 qpk = 0.;
119 dTf_qpk = 0.;
120 qpi = 0.;
121 dTf_qpi = 0.;
122 nv = 0.;
123 d_nuc = 0.;
124
125 const int e = elem(face, 0) > -1 ? elem(face, 0) : elem(face, 1);
126
127 const double y = elem(face, 0) > -1 ? le_dom->dist_face_elem0(face, e) : le_dom->dist_face_elem1(face, e);
128
129 // fill in struct
130 in.N = N;
131 in.f = face;
132 in.y = y;
133 in.D_h = dh(e);
134 in.D_ch = dh(e);
135 in.alpha = &alpha(e, 0);
136 in.p = press(e);
137 in.lambda = &lambda(e, 0);
138 in.mu = &mu(e, 0);
139 in.rho = &rho(e, 0);
140 in.Cp = &Cp(e, 0);
141 in.T = &donnee(e, 0);
142 in.v = nv.addr();
143
144 if (corr.needs_saturation())
145 {
146 in.Lvap = &Lvap_tab(e, 0);
147 in.Sigma = &Sigma_tab(e, 0);
148 in.Tsat = &Ts_tab(e, 0);
149 }
150 else
151 {
152 in.Lvap = nullptr;
153 in.Sigma = nullptr;
154 in.Tsat = nullptr;
155 }
156
157 // velocity norm
158 for (int d = 0; d < Objet_U::dimension; d++)
159 for (int n = 0; n < N; n++)
160 nv(n) += std::pow(pvit_elem(e, N * d + n), 2);
161
162 for (int n = 0; n < N; n++)
163 nv(n) = std::sqrt(nv(n));
164
165 // 3 Cas CLS
166 if (is_Temp_impose_flux_parietal) // Dirichlet
167 {
168 in.Tp = ref_cast(Scalaire_impose_paroi, cl).val_imp(face - ndeb);
169
170 corr.qp(in, out); // call correlation
171
172 if (pqpi)
173 for (int k = 0; k < N; k++)
174 for (int l = 0; l < N; l++)
175 (*pqpi)(e, k, l) += qpi(k, l) * fs(face);
176
177 if ((pdTf_qpi) && (mat))
178 for (int k = 0; k < N; k++)
179 for (int l = 0; l < N; l++)
180 for (int m = 0; m < N; m++)
181 (*pdTf_qpi)(e, k, l, m) += dTf_qpi(k, l, m) * fs(face);
182
183 for (int k = 0; k < N; k++)
184 flux[k] = (elem(face, 0) != -1) ? qpk(k) * fs(face) * pf(face) : -qpk(k) * fs(face) * pf(face);
185
186 fill_flux_tables_(face, N, 1.0, flux, resu);
187
188 if (mat)
189 for (int k = 0; k < N; k++)
190 for (int l = 0; l < N; l++)
191 (*mat)(e * N + k, e * N + l) += dTf_qpk(k, l) * fs(face) * pf(face);
192
193 }
194 if (is_paroi_contact_flux_parietal) // Echange contact
195 {
196 Process::exit(que_suis_je() + " : paroi_contact with flux parietal is not yet coded ! Change to PolyMAC_MPFA or call the 911. ");
197
198 if (!cl.que_suis_je().debute_par("Paroi_Echange_contact"))
199 Process::exit(que_suis_je() + " : in pb_multiphase there is no echange contact with a wall heat flux correlation : choisis ton camp camarade !");
200 }
201 else if (is_Neumann_flux_parietal) // Neumann
202 {
203 // Ici on fait un Newton simple
204 in.Tp = donnee(e, 0);
205
206 double flux_imp = ref_cast(Neumann, cl).flux_impose(face - ndeb);
207 double flux_cor = 0., dTp_flux_cor = 0.;
208 int it = 0, cv = 0;
209
210 for (it = 0; !cv && it < 100; it++)
211 {
212 flux_cor = 0;
213 dTp_flux_cor = 0;
214
215 Tf = 0.;
216 qpk = 0.;
217 dTp_qpk = 0.;
218 dTf_qpk = 0.;
219 qpi = 0.;
220 dTp_qpi = 0.;
221 dTf_qpi = 0.;
222
223 corr.qp(in, out);
224
225 for (int k = 0; k < N; k++)
226 {
227 flux_cor += qpk(k);
228 dTp_flux_cor += dTp_qpk(k);
229 }
230
231 for (int k = 0; k < N; k++)
232 for (int l = 0; l < N; l++)
233 {
234 flux_cor += qpi(k, l);
235 dTp_flux_cor += dTp_qpi(k, l);
236 }
237
238 in.Tp = in.Tp - (flux_cor - flux_imp) / dTp_flux_cor;
239 cv = (std::abs(flux_cor - flux_imp) < 1.e-5);
240 }
241
242 if (!cv)
243 {
244 std::string message_erreur = "Non-convergence des Tefs !!!";
245 message_erreur.append("\n Tp init = ");
246 message_erreur.append(std::to_string( donnee(e, 0)));
247 message_erreur.append("\n T fluide = ");
248 for (int k = 0; k < N; k++)
249 {
250 message_erreur.append(std::to_string(donnee(e, k)));
251 message_erreur.append(" ");
252 }
253 message_erreur.append("\n Phi cible = ");
254 message_erreur.append(std::to_string(flux_imp));
255 message_erreur.append("\n Phi cor = ");
256 message_erreur.append(std::to_string(flux_cor));
257 Process::exit(message_erreur);
258 }
259
260 if (pqpi)
261 for (int k = 0; k < N; k++)
262 for (int l = 0; l < N; l++)
263 (*pqpi)(e, k, l) += qpi(k, l) * fs(face);
264
265 if ((pdTf_qpi) && (mat))
266 for (int k = 0; k < N; k++)
267 for (int l = 0; l < N; l++)
268 for (int m = 0; m < N; m++)
269 (*pdTf_qpi)(e, k, l, m) += dTf_qpi(k, l, m) * fs(face);
270
271 for (int k = 0; k < N; k++)
272 flux[k] = (elem(face, 0) != -1) ? qpk(k) * fs(face) : -qpk(k) * fs(face);
273
274 fill_flux_tables_(face, N, 1.0, flux, resu);
275
276 if (mat)
277 for (int k = 0; k < N; k++)
278 for (int l = 0; l < N; l++)
279 (*mat)(e * N + k, e * N + l) += dTf_qpk(k, l) * fs(face) * pf(face);
280 }
281 }
282}
283
284#endif /* Iterateur_VDF_Elem_Multiphase_Parietal_TPP_included */
class Champ_Face_VDF Cette classe sert a representer un champ vectoriel dont on ne calcule
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.
virtual DoubleTab & passe(int i=1)
Definition Champ_Proto.h:50
virtual const Milieu_base & milieu() const =0
Sources & sources()
Renvoie les termes sources asssocies a l'equation.
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
classe Flux_parietal_base correlations de flux parietal de la forme
virtual int needs_saturation() const
virtual void qp(const input_t &input, output_t &output) const =0
DoubleTab & get_sigma_tab()
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
virtual const Equation_base & equation(const std::string &nom_inc) const
virtual const Champ_Don_base & capacite_calorifique() const
Renvoie la capacite calorifique du milieu.
virtual const Champ_Don_base & conductivite() const
Renvoie la conductivite du milieu.
virtual const Champ_base & masse_volumique() const
Renvoie la masse volumique du milieu.
DoubleTab & diametre_hydraulique_elem()
Definition Milieu_base.h:70
DoubleVect & porosite_face()
Definition Milieu_base.h:62
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 Cette classe est la classe de base de la hierarchie des conditions aux limites de type...
Definition Neumann.h:31
static int dimension
Definition Objet_U.h:99
classe Pb_Multiphase Cette classe represente un probleme de thermohydraulique multiphase de type "3*N...
virtual Equation_base & equation_qdm()
const Equation_base & equation(int) const override
Renvoie l'equation d'hydraulique de type Navier_Stokes_std si i=0 Renvoie l'equation de la thermique ...
virtual Equation_base & equation_masse()
virtual const Milieu_base & milieu() const
Renvoie le milieu physique associe au probleme.
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
void Tsat(const SpanD P, SpanD res, int ncomp=1, int ind=0) const
DoubleTab & get_Tsat_tab()
void Lvap(const SpanD P, SpanD res, int ncomp=1, int ind=0) const
classe Scalaire_impose_paroi Impose un scalaire a la paroi dans une equation de type Convection-Difus...
Classe Source_Flux_interfacial_base.
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
Span_ get_span_tot() override
Definition TRUSTVect.h:182