16#include <Modele_turbulence_hyd_base.h>
17#include <Op_Diff_PolyMAC_CDO_Face.h>
18#include <Domaine_Cl_PolyMAC_family.h>
19#include <Champ_Face_PolyMAC_CDO.h>
20#include <Domaine_PolyMAC_CDO.h>
21#include <TRUSTTab_parts.h>
22#include <Probleme_base.h>
23#include <Synonyme_info.h>
24#include <Matrix_tools.h>
25#include <Array_tools.h>
26#include <TRUSTLists.h>
48 bool flag =
Process::nproc() == 1 && le_dom_poly_->nb_faces() < 10000;
50 EChaine chl(flag ?
"Petsc Cholesky_lapack { quiet }" :
"Petsc gmres { precond block_jacobi_ilu { level 0 } quiet rtol 1.e-14 }");
52 solveur.nommer(
"Op_Diff_PolyMAC_CDO_Face solver");
58 if (domaine.domaine().nb_joints() && domaine.domaine().joint(0).epaisseur() < 1)
59 Cerr <<
"Op_Diff_PolyMAC_CDO_Face : largeur de joint insuffisante (minimum 1)!" << finl,
Process::exit();
67 porosite_e.ref(mon_equation->milieu().porosite_elem());
69 if (
que_suis_je() ==
"Op_Diff_PolyMAC_CDO_Face")
return;
86 const IntTab& e_f = domaine.elem_faces();
87 const int nf_tot = domaine.nb_faces_tot(), na_tot =
dimension < 3 ? domaine.domaine().nb_som_tot() : domaine.domaine().nb_aretes_tot();
91 Stencil stencil(0, 2);
94 for (
int e = 0; e < domaine.nb_elem_tot(); e++)
97 for (
int i = domaine.m2d(e); i < domaine.m2d(e + 1); i++, idx++)
99 const int f = e_f(e, idx);
100 for (
int j = domaine.m2i(i); f < domaine.nb_faces() && ch.
fcl()(f, 0) < 2 && j < domaine.m2i(i + 1); j++)
102 const int fb = e_f(e, domaine.m2j(j));
103 for (
int k = domaine.rfdeb(fb); k < domaine.rfdeb(fb + 1); k++)
110 for (
int a = 0; a < (
dimension < 3 ? domaine.nb_som() : domaine.domaine().nb_aretes()); a++)
112 for (
int i = ch.
radeb(a, 0); i < ch.
radeb(a + 1, 0); i++)
115 for (
int i = domaine.m1deb(a); i < domaine.m1deb(a + 1); i++)
116 stencil.
append_line(nf_tot + a, nf_tot + domaine.m1ji(i, 0));
119 tableau_trier_retirer_doublons(stencil);
132 Process::exit(
"Op_Diff_PolyMAC_CDO_Face::dimensionner_bloc : invalid bloc number! p must be in [-1, 3]");
136 const IntTab& e_f = domaine.elem_faces();
137 int i, j, k, a, e, f, fb, nf_tot = domaine.nb_faces_tot(), na_tot =
dimension < 3 ? domaine.domaine().nb_som_tot() : domaine.domaine().nb_aretes_tot(), idx;
141 Stencil stencil(0, 2);
143 for (
int q = 0; q < 4; q++)
149 for (e = 0; e < domaine.nb_elem_tot(); e++)
150 for (i = domaine.m2d(e), idx = 0; i < domaine.m2d(e + 1); i++, idx++)
151 for (f = e_f(e, idx), j = domaine.m2i(i); f < domaine.nb_faces() && ch.
fcl()(f, 0) < 2 && j < domaine.m2i(i + 1); j++)
152 for (fb = e_f(e, domaine.m2j(j)), k = domaine.rfdeb(fb); k < domaine.rfdeb(fb + 1); k++)
155 sp[1].append_line(f, nf_tot + domaine.rfji(k));
159 for (a = 0; a < (
dimension < 3 ? domaine.nb_som() : domaine.domaine().nb_aretes()); a++)
161 for (i = ch.
radeb(a, 0); i < ch.
radeb(a + 1, 0); i++)
164 sp[2].append_line(a, ch.
raji(i));
166 for (i = domaine.m1deb(a); i < domaine.m1deb(a + 1); i++)
168 stencil.
append_line(nf_tot + a, nf_tot + domaine.m1ji(i, 0));
169 sp[3].append_line(a, domaine.m1ji(i, 0));
175 tableau_trier_retirer_doublons(stencil);
180 tableau_trier_retirer_doublons(sp[p]);
181 const int nx = (p <= 1) ? nf_tot : na_tot;
182 const int ny = (p == 0 || p == 2) ? nf_tot : na_tot;
195 if (!polymac_flica5)
return;
197 if (AF.nb_lignes() == 0)
210 DoubleTab_parts inco_parts(inco);
211 DoubleTab_parts sm_parts(sm);
217 AF.ajouter_multvect(inco_parts[0], sm_parts[1]);
218 if (AA.is_diagonal())
220 const int n = AA.nb_lignes();
221 for (
int i = 0; i < n; i++)
222 for (
auto k = AA.get_tab1()(i) - 1; k < AA.get_tab1()(i + 1) - 1; k++)
223 inco_parts[1][i] = sm_parts[1][i] / AA.get_coeff()(k);
224 inco_parts[1].echange_espace_virtuel();
239 const IntTab& f_e = domaine.
face_voisins(), &e_f = domaine.elem_faces();
241 const Conds_lim& cls = la_zcl_poly_->les_conditions_limites();
242 const DoubleVect& pe =
porosite_e, &ve = domaine.volumes();
243 int i, j, k, e, f, fb, a, nf_tot = domaine.nb_faces_tot(), idx;
247 for (e = 0; e < domaine.nb_elem_tot(); e++)
248 for (i = domaine.m2d(e), idx = 0; i < domaine.m2d(e + 1); i++, idx++)
249 for (f = e_f(e, idx), j = domaine.m2i(i); f < domaine.nb_faces() && j < domaine.m2i(i + 1); j++)
250 for (fb = e_f(e, domaine.m2j(j)), k = domaine.rfdeb(fb); k < domaine.rfdeb(fb + 1); k++)
251 resu(f) -= domaine.m2c(j) * ve(e) * (e == f_e(f, 0) ? 1 : -1) * (e == f_e(fb, 0) ? 1 : -1) * pe(e) * domaine.rfci(k) * inco(nf_tot + domaine.rfji(k));
256 for (a = 0; a < (
dimension < 3 ? domaine.nb_som() : domaine.domaine().nb_aretes()); a++)
259 for (i = ch.
radeb(a, 0); i < ch.
radeb(a + 1, 0); i++)
260 resu(nf_tot + a) -= ch.
raci(i) * inco(ch.
raji(i));
262 for (i = ch.
radeb(a, 1); i < ch.
radeb(a + 1, 1); i++)
264 resu(nf_tot + a) -= ch.
racf(i, k) * ref_cast(
Dirichlet, cls[ch.
fcl()(ch.
rajf(i), 1)].valeur()).val_imp(ch.
fcl()(ch.
rajf(i), 2), k);
266 for (i = domaine.m1deb(a); i < domaine.m1deb(a + 1); i++)
267 resu(nf_tot + a) += domaine.m1ci(i) / (pe(domaine.m1ji(i, 1)) *
nu_(domaine.m1ji(i, 1), 0)) * inco(nf_tot + domaine.m1ji(i, 0));
273 const IntTab& f_e = domaine.
face_voisins(), &e_f = domaine.elem_faces();
275 const Conds_lim& cls = la_zcl_poly_->les_conditions_limites();
277 const int nf_tot = domaine.nb_faces_tot();
282 for (
int e = 0; e < domaine.nb_elem_tot(); e++)
285 for (
int i = domaine.m2d(e); i < domaine.m2d(e + 1); i++, idx++)
287 const int f = e_f(e, idx);
289 for (
int j = domaine.m2i(i); j < domaine.m2i(i + 1); j++)
290 if (f < domaine.nb_faces() && ch.
fcl()(f, 0) < 2)
292 const int fb = e_f(e, domaine.m2j(j));
294 for (
int k = domaine.rfdeb(fb); k < domaine.rfdeb(fb + 1); k++)
295 resu(f) -= domaine.m2c(j) * ve(e) * (e == f_e(f, 0) ? 1 : -1) * (e == f_e(fb, 0) ? 1 : -1) * pe(e) * domaine.rfci(k) * inco(nf_tot + domaine.rfji(k));
305 for (
int a = 0; a < (
dimension < 3 ? domaine.nb_som() : domaine.domaine().nb_aretes()); a++)
308 for (
int i = ch.
radeb(a, 0); i < ch.
radeb(a + 1, 0); i++)
309 resu(nf_tot + a) -= ch.
raci(i) * inco(ch.
raji(i));
312 for (
int i = ch.
radeb(a, 1); i < ch.
radeb(a + 1, 1); i++)
314 resu(nf_tot + a) -= ch.
racf(i, k) * ref_cast(
Dirichlet, cls[ch.
fcl()(ch.
rajf(i), 1)].valeur()).val_imp(ch.
fcl()(ch.
rajf(i), 2), k);
317 for (
int i = domaine.m1deb(a); i < domaine.m1deb(a + 1); i++)
318 resu(nf_tot + a) += domaine.m1ci(i) / (pe(domaine.m1ji(i, 1)) *
nu_(domaine.m1ji(i, 1), 0)) * inco(nf_tot + domaine.m1ji(i, 0));
328 const int nf_tot = domaine.
nb_faces_tot(), na_tot =
dimension < 3 ? domaine.domaine().nb_som_tot() : domaine.domaine().nb_aretes_tot();
344 const IntTab& f_e = domaine.
face_voisins(), &e_f = domaine.elem_faces();
347 const int nf_tot = domaine.nb_faces_tot();
352 for (
int e = 0; e < domaine.nb_elem_tot(); e++)
356 for (
int i = domaine.m2d(e); i < domaine.m2d(e + 1); i++, idx++)
358 const int f = e_f(e, idx);
360 for (
int j = domaine.m2i(i); j < domaine.m2i(i + 1); j++)
361 if (f < domaine.nb_faces() && ch.
fcl()(f, 0) < 2)
363 const int fb = e_f(e, domaine.m2j(j));
365 for (
int k = domaine.rfdeb(fb); k < domaine.rfdeb(fb + 1); k++)
366 matrice(f, nf_tot + domaine.rfji(k)) += domaine.m2c(j) * ve(e) * (e == f_e(f, 0) ? 1 : -1) * (e == f_e(fb, 0) ? 1 : -1) * pe(e) * domaine.rfci(k);
372 for (
int a = 0; a < (
dimension < 3 ? domaine.nb_som() : domaine.domaine().nb_aretes()); a++)
375 for (
int i = ch.
radeb(a, 0); i < ch.
radeb(a + 1, 0); i++)
377 const int f = ch.
raji(i);
379 if (ch.
fcl()(f, 0) < 2)
380 matrice(nf_tot + a, f) += ch.
raci(i);
384 for (
int i = domaine.m1deb(a); i < domaine.m1deb(a + 1); i++)
385 matrice(nf_tot + a, nf_tot + domaine.m1ji(i, 0)) -= domaine.m1ci(i) / (pe(domaine.m1ji(i, 1)) *
nu_(domaine.m1ji(i, 1), 0));
391 if (ip > 3 || ip < -1)
392 Process::exit(
"Op_Diff_PolyMAC_CDO_Elem::contribuer_bloc : invalid bloc number! p must be in [-1, 3]");
395 const IntTab& f_e = domaine.
face_voisins(), &e_f = domaine.elem_faces();
397 const DoubleVect& pe =
porosite_e, &ve = domaine.volumes();
398 int i, j, k, e, f, fb, a, nf_tot = domaine.nb_faces_tot(), idx;
402 for (e = 0; e < domaine.nb_elem_tot(); e++)
403 for (i = domaine.m2d(e), idx = 0; i < domaine.m2d(e + 1); i++, idx++)
404 for (f = e_f(e, idx), j = domaine.m2i(i); f < domaine.nb_faces() && ch.
fcl()(f, 0) < 2 && j < domaine.m2i(i + 1); j++)
405 for (fb = e_f(e, domaine.m2j(j)), k = domaine.rfdeb(fb); k < domaine.rfdeb(fb + 1); k++)
408 matrice(f, nf_tot + domaine.rfji(k)) += domaine.m2c(j) * ve(e) * (e == f_e(f, 0) ? 1 : -1) * (e == f_e(fb, 0) ? 1 : -1) * pe(e) * domaine.rfci(k);
410 matrice(f, domaine.rfji(k)) += domaine.m2c(j) * ve(e) * (e == f_e(f, 0) ? 1 : -1) * (e == f_e(fb, 0) ? 1 : -1) * pe(e) * domaine.rfci(k);
414 for (a = 0; a < (
dimension < 3 ? domaine.nb_som() : domaine.domaine().nb_aretes()); a++)
417 for (i = ch.
radeb(a, 0); i < ch.
radeb(a + 1, 0); i++)
418 if ((ch.
fcl()(f = ch.
raji(i), 0) < 2) || ip > -1)
421 matrice(nf_tot + a, f) += ch.
raci(i);
423 matrice(a, f) += ch.
raci(i);
426 for (i = domaine.m1deb(a); i < domaine.m1deb(a + 1); i++)
429 matrice(nf_tot + a, nf_tot + domaine.m1ji(i, 0)) -= domaine.m1ci(i) / (pe(domaine.m1ji(i, 1)) *
nu_(domaine.m1ji(i, 1), 0));
431 matrice(a, domaine.m1ji(i, 0)) -= domaine.m1ci(i) / (pe(domaine.m1ji(i, 1)) *
nu_(domaine.m1ji(i, 1), 0));
const IntTab & fcl() const
classe Champ_Fonc_base Classe de base des champs qui sont fonction d'une grandeur calculee
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
int nb_faces_tot() const
renvoie le nombre total de faces.
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Une entree dont la source est une chaine de caracteres.
Class defining operators and methods for all reading operation in an input flow (file,...
virtual const Milieu_base & milieu() const =0
virtual const RefObjU & get_modele(Type_modele type) const
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).
int nb_lignes() const override
Return local number of lines (=size on the current proc).
DoubleVect & porosite_elem()
Classe Modele_turbulence_hyd_base Cette classe sert de base a la hierarchie des classes.
const Champ_Fonc_base & viscosite_turbulente() const
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.
void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const override
DOES NOTHING - to override in derived classes.
void contribuer_bloc(const DoubleTab &, Matrice_Morse &, const int i) const
void dimensionner_bloc(Matrice_Morse &mat, const int p) const
Op_Diff_PolyMAC_CDO_Face()
void dimensionner(Matrice_Morse &mat) const override
DOES NOTHING - to override in derived classes.
DoubleTab & ajouter(const DoubleTab &inco, DoubleTab &resu) const override
void completer() override
Associe l'operateur au domaine_dis, le domaine_Cl_dis, et a l'inconnue de son equation.
void update_auxiliary_variables()
void update_nu() const override
void completer() override
Associe l'operateur au domaine_dis, le domaine_Cl_dis, et a l'inconnue de son equation.
void associer_diffusivite_turbulente(const Champ_Fonc_base &)
SolveurSys & set_solveur()
Entree & lire_solveur(Entree &)
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
int resoudre_systeme(const Matrice_Base &matrice, const DoubleVect &secmem, DoubleVect &solution)
Classe de base des flux de sortie.
virtual void declare_support_masse_volumique(int ok)
Le constructeur d'une classe derivee qui se sert de la masse volumique doit appeler cette fonction av...
_SIZE_ dimension_tot(int) const override
const Objet_U & valeur() const