TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Conv_VDF_base.cpp
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#include <Modifier_pour_fluide_dilatable.h>
17#include <Discretisation_base.h>
18#include <Masse_ajoutee_base.h>
19#include <Op_Conv_VDF_base.h>
20#include <Champ_Face_VDF.h>
21#include <Pb_Multiphase.h>
22#include <Matrix_tools.h>
23#include <Array_tools.h>
24#include <TRUSTTrav.h>
25
26Implemente_base(Op_Conv_VDF_base,"Op_Conv_VDF_base",Operateur_Conv_base);
27
28Sortie& Op_Conv_VDF_base::printOn(Sortie& s ) const { return s << que_suis_je() ; }
29
31{
32 if (sub_type(Masse_Multiphase, equation())) //convection dans Masse_Multiphase -> champs de debit / titre
33 {
34 const Pb_Multiphase& pb = ref_cast(Pb_Multiphase, equation().probleme());
35 noms_cc_phases_.dimensionner(pb.nb_phases()), cc_phases_.resize(pb.nb_phases());
36 noms_vd_phases_.dimensionner(pb.nb_phases()), vd_phases_.resize(pb.nb_phases());
37 noms_x_phases_.dimensionner(pb.nb_phases()), x_phases_.resize(pb.nb_phases());
38 for (int i = 0; i < pb.nb_phases(); i++)
39 {
40 noms_cc_phases_[i] = Nom("debit_") + pb.nom_phase(i);
41 noms_vd_phases_[i] = Nom("vitesse_debitante_") + pb.nom_phase(i);
42 noms_x_phases_[i] = Nom("titre_") + pb.nom_phase(i);
43 }
44 }
45 return s;
46}
47
48inline void eval_fluent(const double psc, const int num1, const int num2, const int n, DoubleTab& fluent)
49{
50 if (psc >= 0) fluent(num2, n) += psc;
51 else fluent(num1, n) -= psc;
52}
53
55{
57 iter_->completer_();
58}
59
61{
62 return iter_->impr(os);
63}
64
66{
67 Operateur_Conv_base::preparer_calcul(); /* ne fait rien */
68 iter_->set_convective_op_pb_type(true /* convective op */, sub_type(Pb_Multiphase, equation().probleme()));
69}
70
72{
73 if (sub_type(Pb_Multiphase, equation().probleme())) equation().init_champ_convecte();
74
76 const Champ_Inc_base& cc = equation().has_champ_convecte() ? equation().champ_convecte() : (le_champ_inco ? le_champ_inco.valeur() : equation().inconnue());
77 iter_->associer_champ_convecte_ou_inc(cc, &vitesse());
78 iter_->set_name_champ_inco(le_champ_inco ? nom_inconnue() : cc.le_nom().getString());
79}
80
82{
84 const Champ_Inc_base& cc = le_champ_inco ? le_champ_inco.valeur() : equation().inconnue();
85 iter_->associer_champ_convecte_ou_inc(cc, &vitesse());
86 iter_->set_name_champ_inco(le_champ_inco ? nom_inconnue() : cc.le_nom().getString());
87}
88
89void Op_Conv_VDF_base::associer_champ_temp(const Champ_Inc_base& ch_unite, bool use_base) const
90{
91 const_cast<OWN_PTR(Iterateur_VDF_base)&>(iter_)->associer_champ_convecte_ou_inc(ch_unite, nullptr, use_base);
92}
93
94void Op_Conv_VDF_base::dimensionner_blocs_elem(matrices_t mats, const tabs_t& semi_impl) const
95{
96 const Domaine_VDF& domaine = iter_->domaine();
97 const IntTab& f_e = domaine.face_voisins();
98 int i, j, e, eb, f, n, N = equation().inconnue().valeurs().line_size();
99 const int hcc = equation().has_champ_convecte();
100 const Champ_Inc_base& cc = hcc ? equation().champ_convecte() : equation().inconnue();
101
102 for (auto &&i_m : mats)
103 if (i_m.first == "vitesse" || (!hcc && i_m.first == cc.le_nom()) || (cc.derivees().count(i_m.first) && !semi_impl.count(cc.le_nom().getString())))
104 {
105 Matrice_Morse mat;
106 Stencil stencil(0, 2);
107
108 int m, M = equation().probleme().get_champ(i_m.first.c_str()).valeurs().line_size();
109 if (i_m.first == "vitesse") /* vitesse */
110 {
111 const IntTab& fcl_v = ref_cast(Champ_Face_VDF, vitesse()).fcl();
112
113 for (f = 0; f < domaine.nb_faces_tot(); f++)
114 if (fcl_v(f, 0) < 2)
115 for (i = 0; i < 2; i++)
116 if ((e = f_e(f, i)) >= 0 && e < domaine.nb_elem_tot())
117 for (n = 0; n < N; n++) stencil.append_line(N * e + n, M * f + n * (M > 1));
118 }
119 else for (f = 0; f < domaine.nb_faces_tot(); f++)
120 for (i = 0; i < 2; i++)
121 if ((e = f_e(f, i)) >= 0 && e < domaine.nb_elem_tot()) /* inconnues scalaires */
122 for (j = 0; j < 2; j++)
123 if ((eb = f_e(f, j)) >= 0)
124 for (n = 0, m = 0; n < N; n++, m += (M > 1)) stencil.append_line(N * e + n, M * eb + m);
125
126 tableau_trier_retirer_doublons(stencil);
127 const int nl = equation().inconnue().valeurs().size_totale(),
128 nc = i_m.first == "vitesse" ? vitesse().valeurs().size_totale() : (hcc ? cc.derivees().at(i_m.first).size_totale() : nl);
129 Matrix_tools::allocate_morse_matrix(nl, nc, stencil, mat);
130 i_m.second->nb_colonnes() ? *i_m.second += mat : *i_m.second = mat;
131 }
132}
133
134void Op_Conv_VDF_base::dimensionner_blocs_face(matrices_t matrices, const tabs_t& semi_impl) const
135{
136 const Domaine_VDF& domaine = iter_->domaine();
137 const Champ_Face_VDF& ch = ref_cast(Champ_Face_VDF, equation().inconnue());
138 const IntTab& f_e = domaine.face_voisins(), &e_f = domaine.elem_faces(), &fcl = ch.fcl();
139 const DoubleTab& inco = ch.valeurs();
140
141 const std::string& nom_inco = ch.le_nom().getString();
142 if (!matrices.count(nom_inco) || semi_impl.count(nom_inco)) return; //pas de bloc diagonal ou semi-implicite -> rien a faire
143 const Pb_Multiphase *pbm = sub_type(Pb_Multiphase, equation().probleme()) ? &ref_cast(Pb_Multiphase, equation().probleme()) : nullptr;
144 const Masse_ajoutee_base *corr = pbm && pbm->has_correlation("masse_ajoutee") ? &ref_cast(Masse_ajoutee_base, pbm->get_correlation("masse_ajoutee")) : nullptr;
145 Matrice_Morse& mat = *matrices.at(nom_inco), mat2;
146
147 //int e, eb, fb, N = equation().inconnue().valeurs().line_size();
148 // eb never used ? Warning Error on clang...
149 int e, fb, N = equation().inconnue().valeurs().line_size();
150 Stencil stencil(0, 2);
151
152
153 /* agit uniquement aux elements; diagonale omise */
154 for (int f = 0; f < domaine.nb_faces_tot(); f++)
155 if (f_e(f, 0) >= 0 && (f_e(f, 1) >= 0 || fcl(f, 0) == 3))
156 for (int i = 0; i < 2; i++)
157 if ((e = f_e(f, i)) >= 0)
158 for (int j = 0; j < 2; j++)
159 //if ((eb = f_e(f, j)) >= 0)
160 if (f_e(f, j) >= 0)
161 for (int k = 0; k < e_f.dimension(1); k++)
162 if ((fb = e_f(e, k)) >= 0)
163 if (fb < domaine.nb_faces() && fcl(fb, 0) < 2)
164 for (int n = 0; n < N; n++)
165 for (int m = (corr ? 0 : n); m < (corr ? N : n + 1); m++) stencil.append_line(N * fb + n, N * f + m);
166
167 tableau_trier_retirer_doublons(stencil);
168 Matrix_tools::allocate_morse_matrix(inco.size_totale(), inco.size_totale(), stencil, mat2);
169 mat.nb_colonnes() ? mat += mat2 : mat = mat2;
170}
171
172
173void Op_Conv_VDF_base::ajouter_blocs(matrices_t mats, DoubleTab& secmem, const tabs_t& semi_impl) const
174{
175 iter_->ajouter_blocs(mats, secmem, semi_impl);
176}
177
179{
180 const Domaine_VDF& domaine_VDF = iter_->domaine();
181 const Domaine_Cl_VDF& domaine_Cl_VDF = iter_->domaine_Cl();
182 const IntTab& face_voisins = domaine_VDF.face_voisins();
183 const DoubleVect& volumes = domaine_VDF.volumes();
184 const DoubleVect& face_surfaces = domaine_VDF.face_surfaces();
185 const DoubleTab& vit_associe = vitesse().valeurs();
186 const DoubleTab& vit= (vitesse_pour_pas_de_temps_?vitesse_pour_pas_de_temps_->valeurs(): vit_associe);
187 const int N = std::min(vit.line_size(), equation().inconnue().valeurs().line_size());
188 const DoubleTab* alp = sub_type(Pb_Multiphase, equation().probleme()) ? &ref_cast(Pb_Multiphase, equation().probleme()).equation_masse().inconnue().passe() : nullptr;
189 if (!fluent_.get_md_vector())
190 {
191 fluent_.resize(0, N);
192 domaine_VDF.domaine().creer_tableau_elements(fluent_);
193 }
194 fluent_ = 0;
195 // Remplissage du tableau fluent
196 double psc;
197 int num1, num2, face, elem1;
198
199 // On traite les bords
200 for (int n_bord = 0; n_bord < domaine_VDF.nb_front_Cl(); n_bord++)
201 {
202 const Cond_lim& la_cl = domaine_Cl_VDF.les_conditions_limites(n_bord);
203 if ( sub_type(Dirichlet_entree_fluide,la_cl.valeur()) || sub_type(Neumann_sortie_libre,la_cl.valeur()) )
204 {
205 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
206 num1 = le_bord.num_premiere_face();
207 num2 = num1 + le_bord.nb_faces();
208 for (face=num1; face<num2; face++)
209 for (int n = 0; n < N; n++)
210 {
211 psc = vit(face, n) * face_surfaces(face);
212 if ( (elem1 = face_voisins(face,0)) != -1)
213 {
214 if (psc < 0) fluent_(elem1, n) -= psc;
215 }
216 else // (elem2 != -1)
217 if (psc > 0) fluent_(face_voisins(face,1), n) += psc;
218 }
219 }
220 }
221
222 // Boucle sur les faces internes pour remplir fluent
223 const int domaine_VDF_nb_faces = domaine_VDF.nb_faces(), premiere_face = domaine_VDF.premiere_face_int();
224 for (face = premiere_face; face < domaine_VDF_nb_faces; face++)
225 for (int n = 0; n < N; n++)
226 {
227 psc = vit(face, n) * face_surfaces(face);
228 eval_fluent(psc, face_voisins(face, 0), face_voisins(face, 1), n, fluent_);
229 }
230
231 // Calcul du pas de temps de stabilite a partir du tableau fluent
232 if (vitesse().le_nom()=="rho_u" && equation().probleme().is_dilatable())
233 diviser_par_rho_si_dilatable(fluent_,equation().milieu());
234
235 const double alpha_min_dt = 1e-3; // avoid stupid time steps during vanishing phase
236 double dt_stab = 1.e30;
237 int domaine_VDF_nb_elem=domaine_VDF.nb_elem();
238 // dt_stab = min ( 1 / ( |U|/dx + |V|/dy + |W|/dz ) )
239 for (int num_poly=0; num_poly<domaine_VDF_nb_elem; num_poly++)
240 for (int n = 0; n < N; n++)
241 if ((!alp || (*alp)(num_poly, n) > alpha_min_dt))
242 {
243 double dt_elem = volumes(num_poly)/(fluent_(num_poly, n)+DMINFLOAT);
244 if (dt_elem<dt_stab) dt_stab = dt_elem;
245 }
246
247 dt_stab = Process::mp_min(dt_stab);
248
249 // astuce pour contourner le type const de la methode
250 Op_Conv_VDF_base& op =ref_cast_non_const(Op_Conv_VDF_base, *this);
251 op.fixer_dt_stab_conv(dt_stab);
252 return dt_stab;
253}
254
255// Calculation of local time: Vect of size number of faces of the domain This is the equivalent of "Op_Conv_VDF_base :: calculer_dt_stab ()"
256void Op_Conv_VDF_base::calculer_dt_local(DoubleTab& dt_face) const
257{
258 const Domaine_VDF& domaine_VDF = iter_->domaine();
259 const Domaine_Cl_VDF& domaine_Cl_VDF = iter_->domaine_Cl();
260 const DoubleVect& volumes_entrelaces= domaine_VDF.volumes_entrelaces();
261 const DoubleVect& face_surfaces = domaine_VDF.face_surfaces();
262 //const DoubleVect& vit= vitesse_pour_pas_de_temps_->valeurs();
263 const DoubleVect& vit=equation().inconnue().valeurs();
264 DoubleTrav fluent(volumes_entrelaces);
265
266 // Remplissage du tableau fluent
267 // On traite les bords
268 for (int n_bord = 0; n_bord < domaine_VDF.nb_front_Cl(); n_bord++)
269 {
270 const Cond_lim& la_cl = domaine_Cl_VDF.les_conditions_limites(n_bord);
271
272 if ( sub_type(Dirichlet_entree_fluide,la_cl.valeur()) || sub_type(Neumann_sortie_libre,la_cl.valeur()) )
273 {
274 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
275 const int num1 = le_bord.num_premiere_face(), num2 = num1 + le_bord.nb_faces();
276 for (int face = num1; face < num2; face++)
277 {
278 double value = vit[face]*face_surfaces(face);
279 if (value >0) fluent[face] = value;
280 else fluent[face] -= value;
281 }
282 }
283 }
284
285 // Boucle sur les faces internes pour remplir fluent
286 const int domaine_VDF_nb_faces = domaine_VDF.nb_faces(), premiere_face = domaine_VDF.premiere_face_int();
287 for (int face = premiere_face; face < domaine_VDF_nb_faces; face++)
288 {
289 const double value = vit[face]*face_surfaces(face);
290 if (value >0) fluent[face] = value;
291 else fluent[face] -= value;
292 }
293
294
295 // Calcul du pas de temps de stabilite a partir du tableau fluent
296 if (vitesse().le_nom()=="rho_u" && equation().probleme().is_dilatable())
297 diviser_par_rho_si_dilatable(fluent,equation().milieu());
298
299 dt_face=(volumes_entrelaces);
300 // Boucle sur les faces de bords
301 for (int n_bord=0; n_bord<domaine_VDF.nb_front_Cl(); n_bord++)
302 {
303 const Cond_lim& la_cl = domaine_Cl_VDF.les_conditions_limites(n_bord);
304 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
305 const int ndeb = le_bord.num_premiere_face(), nfin = ndeb + le_bord.nb_faces();
306 for (int num_face = ndeb; num_face < nfin; num_face++)
307 {
308 if( sup_strict(fluent[num_face], 1.e-16) ) dt_face(num_face)= volumes_entrelaces(num_face)/fluent[num_face];
309 else dt_face(num_face) = -1.;
310 }
311 }
312
313 // Boucle sur les faces internes
314 for (int num_face = premiere_face; num_face<domaine_VDF_nb_faces; num_face++)
315 {
316 if( sup_strict(fluent[num_face], 1.e-16) ) dt_face(num_face)= volumes_entrelaces(num_face)/fluent[num_face];
317 else dt_face(num_face) = -1.;
318 }
319
320 double max_dt_local= dt_face.mp_max_abs_vect();
321 const int taille = dt_face.size();
322 for(int i = 0; i < taille; i++)
323 if(! sup_strict(dt_face(i), 1.e-16)) dt_face(i) = max_dt_local;
324
325 dt_face.echange_espace_virtuel();
326
327 for (int n_bord = 0; n_bord < domaine_VDF.nb_front_Cl(); n_bord++)
328 {
329 const Cond_lim& la_cl = domaine_Cl_VDF.les_conditions_limites(n_bord);
330 if (sub_type(Periodique,la_cl.valeur()))
331 {
332 const Periodique& la_cl_perio = ref_cast(Periodique,la_cl.valeur());
333 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
334 const int nb_faces_bord = le_bord.nb_faces();
335 for (int ind_face = 0; ind_face < nb_faces_bord; ind_face++)
336 {
337 int ind_face_associee = la_cl_perio.face_associee(ind_face);
338 int face = le_bord.num_face(ind_face), face_associee = le_bord.num_face(ind_face_associee);
339 if (!est_egal(dt_face(face),dt_face(face_associee),1.e-8))
340 {
341 dt_face(face) = std::min(dt_face(face),dt_face(face_associee));
342 }
343 }
344 }
345 }
346 dt_face.echange_espace_virtuel();
347// dt_conv_locaux=dt_face;
348}
349
350// cf Op_Conv_VDF_base::calculer_dt_stab() pour choix de calcul de dt_stab
351void Op_Conv_VDF_base::calculer_pour_post(Champ_base& espace_stockage,const Nom& option,int comp) const
352{
353 if (Motcle(option)=="stabilite")
354 {
355 DoubleTab& es_valeurs = espace_stockage.valeurs();
356 es_valeurs = 1.e30;
357
358 const Domaine_VDF& domaine_VDF = iter_->domaine();
359 const Domaine_Cl_VDF& domaine_Cl_VDF = iter_->domaine_Cl();
360 const IntTab& face_voisins = domaine_VDF.face_voisins();
361 const DoubleVect& volumes = domaine_VDF.volumes();
362 const DoubleVect& face_surfaces = domaine_VDF.face_surfaces();
363 const DoubleVect& vit = vitesse().valeurs();
364 const int N = std::min(vit.line_size(), equation().inconnue().valeurs().line_size());
365 DoubleTrav fluent(domaine_VDF.domaine().nb_elem_tot(), N);
366 assert(N == 1); // en attendant de coder les boucles...
367
368 // Remplissage du tableau fluent
369 fluent = 0;
370 double psc;
371 int num1, num2, face, elem1;
372
373 // On traite les bords
374 for (int n_bord = 0; n_bord < domaine_VDF.nb_front_Cl(); n_bord++)
375 {
376 const Cond_lim& la_cl = domaine_Cl_VDF.les_conditions_limites(n_bord);
377 if ( sub_type(Dirichlet_entree_fluide,la_cl.valeur()) || sub_type(Neumann_sortie_libre,la_cl.valeur()) )
378 {
379 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
380 num1 = le_bord.num_premiere_face();
381 num2 = num1 + le_bord.nb_faces();
382 for (face = num1; face < num2; face++)
383 {
384 psc = vit[face]*face_surfaces(face);
385 if ( (elem1 = face_voisins(face,0)) != -1)
386 {
387 if (psc < 0) fluent[elem1] -= psc;
388 }
389 else // (elem2 != -1)
390 if (psc > 0) fluent[face_voisins(face,1)] += psc;
391 }
392 }
393 }
394
395 // Boucle sur les faces internes pour remplir fluent
396 const int domaine_VDF_nb_faces = domaine_VDF.nb_faces();
397 for (face = domaine_VDF.premiere_face_int(); face < domaine_VDF_nb_faces; face++)
398 {
399 psc = vit[face]*face_surfaces(face);
400 eval_fluent(psc,face_voisins(face,0),face_voisins(face,1),0,fluent);
401 }
402 //fluent.echange_espace_virtuel();
403 if (vitesse().le_nom()=="rho_u" && equation().probleme().is_dilatable())
404 diviser_par_rho_si_dilatable(fluent,equation().milieu());
405
406 const int domaine_VDF_nb_elem=domaine_VDF.nb_elem();
407 for (int num_poly=0; num_poly<domaine_VDF_nb_elem; num_poly++)
408 es_valeurs(num_poly) = volumes(num_poly)/(fluent[num_poly]+1.e-30);
409
410 //double dt_min = mp_min_vect(es_valeurs);
411 //assert(dt_min==calculer_dt_stab());
412 }
413 else
415}
416
418{
419 Motcle loc;
420 if (Motcle(option)=="stabilite") loc = "elem";
422 return loc;
423}
424
426{
428 Noms noms_compris;
429
430 if (sub_type(Masse_Multiphase, equation()))
431 {
432 const Pb_Multiphase& pb = ref_cast(Pb_Multiphase, equation().probleme());
433
434 for (int i = 0; i < pb.nb_phases(); i++)
435 {
436 noms_compris.add(noms_cc_phases_[i]);
437 noms_compris.add(noms_vd_phases_[i]);
438 noms_compris.add(noms_x_phases_[i]);
439 }
440 }
441 if (opt==DESCRIPTION)
442 Cerr<<" Op_Conv_VDF_base : "<< noms_compris <<finl;
443 else
444 nom.add(noms_compris);
445}
447{
448 Operateur_Conv_base::creer_champ(motlu); // Do nothing mais bon :-) Maybe some day it will
449 if (sub_type(Masse_Multiphase, equation())) //convection dans Masse_Multiphase -> champs de debit / titre
450 {
451 int i = noms_cc_phases_.rang(motlu), j = noms_vd_phases_.rang(motlu), k = noms_x_phases_.rang(motlu);
452 if (i >= 0 && !cc_phases_[i])
453 {
454 equation().discretisation().discretiser_champ("vitesse", equation().domaine_dis(), noms_cc_phases_[i], "kg/m2/s",dimension, 1, 0, cc_phases_[i]);
455 champs_compris_.ajoute_champ(cc_phases_[i]);
456 }
457 if (j >= 0 && !vd_phases_[j])
458 {
459 equation().discretisation().discretiser_champ("vitesse", equation().domaine_dis(), noms_vd_phases_[j], "m/s",dimension, 1, 0, vd_phases_[j]);
460 champs_compris_.ajoute_champ(vd_phases_[j]);
461 }
462 if (k >= 0 && !x_phases_[k])
463 {
464 equation().discretisation().discretiser_champ("temperature", equation().domaine_dis(), noms_x_phases_[k], "m/s",1, 1, 0, x_phases_[k]);
465 champs_compris_.ajoute_champ(x_phases_[k]);
466 }
467 }
468}
469
471{
472 Operateur_Conv_base::mettre_a_jour(temps); // Do nothing mais bon :-) Maybe some day it will
473
474 if (sub_type(Masse_Multiphase, equation())) //convection dans Masse_Multiphase -> champs de debit / titre
475 {
476 const Domaine_VDF& domaine = iter_->domaine();
477 const IntTab& f_e = domaine.face_voisins(), &e_f = domaine.elem_faces();
478 const Champ_Inc_base& cc = le_champ_inco ? le_champ_inco.valeur() : equation().champ_convecte();
479 const DoubleVect& pf = equation().milieu().porosite_face(), &pe = equation().milieu().porosite_elem(), &fs = domaine.face_surfaces(), &ve = domaine.volumes();
480 const DoubleTab& vit = vitesse().valeurs(), &vcc = cc.valeurs(), bcc = cc.valeur_aux_bords(), &xv = domaine.xv(), &xp = domaine.xp();
481 DoubleTab balp;
482 if (vd_phases_.size()) balp = equation().inconnue().valeur_aux_bords();
483
484 int i, e, f, d, D = dimension, n, m, N = vcc.line_size(), M = vit.line_size();
485 //DoubleTrav cc_f(N); //valeur du champ convecte aux faces
486
487 if (cc_phases_.size())
488 for (n = 0, m = 0; n < N; n++, m += (M > 1))
489 if (cc_phases_[n]) /* mise a jour des champs de debit */
490 {
491 Champ_Face_VDF& c_ph = ref_cast(Champ_Face_VDF, cc_phases_[n].valeur());
492 DoubleTab& v_ph = c_ph.valeurs();
493 for (f = 0; f < domaine.nb_faces(); v_ph(f) *= vit(f, m) * pf(f), f++)
494 for (v_ph(f) = 0, i = 0; i < 2; i++) v_ph(f) += (1. + (vit(f, m) * (i ? -1 : 1) >= 0 ? 1. : -1.) * 1.0 /* FIXME : amont */) / 2 * ((e = f_e(f, i)) >= 0 ? vcc(e, n) : bcc(f, n));
495 c_ph.changer_temps(temps);
496 }
497
498 if (vd_phases_.size())
499 for (n = 0, m = 0; n < N; n++, m += (M > 1))
500 if (vd_phases_[n]) /* mise a jour des champs de vitesse debitante */
501 {
502 const DoubleTab& alp = equation().inconnue().valeurs();
503 Champ_Face_VDF& c_ph = ref_cast(Champ_Face_VDF, vd_phases_[n].valeur());
504 DoubleTab& v_ph = c_ph.valeurs();
505 /* on remplit la partie aux faces, puis on demande au champ d'interpoler aux elements */
506 for (f = 0; f < domaine.nb_faces(); v_ph(f) *= vit(f, m) * pf(f), f++)
507 for (v_ph(f) = 0, i = 0; i < 2; i++) v_ph(f) += (1. + (vit(f, m) * (i ? -1 : 1) >= 0 ? 1. : -1.) * 1.0 /* FIXME : amont */) / 2 * ((e = f_e(f, i)) >= 0 ? alp(e, n) : balp(f, n));
508 c_ph.changer_temps(temps);
509 }
510
511 DoubleTrav G(N), v(N, D);
512 double Gt;
513 if (x_phases_.size())
514 for (e = 0; e < domaine.nb_elem(); e++) //titre : aux elements
515 {
516 for (v = 0, i = 0; i < e_f.dimension(1) && (f = e_f(e, i)) >= 0; i++)
517 for (n = 0; n < N; n++)
518 for (d = 0; d < D; d++)
519 v(n, d) += fs(f) * pf(f) * (xv(f, d) - xp(e, d)) * (e == f_e(f, 0) ? 1 : -1) * vit(f, n) / (pe(e) * ve(e));
520 for (Gt = 0, n = 0; n < N; Gt += G(n), n++) G(n) = vcc(e, n) * sqrt(domaine.dot(&v(n, 0), &v(n, 0)));
521 for (n = 0; n < N; n++)
522 if (x_phases_[n]) x_phases_[n]->valeurs()(e) = Gt ? G(n) / Gt : 0;
523 }
524 if (x_phases_.size())
525 for (n = 0; n < N; n++)
526 if (x_phases_[n]) x_phases_[n]->changer_temps(temps);
527 }
528}
class Champ_Face_VDF Cette classe sert a representer un champ vectoriel dont on ne calcule
const IntTab & fcl() const
Classe Champ_Inc_base.
double changer_temps(const double temps) override
Fixe le temps du champ.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
const tabs_t & derivees() const
DoubleTab valeur_aux_bords() const override
renvoie la valeur du champ aux faces de bord
virtual DoubleTab & valeurs()=0
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
virtual void creer_champ(const Motcle &motlu)=0
virtual void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const =0
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
void discretiser_champ(const Motcle &directive, const Domaine_dis_base &z, const Nom &nom, const Nom &unite, int nb_comp, int nb_pas_dt, double temps, OWN_PTR(Champ_Inc_base)&champ, const Nom &sous_type=NOM_VIDE) const
int_t nb_elem_tot() const
Definition Domaine.h:132
virtual void creer_tableau_elements(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
creation d'un tableau parallele de valeurs aux elements.
Definition Domaine.cpp:851
class Domaine_Cl_VDF
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
class Domaine_VDF
Definition Domaine_VDF.h:64
virtual const DoubleVect & face_surfaces() const
Definition Domaine_VF.h:51
int nb_faces() const
renvoie le nombre global de faces.
Definition Domaine_VF.h:471
DoubleVect & volumes_entrelaces()
Definition Domaine_VF.h:99
double volumes(int i) const
Definition Domaine_VF.h:113
int premiere_face_int() const
une face est interne ssi elle separe deux elements.
Definition Domaine_VF.h:463
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
int nb_front_Cl() const
const Domaine & domaine() const
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
virtual int has_champ_convecte() const
const Discretisation_base & discretisation() const
Renvoie la discretisation associee a l'equation.
virtual const Champ_Inc_base & inconnue() const =0
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
virtual void init_champ_convecte() const
virtual Champ_Inc_base & champ_convecte() const
const Nom & le_nom() const override
Renvoie le nom du champ.
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
int num_face(const int) const
Definition Front_VF.h:68
classe Masse_Multiphase Cas particulier de Convection_Diffusion_std pour un fluide quasi conpressible
classe Masse_ajoutee_base masse ajoutee de la forme
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
int nb_colonnes() const override
Return local number of columns (=size on the current proc).
static void allocate_morse_matrix(const int nb_lines, const int nb_columns, const Stencil &stencil, Matrice_Morse &matrix, const bool &attach_stencil_to_matrix=false)
DoubleVect & porosite_elem()
Definition Milieu_base.h:58
DoubleVect & porosite_face()
Definition Milieu_base.h:62
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
virtual Motcle get_localisation_pour_post(const Nom &option) const
Definition MorEqn.cpp:43
virtual void calculer_pour_post(Champ_base &espace_stockage, const Nom &option, int comp) const
Definition MorEqn.cpp:35
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
classe Neumann_sortie_libre Cette classe represente une frontiere ouverte sans vitesse imposee
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const std::string & getString() const
Definition Nom.h:92
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
static int dimension
Definition Objet_U.h:99
friend class Sortie
Definition Objet_U.h:75
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual const Nom & le_nom() const
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Objet_U.cpp:319
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
class Op_Conv_VDF_base Classe de base des operateurs de convection VDF
const OWN_PTR(Iterateur_VDF_base) &get_iter() const
void creer_champ(const Motcle &) override
virtual const Champ_base & vitesse() const =0
void completer() override
Associe l'operateur au domaine_dis, le domaine_Cl_dis, et a l'inconnue de son equation.
void dimensionner_blocs_elem(matrices_t, const tabs_t &) const
void calculer_dt_local(DoubleTab &) const override
void mettre_a_jour(double) override
DOES NOTHING - to override in derived classes.
void preparer_calcul() override
void associer_champ_convecte_elem()
void calculer_pour_post(Champ_base &espace_stockage, const Nom &option, int comp) const override
void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const override
int impr(Sortie &os) const override
DOES NOTHING - to override in derived classes.
Motcle get_localisation_pour_post(const Nom &option) const override
void associer_champ_temp(const Champ_Inc_base &, bool) const override
void ajouter_blocs(matrices_t, DoubleTab &, const tabs_t &) const override
void associer_champ_convecte_face()
void dimensionner_blocs_face(matrices_t, const tabs_t &) const
double calculer_dt_stab() const override
Calcul dt_stab.
Op_Conv_VDF_base(const Iterateur_VDF_base &iter_base)
classe Operateur_Conv_base Cette classe est la base de la hierarchie des operateurs representant
void fixer_dt_stab_conv(double dt)
Champs_compris champs_compris_
virtual void mettre_a_jour(double temps)
DOES NOTHING - to override in derived classes.
virtual void preparer_calcul()
virtual void completer()
Associe l'operateur au domaine_dis, le domaine_Cl_dis, et a l'inconnue de son equation.
const std::string & nom_inconnue() const
classe Pb_Multiphase Cette classe represente un probleme de thermohydraulique multiphase de type "3*N...
const Nom & nom_phase(int i) const
int nb_phases() const
classe Periodique Cette classe represente une condition aux limites periodique.
Definition Periodique.h:31
int face_associee(int i) const
Definition Periodique.h:35
const Champ_base & get_champ(const Motcle &nom) const override
int has_correlation(std::string nom_correlation) const
const Correlation_base & get_correlation(std::string nom_correlation) const
static double mp_min(double)
Definition Process.cpp:386
Classe de base des flux de sortie.
Definition Sortie.h:52
void append_line(_TYPE_)
Definition TRUSTTab.tpp:213
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45
_SIZE_ size_totale() const
Definition TRUSTVect.tpp:61
int line_size() const
Definition TRUSTVect.tpp:67
_TYPE_ mp_max_abs_vect(Mp_vect_options opt=VECT_REAL_ITEMS) const
Definition TRUSTVect.h:160
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")