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>
32 if (sub_type(Masse_Multiphase,
equation()))
34 const Pb_Multiphase& pb = ref_cast(Pb_Multiphase,
equation().probleme());
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);
48inline void eval_fluent(
const double psc,
const int num1,
const int num2,
const int n, DoubleTab& fluent)
50 if (psc >= 0) fluent(num2, n) += psc;
51 else fluent(num1, n) -= psc;
62 return iter_->impr(os);
77 iter_->associer_champ_convecte_ou_inc(cc, &
vitesse());
85 iter_->associer_champ_convecte_ou_inc(cc, &
vitesse());
97 const IntTab& f_e = domaine.face_voisins();
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())))
106 Stencil stencil(0, 2);
109 if (i_m.first ==
"vitesse")
113 for (f = 0; f < domaine.nb_faces_tot(); f++)
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));
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())
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);
126 tableau_trier_retirer_doublons(stencil);
130 i_m.second->nb_colonnes() ? *i_m.second += mat : *i_m.second = mat;
138 const IntTab& f_e = domaine.face_voisins(), &e_f = domaine.elem_faces(), &fcl = ch.
fcl();
139 const DoubleTab& inco = ch.
valeurs();
142 if (!matrices.count(nom_inco) || semi_impl.count(nom_inco))
return;
150 Stencil stencil(0, 2);
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++)
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);
167 tableau_trier_retirer_doublons(stencil);
175 iter_->ajouter_blocs(mats, secmem, semi_impl);
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();
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());
189 if (!fluent_.get_md_vector())
191 fluent_.resize(0, N);
197 int num1, num2, face, elem1;
200 for (
int n_bord = 0; n_bord < domaine_VDF.
nb_front_Cl(); n_bord++)
208 for (face=num1; face<num2; face++)
209 for (
int n = 0; n < N; n++)
211 psc = vit(face, n) * face_surfaces(face);
212 if ( (elem1 = face_voisins(face,0)) != -1)
214 if (psc < 0) fluent_(elem1, n) -= psc;
217 if (psc > 0) fluent_(face_voisins(face,1), n) += psc;
224 for (face = premiere_face; face < domaine_VDF_nb_faces; face++)
225 for (
int n = 0; n < N; n++)
227 psc = vit(face, n) * face_surfaces(face);
228 eval_fluent(psc, face_voisins(face, 0), face_voisins(face, 1), n, fluent_);
233 diviser_par_rho_si_dilatable(fluent_,
equation().milieu());
235 const double alpha_min_dt = 1e-3;
236 double dt_stab = 1.e30;
237 int domaine_VDF_nb_elem=domaine_VDF.
nb_elem();
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))
243 double dt_elem = volumes(num_poly)/(fluent_(num_poly, n)+DMINFLOAT);
244 if (dt_elem<dt_stab) dt_stab = dt_elem;
261 const DoubleVect& face_surfaces = domaine_VDF.
face_surfaces();
264 DoubleTrav fluent(volumes_entrelaces);
268 for (
int n_bord = 0; n_bord < domaine_VDF.
nb_front_Cl(); n_bord++)
276 for (
int face = num1; face < num2; face++)
278 double value = vit[face]*face_surfaces(face);
279 if (value >0) fluent[face] = value;
280 else fluent[face] -= value;
287 for (
int face = premiere_face; face < domaine_VDF_nb_faces; face++)
289 const double value = vit[face]*face_surfaces(face);
290 if (value >0) fluent[face] = value;
291 else fluent[face] -= value;
297 diviser_par_rho_si_dilatable(fluent,
equation().milieu());
299 dt_face=(volumes_entrelaces);
301 for (
int n_bord=0; n_bord<domaine_VDF.
nb_front_Cl(); n_bord++)
306 for (
int num_face = ndeb; num_face < nfin; num_face++)
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.;
314 for (
int num_face = premiere_face; num_face<domaine_VDF_nb_faces; num_face++)
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.;
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;
327 for (
int n_bord = 0; n_bord < domaine_VDF.
nb_front_Cl(); n_bord++)
334 const int nb_faces_bord = le_bord.
nb_faces();
335 for (
int ind_face = 0; ind_face < nb_faces_bord; 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))
341 dt_face(face) = std::min(dt_face(face),dt_face(face_associee));
355 DoubleTab& es_valeurs = espace_stockage.
valeurs();
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();
364 const int N = std::min(vit.
line_size(),
equation().inconnue().valeurs().line_size());
371 int num1, num2, face, elem1;
374 for (
int n_bord = 0; n_bord < domaine_VDF.
nb_front_Cl(); n_bord++)
382 for (face = num1; face < num2; face++)
384 psc = vit[face]*face_surfaces(face);
385 if ( (elem1 = face_voisins(face,0)) != -1)
387 if (psc < 0) fluent[elem1] -= psc;
390 if (psc > 0) fluent[face_voisins(face,1)] += psc;
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++)
399 psc = vit[face]*face_surfaces(face);
400 eval_fluent(psc,face_voisins(face,0),face_voisins(face,1),0,fluent);
404 diviser_par_rho_si_dilatable(fluent,
equation().milieu());
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);
436 noms_compris.add(noms_cc_phases_[i]);
437 noms_compris.add(noms_vd_phases_[i]);
438 noms_compris.add(noms_x_phases_[i]);
441 if (opt==DESCRIPTION)
442 Cerr<<
" Op_Conv_VDF_base : "<< noms_compris <<finl;
444 nom.add(noms_compris);
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])
457 if (j >= 0 && !vd_phases_[j])
462 if (k >= 0 && !x_phases_[k])
477 const IntTab& f_e = domaine.face_voisins(), &e_f = domaine.elem_faces();
487 if (cc_phases_.size())
488 for (n = 0, m = 0; n < N; n++, m += (M > 1))
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 ) / 2 * ((e = f_e(f, i)) >= 0 ? vcc(e, n) : bcc(f, n));
498 if (vd_phases_.size())
499 for (n = 0, m = 0; n < N; n++, m += (M > 1))
504 DoubleTab& v_ph = c_ph.
valeurs();
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 ) / 2 * ((e = f_e(f, i)) >= 0 ? alp(e, n) : balp(f, n));
511 DoubleTrav G(N), v(N, D);
513 if (x_phases_.size())
514 for (e = 0; e < domaine.nb_elem(); e++)
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;
524 if (x_phases_.size())
525 for (n = 0; n < N; n++)
526 if (x_phases_[n]) x_phases_[n]->changer_temps(temps);
class Champ_Face_VDF Cette classe sert a representer un champ vectoriel dont on ne calcule
const IntTab & fcl() const
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.
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
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
virtual void creer_tableau_elements(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
creation d'un tableau parallele de valeurs aux elements.
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
virtual const DoubleVect & face_surfaces() const
int nb_faces() const
renvoie le nombre global de faces.
DoubleVect & volumes_entrelaces()
double volumes(int i) const
int premiere_face_int() const
une face est interne ssi elle separe deux elements.
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
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.
int num_premiere_face() const
int num_face(const int) const
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).
DoubleVect & porosite_elem()
DoubleVect & porosite_face()
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
virtual Motcle get_localisation_pour_post(const Nom &option) const
virtual void calculer_pour_post(Champ_base &espace_stockage, const Nom &option, int comp) const
Une chaine de caractere (Nom) en majuscules.
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
const std::string & getString() const
Un tableau de chaine de caracteres (VECT(Nom)).
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
virtual const Nom & le_nom() const
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
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
classe Periodique Cette classe represente une condition aux limites periodique.
int face_associee(int i) const
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)
Classe de base des flux de sortie.
_SIZE_ dimension(int d) const
_SIZE_ size_totale() const
_TYPE_ mp_max_abs_vect(Mp_vect_options opt=VECT_REAL_ITEMS) const
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")