16#include <Modele_turbulence_scal_base.h>
17#include <Echange_externe_impose.h>
18#include <Op_Dift_Stab_VEF_Face.h>
19#include <Scalaire_impose_paroi.h>
20#include <Neumann_sortie_libre.h>
21#include <Check_espace_virtuel.h>
22#include <Dirichlet_homogene.h>
23#include <Neumann_homogene.h>
24#include <Porosites_champ.h>
25#include <Neumann_paroi.h>
26#include <Periodique.h>
27#include <Champ_P1NC.h>
50double my_minimum(
double a,
double b,
double c)
52 if (a <= b)
return (a <= c) ? a : c;
53 else if (b <= c)
return b;
57double my_maximum(
double a,
double b,
double c)
59 if (a >= b)
return (a >= c) ? a : c;
60 else if (b >= c)
return b;
64double my_minimum(
double a,
double b)
66 return (a <= b) ? a : b;
69double my_maximum(
double a,
double b)
71 return (a >= b) ? a : b;
78 Motcle accouverte =
"{", accfermee =
"}", motlu;
83 les_mots[2] =
"nu_transp";
84 les_mots[3] =
"nut_transp";
85 les_mots[4] =
"standard";
86 les_mots[5] =
"new_jacobian";
90 if (motlu != accouverte)
91 Process::exit(
"Error in Op_Dift_Stab_VEF_Face::readOn(). Option keywords must be preceded by an open brace { !");
94 while (motlu != accfermee)
96 int rang = les_mots.search(motlu);
109 is >> nut_transp_lu_;
118 Cerr <<
"Error in Op_Dift_Stab_VEF_Face::readOn(). Word " << motlu <<
" is unknown !" << finl;
119 Cerr <<
"Known keywords are : " << les_mots << finl;
127 if (motlu != accfermee)
129 Cerr <<
"Error in Op_Dift_Stab_VEF_Face::readOn(). Final known keyword is the closing brace sign } !" << finl;
140inline double aij_extradiag__(
const Op_Dift_Stab_VEF_Face& z_class,
const int elem,
const int facei,
const int facej,
const int dim,
const int dim2,
const double nu_elem)
143 const IntTab& face_voisins = domaine_VEF.
face_voisins();
144 const DoubleTab& face_normales = domaine_VEF.
face_normales();
145 const DoubleVect& volumes = domaine_VEF.
volumes();
147 double volume = 0., signei = 1., signej = 1., aij = 0.;
153 volume = 1. / volumes(elem);
156 if (face_voisins(facei, 0) != elem) signei = -1.;
157 if (face_voisins(facej, 0) != elem) signej = -1.;
159 aij = face_normales(facei, dim2) * face_normales(facej, dim);
160 aij *= signei * signej;
166template <Type_Champ _TYPE_>
167void ajouter_operateur_centre__(
const Op_Dift_Stab_VEF_Face& z_class,
const DoubleTab& Aij_diag,
const DoubleTab& nu,
const DoubleTab& inconnue, DoubleTab& resu)
169 constexpr bool is_VECT = (_TYPE_ == Type_Champ::VECTORIEL);
172 const IntTab& elem_faces = domaine_VEF.
elem_faces();
174 double nu_elem = 0., aij = 0.;
176 for (
int elem = 0; elem < nb_elem_tot; elem++)
178 if (is_VECT) nu_elem = nu(elem);
180 for (
int facei_loc = 0; facei_loc < nb_faces_elem; facei_loc++)
182 const int facei = elem_faces(elem, facei_loc);
185 for (
int facej_loc = facei_loc + 1; facej_loc < nb_faces_elem; facej_loc++)
187 const int facej = elem_faces(elem, facej_loc);
189 if (!is_VECT) aij = Aij_diag(elem, facei_loc, facej_loc);
191 for (
int nc = 0; nc < nb_comp; nc++)
193 if (is_VECT) aij = Aij_diag(elem, facei_loc, facej_loc, nc);
195 const double delta_ij = aij * (inconnue(facej, nc) - inconnue(facei, nc));
196 resu(facei, nc) += delta_ij;
197 resu(facej, nc) -= delta_ij;
203 for (
int facej_loc = 0; facej_loc < nb_faces_elem; facej_loc++)
204 if (facej_loc != facei_loc)
206 const int facej = elem_faces(elem, facej_loc);
208 for (
int nc = 0; nc < nb_comp; nc++)
209 for (
int nc2 = nc + 1; nc2 < nb_comp; nc2++)
211 aij = aij_extradiag__(z_class, elem, facei, facej, nc, nc2, nu_elem);
213 double delta_ij = aij * (inconnue(facej, nc2) - inconnue(facei, nc2));
214 resu(facei, nc) += delta_ij;
216 delta_ij = aij * (inconnue(facej, nc) - inconnue(facei, nc));
217 resu(facej, nc2) -= delta_ij;
224template <Type_Champ _TYPE_>
225void calculer_coefficients__(
const Op_Dift_Stab_VEF_Face& z_class,
const DoubleTab& nu,
const DoubleTab& nu2 , DoubleTab& Aij)
227 constexpr bool is_VECT = (_TYPE_ == Type_Champ::VECTORIEL);
231 const DoubleTab& face_normales = domaine_VEF.
face_normales();
232 const DoubleVect& volumes = domaine_VEF.
volumes();
237 assert(Aij.
dimension(1) == nb_faces_elem);
238 assert(Aij.
dimension(2) == nb_faces_elem);
243 assert(Aij.
nb_dim() == 4);
247 assert(Aij.
nb_dim() == 3);
249 double nu2_elem = 0.;
251 for (
int elem = 0; elem < nb_elem_tot; elem++)
253 double volume = 1. / volumes(elem);
255 double nu_elem = nu(elem);
260 nu2_elem = nu2(elem);
264 for (
int facei_loc = 0; facei_loc < nb_faces_elem; facei_loc++)
266 const int facei = elem_faces(elem, facei_loc);
269 if (face_voisins(facei, 0) != elem) signei = -1;
271 for (
int facej_loc = facei_loc + 1; facej_loc < nb_faces_elem; facej_loc++)
273 const int facej = elem_faces(elem, facej_loc);
276 if (face_voisins(facej, 0) != elem) signej = -1;
281 psc += face_normales(facei, dim) * face_normales(facej, dim);
283 psc *= signei * signej;
288 Aij(elem, facei_loc, facej_loc) = psc;
289 Aij(elem, facej_loc, facei_loc) = psc;
293 for (
int dim = 0; dim < nb_comp; dim++)
295 Aij(elem, facei_loc, facej_loc, dim) = psc;
296 Aij(elem, facej_loc, facei_loc, dim) = psc;
300 for (
int dim = 0; dim < nb_comp; dim++)
302 psc = face_normales(facei, dim) * face_normales(facej, dim);
303 psc *= signei * signej;
306 Aij(elem, facei_loc, facej_loc, dim) += psc;
307 Aij(elem, facej_loc, facei_loc, dim) += psc;
319void Op_Dift_Stab_VEF_Face::ajouter_diffusion(
const DoubleTab& Aij,
const DoubleTab& inconnueTab, DoubleTab& resuTab,
const bool is_VECT)
const
322 const IntTab& elem_faces = domaine_VEF.
elem_faces();
324 const DoubleVect& inconnue = inconnueTab;
325 DoubleVect& resu = resuTab;
326 int elem = 0, facei_loc = 0, facei = 0, facej_loc = 0, facej = 0, dim = 0;
327 double inc_i = 0., inc_j = 0., delta_ij = 0., dij = 0.;
329 for (elem = 0; elem < nb_elem_tot; elem++)
330 for (facei_loc = 0; facei_loc < nb_faces_elem; facei_loc++)
332 facei = elem_faces(elem, facei_loc);
333 for (facej_loc = facei_loc + 1; facej_loc < nb_faces_elem; facej_loc++)
335 facej = elem_faces(elem, facej_loc);
337 for (dim = 0; dim < nb_comp; dim++)
339 const double aij = Aij(elem, facei_loc, facej_loc, dim);
344 inc_i = inconnue[facei * nb_comp + dim];
345 inc_j = inconnue[facej * nb_comp + dim];
346 delta_ij = dij * (inc_j - inc_i);
348 resu[facei * nb_comp + dim] += delta_ij;
349 resu[facej * nb_comp + dim] -= delta_ij;
354 const double aij = Aij(elem, facei_loc, facej_loc);
358 for (dim = 0; dim < nb_comp; dim++)
360 inc_i = inconnue[facei * nb_comp + dim];
361 inc_j = inconnue[facej * nb_comp + dim];
362 delta_ij = dij * (inc_j - inc_i);
364 resu[facei * nb_comp + dim] += delta_ij;
365 resu[facej * nb_comp + dim] -= delta_ij;
373void Op_Dift_Stab_VEF_Face::ajouter_antidiffusion(
const DoubleTab& Aij,
const DoubleTab& inconnueTab, DoubleTab& resuTab,
const bool is_VECT)
const
376 const DoubleTab& xv = domaine_VEF.
xv();
377 const IntTab& elem_faces = domaine_VEF.
elem_faces();
381 const DoubleVect& inconnue = inconnueTab;
382 DoubleVect& resu = resuTab;
386 int elem = 0, facei_loc = 0, facei = 0, facej_loc = 0, facej = 0, dim = 0, dim2 = 0;
387 double inc_i = 0., inc_j = 0., delta_ij = 0., delta_imax = 0., delta_imin = 0.;
388 double delta_jmax = 0., delta_jmin = 0., sij = 0., muij = 0., muji = 0.;
390 bool ok_facei =
false, ok_facej =
false;
392 DoubleTab Minima(nb_faces_tot), Maxima(nb_faces_tot);
394 for (dim = 0; dim < nb_comp; dim++)
396 calculer_min_max(inconnueTab, dim, Minima,
false );
397 calculer_min_max(inconnueTab, dim, Maxima,
true );
399 for (elem = 0; elem < nb_elem_tot; elem++)
400 for (facei_loc = 0; facei_loc < nb_faces_elem; facei_loc++)
402 facei = elem_faces(elem, facei_loc);
403 ok_facei = is_dirichlet_faces_(facei);
404 inc_i = inconnue[facei * nb_comp + dim];
406 delta_imin = Minima(facei) - inc_i;
407 delta_imax = Maxima(facei) - inc_i;
408 assert(delta_imax >= 0.);
409 assert(delta_imin <= 0.);
411 for (facej_loc = facei_loc + 1; facej_loc < nb_faces_elem; facej_loc++)
413 const double aij = is_VECT ? Aij(elem, facei_loc, facej_loc, dim) : Aij(elem, facei_loc, facej_loc);
417 facej = elem_faces(elem, facej_loc);
418 ok_facej = is_dirichlet_faces_(facej);
419 inc_j = inconnue[facej * nb_comp + dim];
422 rij(dim2) = xv(facej, dim2) - xv(facei, dim2);
427 delta_ij = inc_i - inc_j;
428 delta_jmin = Minima(facej) - inc_j;
429 delta_jmax = Maxima(facej) - inc_j;
430 assert(delta_jmax >= 0.);
431 assert(delta_jmin <= 0.);
433 muij = calculer_gradients(facei, rij);
434 muji = calculer_gradients(facej, rji);
442 if (!ok_facei && !ok_facej)
443 sij = my_minimum(muij, delta_ij, muji);
444 if (!ok_facei && ok_facej)
445 sij = my_minimum(muij, delta_ij);
446 if (ok_facei && !ok_facej)
447 sij = my_minimum(delta_ij, muji);
449 else if (delta_ij < 0.)
454 if (!ok_facei && !ok_facej)
455 sij = my_maximum(muij, delta_ij, muji);
456 if (!ok_facei && ok_facej)
457 sij = my_maximum(muij, delta_ij);
458 if (ok_facei && !ok_facej)
459 sij = my_maximum(delta_ij, muji);
462 resu[facei * nb_comp + dim] -= aij * sij;
463 resu[facej * nb_comp + dim] += aij * sij;
471double Op_Dift_Stab_VEF_Face::calculer_gradients(
int facei,
const DoubleTab& rij)
const
475 const DoubleTab& face_normales = domaine_VEF.
face_normales();
476 const DoubleVect& volumes = domaine_VEF.
volumes();
478 double volume = 0., signek = 0., psc = 0., mu_ij = 0.;
479 int elem = 0, elem_loc = 0, facei_loc = 0, facek_loc = 0, facek = 0, dim = 0;
481 for (elem_loc = 0; elem_loc < 2; elem_loc++)
483 facei_loc = get_num_fac_loc(facei, elem_loc);
484 elem = face_voisins(facei, elem_loc);
488 volume += volumes(elem);
490 for (facek_loc = 0; facek_loc < nb_faces_elem; facek_loc++)
491 if (facek_loc != facei_loc)
493 facek = elem_faces(elem, facek_loc);
496 if (face_voisins(facek, 0) != elem)
501 psc += face_normales(facek, dim) * rij(dim);
516void Op_Dift_Stab_VEF_Face::calculer_min_max(
const DoubleTab& inconnueTab,
int& dim, DoubleTab& minima_ou_maxima,
const bool is_max)
const
521 const IntTab& elem_faces = domaine_VEF.
elem_faces();
522 int elem = 0, facei_loc = 0, facei = 0, facej_loc = 0, facej = 0;
523 double inc_i = 0., inc_j = 0.;
524 const DoubleVect& inconnue = inconnueTab;
526 assert(minima_ou_maxima.
nb_dim() == 1);
527 assert(minima_ou_maxima.
dimension(0) == nb_faces_tot);
528 assert(dim < nb_comp);
530 for (facei = 0; facei < nb_faces_tot; facei++)
531 minima_ou_maxima(facei) = inconnue[facei * nb_comp + dim];
533 for (elem = 0; elem < nb_elem_tot; elem++)
534 for (facei_loc = 0; facei_loc < nb_faces_elem; facei_loc++)
536 facei = elem_faces(elem, facei_loc);
538 inc_i = inconnue[facei * nb_comp + dim];
539 double& min_ou_maxi = minima_ou_maxima(facei);
541 for (facej_loc = facei_loc + 1; facej_loc < nb_faces_elem; facej_loc++)
543 facej = elem_faces(elem, facej_loc);
545 inc_j = inconnue[facej * nb_comp + dim];
546 double& min_ou_maxj = minima_ou_maxima(facej);
550 if (inc_j > min_ou_maxi)
552 if (inc_i > min_ou_maxj)
557 if (inc_j < min_ou_maxi)
559 if (inc_i < min_ou_maxj)
567 const int nb_bords = les_cl.size();
568 int num1 = 0, num2 = 0, n_bord = 0, ind_face = 0;
570 for (n_bord = 0; n_bord < nb_bords; n_bord++)
573 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
578 if (sub_type(Periodique, la_cl.valeur()))
580 const Periodique& la_cl_perio = ref_cast(Periodique, la_cl.valeur());
582 for (ind_face = num1; ind_face < num2; ind_face++)
589 double& min_ou_maxi = minima_ou_maxima(facei);
590 double& min_ou_maxj = minima_ou_maxima(facej);
593 if (min_ou_maxi > min_ou_maxj)
594 min_ou_maxj = min_ou_maxi;
595 if (min_ou_maxj > min_ou_maxi)
596 min_ou_maxi = min_ou_maxj;
600 if (min_ou_maxi < min_ou_maxj)
601 min_ou_maxj = min_ou_maxi;
602 if (min_ou_maxj < min_ou_maxi)
603 min_ou_maxi = min_ou_maxj;
619 const int nb_bord = les_cl.size(), nb_faces_tot = domaine_VEF.
nb_faces_tot();
622 is_dirichlet_faces_.resize(nb_faces_tot);
623 is_dirichlet_faces_ = 0;
625 for (
int n_bord = 0; n_bord < nb_bord; n_bord++)
629 int nb_faces_bord_tot = le_bord.
nb_faces_tot(), face = -1;
632 for (ind_face = 0; ind_face < nb_faces_bord_tot; ind_face++)
635 is_dirichlet_faces_(face) = 1;
640void Op_Dift_Stab_VEF_Face::ajouter_cas_scalaire(
const DoubleTab& inconnue,
const DoubleTab& nu,
const DoubleTab& nu_turb_m, DoubleTab& resu2)
const
644 DoubleTab Aij(nb_elem_tot, nb_faces_elem, nb_faces_elem), nu_total(nu);
645 nu_total += nu_turb_m;
647 calculer_coefficients__<Type_Champ::SCALAIRE>(*
this, nu_total, nu_total , Aij);
648 ajouter_operateur_centre__<Type_Champ::SCALAIRE>(*
this, Aij, nu, inconnue, resu2);
652 ajouter_diffusion(Aij, inconnue, resu2,
false );
653 ajouter_antidiffusion(Aij, inconnue, resu2,
false );
657void Op_Dift_Stab_VEF_Face::ajouter_cas_vectoriel(
const DoubleTab& inconnue,
const DoubleTab& nu,
const DoubleTab& nu_turb_m, DoubleTab& resu2)
const
662 DoubleTab Aij_diag(nb_elem_tot, nb_faces_elem, nb_faces_elem, nb_comp);
664 DoubleTab nu_total(nu);
665 if (nu_lu_ == 0) nu_total = 0.;
666 if (nut_lu_) nu_total += nu_turb_m;
668 DoubleTab nu_transp_total(nu);
669 if (nu_transp_lu_ == 0) nu_transp_total = 0.;
670 if (nut_transp_lu_) nu_transp_total += nu_turb_m;
672 calculer_coefficients__<Type_Champ::VECTORIEL>(*
this, nu_total, nu_transp_total, Aij_diag);
673 ajouter_operateur_centre__<Type_Champ::VECTORIEL>(*
this, Aij_diag, nu_transp_total, inconnue, resu2);
677 ajouter_diffusion(Aij_diag, inconnue, resu2,
true );
678 ajouter_antidiffusion(Aij_diag, inconnue, resu2,
true );
689 flux_bords_.resize(le_dom_vef->nb_faces_bord(), nb_comp);
692 DoubleTab resu2(resu);
696 DoubleTab nu, nu_turb_m, tab_inconnue_;
701 modif_par_porosite_si_flag(
nu_, nu, !marq, porosite_elem);
702 modif_par_porosite_si_flag(nu_turb, nu_turb_m, !marq, porosite_elem);
703 const DoubleTab& inconnue = modif_par_porosite_si_flag(inconnue_org, tab_inconnue_, marq, porosite_face);
705 assert_espace_virtuel_vect(nu);
706 assert_espace_virtuel_vect(inconnue);
707 assert_espace_virtuel_vect(nu_turb_m);
710 Debog::verifier(
"Op_Dift_Stab_VEF_Face::ajouter inconnue_org", inconnue_org);
713 if (
equation().inconnue().nature_du_champ() != vectoriel)
714 ajouter_cas_scalaire(inconnue, nu, nu_turb_m, resu2);
716 ajouter_cas_vectoriel(inconnue, nu, nu_turb_m, resu2);
731 DoubleTab nu, nu_turb;
737 modif_par_porosite_si_flag(
nu_, nu, !marq, porosite_elem);
738 modif_par_porosite_si_flag(nu_turb_, nu_turb, !marq, porosite_elem);
740 DoubleVect porosite_eventuelle(
equation().milieu().porosite_face());
741 if (!marq) porosite_eventuelle = 1;
743 if (
equation().inconnue().nature_du_champ() == vectoriel)
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
classe Cond_lim Classe generique servant a representer n'importe quelle classe
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
static void verifier(const char *const msg, double)
Classe Dirichlet_homogene Cette classe est la classe de base de la hierarchie des conditions aux limi...
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
int nb_faces_elem(int=0) const
Renvoie le nombre de face de type i des elements geometriques constituants le domaine.
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
int nb_faces_tot() const
renvoie le nombre total de faces.
virtual double face_normales(int face, int comp) const
double xv(int num_face, int k) const
double volumes(int i) const
const IntTab & get_num_fac_loc() const
int elem_faces(int i, int j) const
renvoie le numero de le ieme face de la maille num_elem la facon dont ces faces sont numerotees est
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 const Champ_Inc_base & inconnue() const =0
int num_face(const int) const
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
DoubleVect & porosite_elem()
DoubleVect & porosite_face()
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
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 Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
const Champ_Fonc_base & diffusivite_turbulente() const
int phi_psi_diffuse(const Equation_base &eq) const
definit si on calcule div(phi nu grad Psi) ou div(nu grap Phi psi)
virtual void remplir_nu(DoubleTab &) const
const Domaine_VEF & domaine_vef() const
const Domaine_Cl_VEF & domaine_cl_vef() const
void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const override
DOES NOTHING - to override in derived classes.
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
void completer() override
Associe l'operateur au domaine_dis, le domaine_Cl_dis, et a l'inconnue de son equation.
void modifie_pour_cl_gen(const DoubleTab &, DoubleTab &, DoubleTab &) const
void ajouter_contribution_bord_gen(const DoubleTab &, Matrice_Morse &, const DoubleTab &, const DoubleTab &, const DoubleVect &) const
void ajouter_contribution_interne_gen(const DoubleTab &inco, Matrice_Morse &mat, const DoubleTab &nu, const DoubleTab &nu_turb, const DoubleVect &porosite_eventuelle) const
void completer() override
Associe l'operateur au domaine_dis, le domaine_Cl_dis, et a l'inconnue de son equation.
void modifier_matrice_pour_periodique_apres_contribuer(Matrice_Morse &matrice, const Equation_base &) const
Somme les 2 lignes des faces periodiques associees permet de calculer dans le code sans se poser de q...
void modifier_matrice_pour_periodique_avant_contribuer(Matrice_Morse &matrice, const Equation_base &) const
divise les coefficients sur les ligne des faces periodiques par 2 en prevision de l'application modif...
void modifier_flux(const Operateur_base &) const
int face_associee(int i) const
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Classe de base des flux de sortie.
_SIZE_ dimension(int d) const