TrioCFD 1.9.8
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.: on va faire += sur des items virtuels, initialiser les cases : sinon risque que les cases soient invalides ou non initialisees
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 //derivees : vitesse
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 //derivees : champ convecte
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(); // On bloque ici :-)
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()); // si le champ associe est un champ_face, alors on est dans un operateur de div
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 , Novembre 2023 : pour le cas avec flux_parietal
210 // TODO FIXME : ceci ne marche qu'avec une CL scalaire_impose_paroi, faire le bon truc pour paroi_temperature_imposee ?
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 ; // On tente de toujours impliciter le flux parietal en pb multi lol
215 mat = mats.count(nom_ch_inco_) ? mats.at(nom_ch_inco_) : nullptr; // On tente de toujours impliciter le flux parietal en pb multi 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 //derivees : vitesse
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 //derivees : champ convecte
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 : je rajoute l'option multiscalar_diff dans les CL périodiques
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); // attention 2 fois donnee
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 //derivees : vitesse
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 //derivees : champ convecte
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 // Si la method est faite dans FT, on sort
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 // Sinon, 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 //derivees : vitesse
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 //derivees : champ convecte
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 pour d_cc c'est pas tout a fait comme avant ... N et 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 //liste des derivees de cc a renseigner : couples (derivee de cc, matrice, nb de compos de la variable)
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> // pour FT ...
453#include <Iterateur_VDF_Elem_Multiphase_Parietal.tpp> // pour partie Multiphase si vap paroi ...
454
455#endif /* Iterateur_VDF_Elem_TPP_included */
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
classe Dirichlet_entree_fluide Cette classe represente une condition aux limite imposant une grandeur
Classe Dirichlet_loi_paroi Classe de base pour les valeurs impose pour une condition aux limites des ...
classe Dirichlet_paroi_defilante Impose la vitesse de paroi dnas une equation de type Navier_Stokes.
classe Dirichlet_paroi_fixe Represente une paroi immobile dans une equation de type Navier_Stokes.
Classe Echange_externe_impose: Cette classe represente le cas particulier de la classe.
Classe Echange_global_impose Cette classe represente le cas particulier de la classe.
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
Renvoie le nom de la frontiere geometrique.
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
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
Classe Neumann_paroi_adiabatique Cette condition limite correspond a une paroi adiabatique dans une.
Classe Neumann_paroi Cette condition limite correspond a un flux impose pour l'equation de.
classe Neumann_sortie_libre Cette classe represente une frontiere ouverte sans vitesse imposee
classe Periodique Cette classe represente une condition aux limites periodique.
Definition Periodique.h:31
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
classe Scalaire_impose_paroi Impose un scalaire a la paroi dans une equation de type Convection-Difus...
classe Symetrie Sur les faces de symetrie on a les proprietes suivantes:
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