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
class Champ_Fonc_base Base class of fields that are functions of a calculated quantity
class Conds_lim This class represents a vector of boundary conditions.
Dirichlet This class is the base class of the hierarchy of Dirichlet-type boundary conditions.
int nb_faces_tot() const
Returns the total number of faces.
int face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in direction i.
An input stream whose source is a character string.
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
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
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()
Base class for the turbulence model hierarchy for Navier-Stokes equations.
const Champ_Fonc_base & viscosite_turbulente() const
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
const Nom & que_suis_je() const
Returns the string identifying the class.
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
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
Associates the operator with the domaine_dis, the domaine_Cl_dis, and the unknown of its equation.
void update_auxiliary_variables()
void update_nu() const override
void completer() override
Associates the operator with the domaine_dis, the domaine_Cl_dis, and the unknown of its equation.
void associer_diffusivite_turbulente(const Champ_Fonc_base &)
SolveurSys & set_solveur()
Entree & lire_solveur(Entree &)
static int nproc()
Returns the number of processors in the current group. See Comm_Group::nproc() and PE_Groups::current...
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
int resoudre_systeme(const Matrice_Base &matrice, const DoubleVect &secmem, DoubleVect &solution)
Base class for output streams.
virtual void declare_support_masse_volumique(int ok)
The constructor of a derived class that uses the density field must call this function with the value...
_SIZE_ dimension_tot(int) const override
const Objet_U & valeur() const