TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Iterateur_VDF_Elem.tpp
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#ifndef Iterateur_VDF_Elem_TPP_included
17#define Iterateur_VDF_Elem_TPP_included
18
19#include <Convection_Diffusion_Temperature_base.h>
20#include <Operateur_Diff_base.h>
21#include <Champ_Uniforme.h>
22#include <communications.h>
23#include <TRUSTSingle.h>
24
25template<class _TYPE_>
26void Iterateur_VDF_Elem<_TYPE_>::ajouter_contribution_autre_pb(const DoubleTab& inco, Matrice_Morse& matrice, const Cond_lim& la_cl, std::map<int, std::pair<int, int>>& f2e) const
27{
28 const int ncomp = inco.line_size();
29 ArrOfDouble aii(ncomp), ajj(ncomp);
30 const Front_VF& frontiere_dis = ref_cast(Front_VF, la_cl->frontiere_dis());
31 const int ndeb = frontiere_dis.num_premiere_face(), nfin = ndeb + frontiere_dis.nb_faces();
32 if (_TYPE_::CALC_FLUX_FACES_ECH_GLOB_IMP)
33 {
34 const Echange_global_impose& cl = (const Echange_global_impose&) (la_cl.valeur());
35 for (int f = ndeb; f < nfin; f++)
36 {
37 const int e1 = f2e[f].first, e2 = f2e[f].second;
38 flux_evaluateur.coeffs_face(f, ndeb, cl, aii, ajj);
39 for (int i = 0; i < ncomp; i++)
40 matrice(e1 * ncomp + i, e2 * ncomp + i) = -(elem(f, 0) > -1 ? aii[i] : ajj[i]);
41 }
42 }
43}
44
45/* ************************************** *
46 * ********* INTERFACE BLOCS ********** *
47 * ************************************** */
48
49template<class _TYPE_>
50void Iterateur_VDF_Elem<_TYPE_>::ajouter_blocs(matrices_t mats, DoubleTab& secmem, const tabs_t& semi_impl) const
51{
52 ((_TYPE_&) flux_evaluateur).mettre_a_jour();
53 assert(op_base->equation().inconnue().valeurs().nb_dim() < 3 && la_zcl && le_dom);
54 const int ncomp = op_base->equation().inconnue().valeurs().line_size();
55 DoubleTab& flux_bords = op_base->flux_bords();
56 flux_bords.resize(le_dom->nb_faces_bord(), ncomp);
57 flux_bords = 0.;
58 // modif b.m.: will do += on virtual items; initialize entries to avoid invalid or uninitialized values
59 {
60 int n = secmem.size_array() - secmem.size();
61 double *data = secmem.addr() + secmem.size();
62 for (; n; n--, data++) *data = 0.;
63 }
64 if (ncomp == 1)
65 {
66 ajouter_blocs_bords < SingleDouble > (ncomp, mats, secmem, semi_impl);
67 ajouter_blocs_interne < SingleDouble > (ncomp, mats, secmem, semi_impl);
68 }
69 else
70 {
71 ajouter_blocs_bords < ArrOfDouble > (ncomp, mats, secmem, semi_impl);
72 ajouter_blocs_interne < ArrOfDouble > (ncomp, mats, secmem, semi_impl);
73 }
74
75 if (!is_pb_multi) modifier_flux(); /* deja rho*cp car champ convecte */
76}
77
78template<class _TYPE_> template<typename Type_Double>
79void Iterateur_VDF_Elem<_TYPE_>::ajouter_blocs_bords(const int ncomp, matrices_t mats, DoubleTab& resu, const tabs_t& semi_impl) const
80{
81 for (int num_cl = 0; num_cl < le_dom->nb_front_Cl(); num_cl++)
82 {
83 const Cond_lim& la_cl = la_zcl->les_conditions_limites(num_cl);
84 const Front_VF& frontiere_dis = ref_cast(Front_VF, la_cl->frontiere_dis());
85 const int ndeb = frontiere_dis.num_premiere_face(), nfin = ndeb + frontiere_dis.nb_faces();
86 /* Test en bidim axi */
87 if (bidim_axi && !sub_type(Symetrie, la_cl.valeur()))
88 {
89 if (nfin > ndeb && est_egal(le_dom->face_surfaces()[ndeb], 0))
90 {
91 Cerr << "Error in the definition of the boundary conditions. The axis of revolution for this 2D calculation is along Y." << finl;
92 Cerr << "So you must specify symmetry boundary condition (symetrie keyword) for the boundary " << frontiere_dis.le_nom() << finl;
94 }
95 }
96
97 switch(type_cl(la_cl))
98 {
99 case navier:
100 ajouter_blocs_bords_<_TYPE_::CALC_FLUX_FACES_SYMM, Type_Double>((const Symetrie&) la_cl.valeur(), ndeb, nfin, ncomp, mats, resu, semi_impl);
101 break;
102 case sortie_libre:
103 ajouter_blocs_bords_<_TYPE_::CALC_FLUX_FACES_SORTIE_LIB, Type_Double>((const Neumann_sortie_libre&) la_cl.valeur(), ndeb, nfin, ncomp, mats, resu, semi_impl);
104 break;
105 case entree_fluide:
106 ajouter_blocs_bords_<_TYPE_::CALC_FLUX_FACES_ENTREE_FL, Type_Double>((const Dirichlet_entree_fluide&) la_cl.valeur(), ndeb, nfin, ncomp, mats, resu, semi_impl);
107 break;
108 case paroi_fixe:
109 ajouter_blocs_bords_<_TYPE_::CALC_FLUX_FACES_PAR_FIXE, Type_Double>((const Dirichlet_paroi_fixe&) la_cl.valeur(), ndeb, nfin, ncomp, mats, resu, semi_impl);
110 break;
111 case paroi_defilante:
112 ajouter_blocs_bords_<_TYPE_::CALC_FLUX_FACES_PAR_DEFIL, Type_Double>((const Dirichlet_paroi_defilante&) la_cl.valeur(), ndeb, nfin, ncomp, mats, resu, semi_impl);
113 break;
114 case paroi_scalaire_impose:
115 ajouter_blocs_bords_<_TYPE_::CALC_FLUX_FACES_SCAL_IMPOSEE, Type_Double>((const Scalaire_impose_paroi&) la_cl.valeur(), ndeb, nfin, ncomp, mats, resu, semi_impl);
116 break;
117 case paroi_dirichlet_loi_paroi:
118 ajouter_blocs_bords_<_TYPE_::CALC_FLUX_FACES_SCAL_IMPOSEE /* true */, Type_Double>((const Dirichlet_loi_paroi&) la_cl.valeur(), ndeb, nfin, ncomp, mats, resu, semi_impl);
119 break;
120 case paroi:
121 ajouter_blocs_bords_<_TYPE_::CALC_FLUX_FACES_PAR, Type_Double>((const Neumann_paroi&) la_cl.valeur(), ndeb, nfin, ncomp, mats, resu, semi_impl);
122 break;
123 case echange_global_impose:
124 ajouter_blocs_bords_<_TYPE_::CALC_FLUX_FACES_ECH_GLOB_IMP, Type_Double>((const Echange_global_impose&) la_cl.valeur(), ndeb, nfin, ncomp, mats, resu, semi_impl);
125 break;
126 case paroi_adiabatique:
127 ajouter_blocs_bords_<_TYPE_::CALC_FLUX_FACES_PAR_ADIAB, Type_Double>((const Neumann_paroi_adiabatique&) la_cl.valeur(), ndeb, nfin, ncomp, mats, resu, semi_impl);
128 break;
129 case echange_externe_impose:
130 ajouter_blocs_bords_ < Type_Double > ((const Echange_externe_impose&) la_cl.valeur(), ndeb, nfin, num_cl, ncomp, frontiere_dis, mats, resu, semi_impl);
131 break;
132 case periodique:
133 ajouter_blocs_bords_ < Type_Double > ((const Periodique&) la_cl.valeur(), ndeb, nfin, ncomp, frontiere_dis, mats, resu, semi_impl);
134 break;
135 default:
136 Cerr << "On ne reconnait pas la condition limite : " << la_cl.valeur() << " , dans Iterateur_VDF_Elem<_TYPE_>::ajouter_bords" << finl;
138 break;
139 }
140 }
141}
142
143template<class _TYPE_> template<typename Type_Double>
144void Iterateur_VDF_Elem<_TYPE_>::ajouter_blocs_interne(const int N, matrices_t mats, DoubleTab& resu, const tabs_t& semi_impl) const
145{
146 const DoubleTab& donnee = semi_impl.count(nom_ch_inco_) ? semi_impl.at(nom_ch_inco_) : le_champ_convecte_ou_inc->valeurs();
147 Type_Double flux(N), aii(N * (multiscalar_diff_ ? N : 1)), ajj(N * (multiscalar_diff_ ? N : 1)), aef(N);
148 const int ndeb = le_dom->premiere_face_int(), nfin = le_dom->nb_faces(), Mv = le_ch_v ? le_ch_v->valeurs().line_size() : N;
149 for (int face = ndeb; face < nfin; face++)
150 {
151 flux_evaluateur.flux_faces_interne(donnee, face, flux);
152 const int e0 = elem(face, 0), e1 = elem(face, 1);
153 // second membre
154 for (int k = 0; k < N; k++)
155 {
156 resu(e0, k) += flux[k];
157 resu(e1, k) -= flux[k];
158 }
159 }
160
161 Matrice_Morse *m_vit = (mats.count("vitesse") && is_convective_op()) ? mats.at("vitesse") : nullptr, *mat = (!is_pb_multiphase() && mats.count(nom_ch_inco_)) ? mats.at(nom_ch_inco_) : nullptr;
162 VectorDeriv d_cc;
163 fill_derivee_cc(mats, semi_impl, d_cc);
164
165 //derivatives: velocity
166 if (m_vit)
167 for (int face = ndeb; face < nfin; face++)
168 {
169 flux_evaluateur.coeffs_faces_interne_bloc_vitesse(donnee, face, aef);
170 for (int i = 0; i < 2; i++)
171 for (int n = 0, m = 0; n < N; n++, m += (Mv > 1))
172 (*m_vit)(N * elem(face, i) + n, Mv * face + m) += (i ? -1.0 : 1.0) * aef(n);
173 }
174
175 //derivatives: convected field
176 if (mat || d_cc.size() > 0)
177 for (int face = ndeb; face < nfin; face++)
178 {
179 flux_evaluateur.coeffs_faces_interne(face, aii, ajj);
180 fill_coeffs_matrices(face, 1.0 /* coeff */, aii, ajj, mat, d_cc);
181 }
182}
183
184template<class _TYPE_> template<bool should_calc_flux, typename Type_Double, typename BC>
185void Iterateur_VDF_Elem<_TYPE_>::ajouter_blocs_bords_(const BC& cl, const int ndeb, const int nfin, const int N, matrices_t mats, DoubleTab& resu, const tabs_t& semi_impl) const
186{
187 constexpr bool is_Neum_paroi_adiab = std::is_same<BC, Neumann_paroi_adiabatique>::value;
188
189 constexpr bool is_scal_imp = std::is_same<BC, Scalaire_impose_paroi>::value;
190 constexpr bool is_neum_paroi = std::is_same<BC, Neumann_paroi>::value;
191 constexpr bool is_paroi_contact = std::is_same<BC, Echange_global_impose>::value;
192
193 const bool is_Temp_impose_flux_parietal = is_scal_imp && corr_flux_parietal_ && !is_conv_op_;
194 const bool is_Neumann_flux_parietal = is_neum_paroi && corr_flux_parietal_ && !is_conv_op_;
195 const bool is_paroi_contact_flux_parietal = is_paroi_contact && corr_flux_parietal_ && !is_conv_op_;
196
197 if (should_calc_flux)
198 {
199 if (is_Neum_paroi_adiab)
200 Process::exit(); // Stop here :-)
201
202 const DoubleTab& donnee = semi_impl.count(nom_ch_inco_) ? semi_impl.at(nom_ch_inco_) : le_champ_convecte_ou_inc->valeurs(),
203 val_b = sub_type(Champ_Face_base, le_champ_convecte_ou_inc.valeur()) ? DoubleTab() :
204 (use_base_val_b_ ? le_champ_convecte_ou_inc->Champ_base::valeur_aux_bords() : le_champ_convecte_ou_inc->valeur_aux_bords()); // if the associated field is a champ_face, then we are in a divergence operator
205
206 Matrice_Morse *mat = (!is_pb_multiphase() && mats.count(nom_ch_inco_)) ? mats.at(nom_ch_inco_) : nullptr;
207 VectorDeriv d_cc;
208
209 // XXX Corentin, November 2023: for the case with parietal flux
210 // TODO FIXME: this only works with a scalaire_impose_paroi BC; handle paroi_temperature_imposee properly
211 if (is_Temp_impose_flux_parietal || is_Neumann_flux_parietal || is_paroi_contact_flux_parietal)
212 {
213 fill_derivee_cc(mats, semi_impl, d_cc);
214 const DoubleTab& donnee2 = is_pb_multiphase() ? le_champ_convecte_ou_inc->valeurs() : donnee ; // Always try to implicitate the parietal flux in multiphase lol
215 mat = mats.count(nom_ch_inco_) ? mats.at(nom_ch_inco_) : nullptr; // Always try to implicitate the parietal flux in multiphase lol
216 ajouter_blocs_bords_flux_parietal_<Type_Double, BC>(cl, ndeb, nfin, N, donnee2, resu, mat, d_cc, semi_impl);
217 }
218 else
219 {
220 int e, Mv = le_ch_v ? le_ch_v->valeurs().line_size() : N;
221 Type_Double flux(N), aii(N * (multiscalar_diff_ ? N : 1)), ajj(N * (multiscalar_diff_ ? N : 1)), aef(N);
222 for (int face = ndeb; face < nfin; face++)
223 {
224 flux_evaluateur.flux_face(donnee, val_b, face, cl, ndeb, flux); // Generic code
225 fill_flux_tables_(face, N, 1.0 /* coeff */, flux, resu);
226 }
227
228 Matrice_Morse *m_vit = (mats.count("vitesse") && is_convective_op()) ? mats.at("vitesse") : nullptr;
229
230 fill_derivee_cc(mats, semi_impl, d_cc);
231
232 //derivatives: velocity
233 if (m_vit)
234 {
235 const IntTab *fcl_v = le_ch_v ? &ref_cast(Champ_Face_base, le_ch_v.valeur()).fcl() : nullptr;
236 for (int f = ndeb; f < nfin; f++)
237 if ((*fcl_v)(f, 0) < 2)
238 {
239 flux_evaluateur.coeffs_face_bloc_vitesse(donnee, val_b, f, cl, ndeb, aef);
240 for (int i = 0; i < 2; i++)
241 if ((e = elem(f, i)) >= 0)
242 for (int n = 0, m = 0; n < N; n++, m += (Mv > 1))
243 (*m_vit)(N * e + n, Mv * f + m) += (i ? -1.0 : 1.0) * aef(n);
244 }
245 }
246
247 //derivatives: convected field
248 if (mat || d_cc.size() > 0)
249 for (int face = ndeb; face < nfin; face++)
250 {
251 flux_evaluateur.coeffs_face(face, ndeb, cl, aii, ajj); // Generic code
252 fill_coeffs_matrices(face, aii, ajj, mat, d_cc);
253 }
254 }
255 }
256}
257
258template<class _TYPE_> template<typename Type_Double>
259void Iterateur_VDF_Elem<_TYPE_>::ajouter_blocs_bords_(const Periodique& cl, const int ndeb, const int nfin, const int N, const Front_VF& frontiere_dis,
260 matrices_t mats, DoubleTab& resu, const tabs_t& semi_impl) const
261{
262 DoubleTab& flux_bords = op_base->flux_bords();
263 if (_TYPE_::CALC_FLUX_FACES_PERIO)
264 {
265 const DoubleTab& donnee = semi_impl.count(nom_ch_inco_) ? semi_impl.at(nom_ch_inco_) : le_champ_convecte_ou_inc->valeurs();
266
267 // Luis: adding the multiscalar_diff option in periodic BCs
268 Type_Double flux(N), aii(N * (multiscalar_diff_ ? N : 1)), ajj(N * (multiscalar_diff_ ? N : 1)), aef(N);
269 for (int face = ndeb; face < nfin; face++)
270 {
271 const int e0 = elem(face, 0), e1 = elem(face, 1);
272 flux_evaluateur.flux_face(donnee, donnee, face, cl, ndeb, flux); // note: donnee appears twice intentionally
273
274 for (int n = 0; n < N; n++)
275 {
276 if (e0 > -1)
277 {
278 resu(e0, n) += 0.5 * flux[n];
279 if (face < (ndeb + frontiere_dis.nb_faces() / 2)) flux_bords(face, n) += flux[n];
280 }
281 if (e1 > -1)
282 {
283 resu(e1, n) -= 0.5 * flux[n];
284 if ((ndeb + frontiere_dis.nb_faces() / 2) <= face) flux_bords(face, n) -= flux[n];
285 }
286 }
287 }
288
289 Matrice_Morse *m_vit = mats.count("vitesse") ? mats.at("vitesse") : nullptr, *mat = (!is_pb_multiphase() && mats.count(nom_ch_inco_)) ? mats.at(nom_ch_inco_) : nullptr;
290 VectorDeriv d_cc;
291 fill_derivee_cc(mats, semi_impl, d_cc);
292
293 //derivatives: velocity
294 if (m_vit)
295 for (int face = ndeb; face < nfin; face++)
296 {
297 const int e0 = elem(face, 0), e1 = elem(face, 1);
298 flux_evaluateur.coeffs_face_bloc_vitesse(donnee, DoubleTab(), face, cl, ndeb, aef);
299 if (e0 > -1)
300 for (int i = 0; i < N; i++)
301 if (face < (ndeb + frontiere_dis.nb_faces() / 2)) (*m_vit)(e0 * N + i, face * N + i) += aef[i];
302 if (e1 > -1)
303 for (int i = 0; i < N; i++)
304 if ((ndeb + frontiere_dis.nb_faces() / 2) <= face) (*m_vit)(e1 * N + i, face * N + i) -= aef[i];
305 }
306
307 //derivatives: convected field
308 if (mat || d_cc.size() > 0)
309 for (int face = ndeb; face < nfin; face++)
310 {
311 flux_evaluateur.coeffs_face(face, ndeb, cl, aii, ajj);
312 fill_coeffs_matrices(face, 0.5 /* coeff */, aii, ajj, mat, d_cc);
313 }
314 }
315}
316
317template<class _TYPE_> template<typename Type_Double>
318void Iterateur_VDF_Elem<_TYPE_>::ajouter_blocs_bords_(const Echange_externe_impose& cl, const int ndeb, const int nfin, const int num_cl, const int N, const Front_VF& frontiere_dis,
319 matrices_t mats, DoubleTab& resu, const tabs_t& semi_impl) const
320{
321 if (_TYPE_::CALC_FLUX_FACES_ECH_EXT_IMP)
322 {
323 // If the method is handled in FT, return
324 const bool calculated_in_FT = ajouter_blocs_bords_echange_ext_FT_TCL<Type_Double>(cl, ndeb, nfin, num_cl, N, frontiere_dis, mats, resu, semi_impl);
325 if ( calculated_in_FT ) return;
326
327 // Otherwise, GO!
328 const DoubleTab& donnee = semi_impl.count(nom_ch_inco_) ? semi_impl.at(nom_ch_inco_) : le_champ_convecte_ou_inc->valeurs();
329
330 Type_Double flux(N), aii(N * (multiscalar_diff_ ? N : 1)), ajj(N * (multiscalar_diff_ ? N : 1)), aef(N);
331 int boundary_index = -1;
332 if (le_dom->front_VF(num_cl).le_nom() == frontiere_dis.le_nom())
333 boundary_index = num_cl;
334
335 int e, Mv = le_ch_v ? le_ch_v->valeurs().line_size() : N;
336 for (int face = ndeb; face < nfin; face++)
337 {
338 const int local_face = le_dom->front_VF(boundary_index).num_local_face(face);
339 flux_evaluateur.flux_face(donnee, boundary_index, face, local_face, cl, ndeb, flux);
340 fill_flux_tables_(face, N, 1.0 /* coeff */, flux, resu);
341 }
342
343 Matrice_Morse *m_vit = (mats.count("vitesse") && is_convective_op()) ? mats.at("vitesse") : nullptr, *mat = (!is_pb_multiphase() && mats.count(nom_ch_inco_)) ? mats.at(nom_ch_inco_) : nullptr;
344 VectorDeriv d_cc;
345 fill_derivee_cc(mats, semi_impl, d_cc);
346
347 //derivatives: velocity
348 if (m_vit)
349 {
350 DoubleTab val_b = use_base_val_b_ ? le_champ_convecte_ou_inc->Champ_base::valeur_aux_bords() : le_champ_convecte_ou_inc->valeur_aux_bords();
351 for (int face = ndeb; face < nfin; face++)
352 {
353 const int local_face = le_dom->front_VF(boundary_index).num_local_face(face);
354 flux_evaluateur.coeffs_face_bloc_vitesse(donnee, val_b, boundary_index, face, local_face, cl, ndeb, aef);
355
356 for (int i = 0; i < 2; i++)
357 if ((e = elem(face, i)) >= 0)
358 for (int n = 0, m = 0; n < N; n++, m += (Mv > 1)) (*m_vit)(N * e + n, Mv * face + m) += (i ? -1.0 : 1.0) * aef(n);
359 }
360 }
361
362 //derivatives: convected field
363 if (mat || d_cc.size() > 0)
364 for (int face = ndeb; face < nfin; face++)
365 {
366 const int local_face = le_dom->front_VF(boundary_index).num_local_face(face);
367 flux_evaluateur.coeffs_face(donnee, boundary_index, face, local_face, ndeb, cl, aii, ajj);
368 fill_coeffs_matrices(face, aii, ajj, mat, d_cc); // XXX: Attention Yannick, for d_cc this is not exactly as before... N and M...
369 }
370 }
371}
372
373template<class _TYPE_>
374inline void Iterateur_VDF_Elem<_TYPE_>::fill_derivee_cc(matrices_t mats, const tabs_t& semi_impl, VectorDeriv& d_cc) const
375{
376 //list of derivatives of cc to fill in: pairs (derivative of cc, matrix, number of variable components)
377 if (is_pb_multiphase() && is_convective_op() && !semi_impl.count(le_champ_convecte_ou_inc->le_nom().getString()))
378 {
379 for (auto &i_m : mats)
380 if (le_champ_convecte_ou_inc->derivees().count(i_m.first))
381 d_cc.push_back(std::make_tuple(&le_champ_convecte_ou_inc->derivees().at(i_m.first), i_m.second, op_base->equation().probleme().get_champ(i_m.first.c_str()).valeurs().line_size()));
382 }
383 else assert(d_cc.size() == 0);
384}
385
386template<class _TYPE_> template<typename Type_Double>
387inline void Iterateur_VDF_Elem<_TYPE_>::fill_coeffs_matrices(const int f, const double coeff, Type_Double& aii, Type_Double& ajj, Matrice_Morse *mat, VectorDeriv& d_cc) const
388{
389 const int N = multiscalar_diff_ ? int(sqrt(aii.size_array())) : aii.size_array();
390 if (mat)
391 {
392 for (int i = 0; i < 2; i++)
393 for (int j = 0, e = elem(f, i); j < 2; j++)
394 for (int n = 0, eb = elem(f, j); n < N; n++)
395 for (int m = (multiscalar_diff_ ? 0 : n); m < (multiscalar_diff_ ? N : n + 1); m++)
396 (*mat)(N * e + n, N * eb + m) += (i == j ? 1.0 : -1.0) * coeff * (j ? ajj[multiscalar_diff_ ? N * n + m : n] : aii[multiscalar_diff_ ? N * n + m : n]);
397 }
398 else
399 for (auto &&d_m_i : d_cc)
400 for (int i = 0; i < 2; i++)
401 for (int j = 0, e = elem(f, i); j < 2; j++)
402 {
403 const int M = std::get<2> (d_m_i);
404 const DoubleTab& d_var_cc = *std::get<0> (d_m_i);
405 Matrice_Morse& d_var_operateur = *std::get<1> (d_m_i);
406
407 for (int n = 0, m = 0, eb = elem(f, j); n < N; n++, m += (M > 1))
408 d_var_operateur(N * e + n, M * eb + m) += (i == j ? 1.0 : -1.0) * coeff * (j ? ajj[n] : aii[n]) * d_var_cc(eb, m);
409 }
410}
411
412template<class _TYPE_> template<typename Type_Double>
413inline void Iterateur_VDF_Elem<_TYPE_>::fill_coeffs_matrices(const int face, Type_Double& aii, Type_Double& ajj, Matrice_Morse *mat, VectorDeriv& d_cc) const
414{
415 const int e0 = elem(face, 0), e1 = elem(face, 1);
416 const int N = multiscalar_diff_ ? int(sqrt(aii.size_array())) : aii.size_array();
417
418 if (mat)
419 {
420 if (e0 > -1)
421 for (int n = 0; n < N; n++)
422 for (int m = (multiscalar_diff_ ? 0 : n); m < (multiscalar_diff_ ? N : n + 1); m++)
423 (*mat)(e0 * N + n, e0 * N + m) += aii[multiscalar_diff_ ? N * n + m : n];
424 if (e1 > -1)
425 for (int n = 0; n < N; n++)
426 for (int m = (multiscalar_diff_ ? 0 : n); m < (multiscalar_diff_ ? N : n + 1); m++)
427 (*mat)(e1 * N + n, e1 * N + m) += ajj[multiscalar_diff_ ? N * n + m : n];
428 }
429 else
430 for (auto &&d_m_i : d_cc)
431 {
432 const int M = std::get<2> (d_m_i);
433 const DoubleTab& d_var_cc = *std::get<0> (d_m_i);
434 Matrice_Morse& d_var_operateur = *std::get<1> (d_m_i);
435
436 if (e0 > -1)
437 for (int n = 0, m = 0; n < N; n++, m += (M > 1))
438 {
439 const int i0 = N * e0 + n;
440 d_var_operateur(i0, i0) += aii[n] * d_var_cc(e0, m);
441 }
442 if (e1 > -1)
443 for (int n = 0, m = 0; n < N; n++, m += (M > 1))
444 {
445 const int j0 = M * e1 + m;
446 d_var_operateur(j0, j0) += ajj[n] * d_var_cc(e1, m);
447 }
448 }
449}
450
451#include <Iterateur_VDF_Elem_bis.tpp>
452#include <Iterateur_VDF_Elem_FT_TCL.tpp> // for FT ...
453#include <Iterateur_VDF_Elem_Multiphase_Parietal.tpp> // for Multiphase part if wall vapour ...
454
455#endif /* Iterateur_VDF_Elem_TPP_included */
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
Dirichlet_entree_fluide This class represents a boundary condition imposing a quantity.
Classe Dirichlet_loi_paroi Base class for imposed values in a boundary condition of the turbulence eq...
Dirichlet_paroi_defilante Imposes the wall velocity in an equation of type Navier_Stokes.
Dirichlet_paroi_fixe Represents a fixed wall in a Navier-Stokes type equation.
Classe Echange_externe_impose: This class represents the special case of the class.
Classe Echange_global_impose This class represents the special case of the class.
class Front_VF
Definition Front_VF.h:36
int nb_faces() const
Definition Front_VF.h:53
int num_premiere_face() const
Definition Front_VF.h:63
const Nom & le_nom() const override
Returns the name of the geometric boundary.
void ajouter_contribution_autre_pb(const DoubleTab &inco, Matrice_Morse &matrice, const Cond_lim &la_cl, std::map< int, std::pair< int, int > > &) const override
void ajouter_blocs(matrices_t mats, DoubleTab &secmem, const tabs_t &semi_impl) const override
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
Classe Neumann_paroi_adiabatique This boundary condition corresponds to an adiabatic wall in a.
Classe Neumann_paroi This boundary condition corresponds to an imposed flux for the.
Neumann_sortie_libre This class represents an open boundary without imposed velocity.
class Periodique This class represents a periodic boundary condition.
Definition Periodique.h:31
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
Scalaire_impose_paroi Imposes a scalar at the wall in a Convection-Diffusion equation for a scalar.
Symetrie On symmetry faces, the following properties hold:
Definition Symetrie.h:37
_SIZE_ size_array() const
_TYPE_ * addr()
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ size() const
Definition TRUSTVect.tpp:45
int line_size() const
Definition TRUSTVect.tpp:67