16#include <Op_Grad_VEF_P1B_Face.h>
17#include <Check_espace_virtuel.h>
18#include <Neumann_sortie_libre.h>
19#include <Dirichlet_homogene.h>
20#include <Schema_Temps_base.h>
21#include <Navier_Stokes_std.h>
22#include <communications.h>
23#include <Probleme_base.h>
24#include <EcrFicPartage.h>
25#include <Periodique.h>
51static int chercher_arete(
int elem,
int somi,
int somj,
const IntTab& elem_aretes,
const IntTab& aretes_som)
59 for (
int i_arete = 0; i_arete < 6; i_arete++)
61 int arete = elem_aretes(elem, i_arete);
62 int som1 = aretes_som(arete, 0);
65 int som2 = aretes_som(arete, 1);
78 Cerr <<
"Method verifier of Op_Grad_VEF_P1B_Face is not valid for this discretization." << finl;
83 Cerr <<
"Method verifier of Op_Grad_VEF_P1B_Face is not valid for this discretization." << finl;
86 const Domaine& domaine = domaine_VEF.
domaine();
87 const Domaine& dom = domaine;
90 int nb_elem = domaine.nb_elem();
93 const DoubleTab& xp = domaine_VEF.
xp();
98 exemple_champ_non_homogene(domaine_VEF, tab);
111 Cerr <<
Process::me() <<
" grad(1) som = " << finl;
117 for (; i < nb_elem_tot; i++)
121 Cerr <<
"[" <<
Process::me() <<
"] p(1) elem = " << finl;
123 Cerr <<
"[" <<
Process::me() <<
"] grad(1) elem = " << finl;
128 for (; i < nb_elem_tot + nb_som_tot; i++)
132 Cerr <<
Process::me() <<
" grad(1) som = " << finl;
137 int sz = p.size_totale();
142 Cerr <<
Process::me() <<
" grad(1) aretes = " << finl;
146 for (i = 0; i < nb_elem_tot; i++)
150 int nbf = volumes_entrelaces.
size();
151 for (i = 0; i < nbf; i++)
153 r(i, comp) /= volumes_entrelaces(i);
154 Cerr <<
Process::me() <<
" grad(x-1) elem = " << finl;
159 for (i = nb_elem_tot; i < nb_elem_tot + nb_som_tot; i++)
161 p(i) = coord_sommets(i - nb_elem_tot, 0) - 1;
165 for (i = 0; i < nbf; i++)
167 r(i, comp) /= volumes_entrelaces(i);
168 Cerr <<
Process::me() <<
" grad(x-1) som = " << finl;
177 int nb_bords = les_cl.size();
179 for (
int n_bord = 0; n_bord < nb_bords; n_bord++)
185 int num2 = num1 + le_bord.
nb_faces();
189 CIntArrView face_associee = la_cl_perio.
face_associee().view_ro();
190 DoubleTabView grad = tab_grad.
view_rw();
191 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(num1, num1+le_bord.
nb_faces()/2), KOKKOS_LAMBDA(
const int face)
193 int face_ass = num1 + face_associee(face - num1);
194 for (
int comp = 0; comp < dim; comp++)
196 grad(face, comp) += grad(face_ass, comp);
197 grad(face_ass, comp) = grad(face, comp);
200 end_gpu_timer(__KERNEL_NAME__);
204 if (sub_type(
Symetrie, la_cl.valeur()))
206 CDoubleTabView face_normales = domaine_VEF.
face_normales().view_ro();
207 DoubleTabView grad = tab_grad.
view_rw();
208 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(num1, num2), KOKKOS_LAMBDA(
const int face)
212 for (
int comp = 0; comp < dim; comp++)
214 psc += grad(face, comp) * face_normales(face, comp);
215 norm += face_normales(face, comp) * face_normales(face, comp);
218 if (std::fabs(norm) >= DMINFLOAT)
220 for (
int comp = 0; comp < dim; comp++)
221 grad(face, comp) -= psc * face_normales(face, comp);
223 end_gpu_timer(__KERNEL_NAME__);
227 DoubleTabView grad = tab_grad.
view_wo();
228 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::MDRangePolicy<Kokkos::Rank<2>>({num1,0}, {num2,dim}), KOKKOS_LAMBDA(
const int face,
const int comp)
230 grad(face, comp) = 0;
232 end_gpu_timer(__KERNEL_NAME__);
244 const Domaine& domaine = domaine_VEF.
domaine();
245 const IntTab& elem_faces = domaine_VEF.
elem_faces();
246 int nfe = domaine.nb_faces_elem();
247 int nb_elem_tot = domaine.nb_elem_tot();
249 CDoubleTabView face_normales = domaine_VEF.
face_normales().view_ro();
257 int nb_bords = les_cl.size();
259 for (
int n_bord = 0; n_bord < nb_bords; n_bord++)
267 int num2 = num1 + le_bord.
nb_faces();
268 CDoubleTabView flux_impose = la_sortie_libre.
flux_impose().view_ro();
269 DoubleTabView grad = tab_grad.
view_rw();
270 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(num1, num2), KOKKOS_LAMBDA(
const int face)
272 double P_imp = flux_impose(face - num1, 0);
274 for (
int comp = 0; comp < dim; comp++)
275 grad(face, comp) += diff * face_normales(face, comp) * porosite_face(face);
277 end_gpu_timer(__KERNEL_NAME__);
283 Cerr <<
"Warning not tested on GPU" << finl;
287 int num2 = num1 + le_bord.
nb_faces();
288 DoubleTabView grad = tab_grad.
view_rw();
289 CDoubleTabView pre = tab_pre.
view_ro();
290 CIntTabView face_voisins = domaine_VEF.
face_voisins().view_ro();
291 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(num1, num2), KOKKOS_LAMBDA(
const int face)
293 int elem = face_voisins(face,0);
294 double Pstar_OSWR = pre(elem,0);
295 double diff = Pstar_OSWR*0;
296 for (
int comp = 0; comp < dim; comp++)
297 grad(face, comp) += diff * face_normales(face, comp) * porosite_face(face);
299 end_gpu_timer(__KERNEL_NAME__);
304 CIntTabView face_voisins = domaine_VEF.
face_voisins().view_ro();
305 CIntTabView elem_faces_v = elem_faces.
view_ro();
306 CDoubleTabView pre = tab_pre.
view_ro();
307 DoubleTabView grad = tab_grad.
view_rw();
310 auto kern_elem = KOKKOS_LAMBDA(
int
313 for (
int indice = 0; indice < nfe; indice++)
315 double pe = pre(elem, 0);
316 int face = elem_faces_v(elem, indice);
318 if (elem != face_voisins(face, 0)) signe = -1;
319 for (
int comp = 0; comp < dim; comp++)
321 double val = pe * signe * face_normales(face, comp) * porosite_face(face);
322 Kokkos::atomic_sub(&grad(face, comp), val);
328 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_elem_tot, kern_elem);
329 end_gpu_timer(__KERNEL_NAME__);
338 const Domaine& domaine = domaine_VEF.
domaine();
339 const Domaine& dom = domaine;
342 const DoubleTab& tab_face_normales = domaine_VEF.
face_normales();
344 const IntTab& tab_som_elem = domaine.les_elems();
345 const IntTab& tab_elem_faces = domaine_VEF.
elem_faces();
346 const IntTab& tab_face_voisins = domaine_VEF.
face_voisins();
348 int nfe = domaine.nb_faces_elem();
350 int nb_elem_tot = domaine.nb_elem_tot();
352 if (som_.size_array() == 0)
355 som_.resize(nb_elem_tot, nfe);
356 coeff_som_.resize(nb_elem_tot);
357 for (
int el = 0; el < nb_elem_tot; el++)
360 for (
int indice = 0; indice < nfe; indice++)
365 CIntTabView elem_faces = tab_elem_faces.
view_ro();
366 CIntTabView face_voisins = tab_face_voisins.
view_ro();
367 CDoubleTabView face_normales = tab_face_normales.
view_ro();
368 CDoubleArrView porosite_face = tab_porosite_face.view_ro();
369 CDoubleArrView coeff_som = coeff_som_.view_ro();
370 CIntTabView som_v = som_.view_ro();
371 CDoubleArrView pre =
static_cast<const ArrOfDouble&
>(tab_pre).view_ro();
372 DoubleTabView grad = tab_grad.
view_rw();
375 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
376 Kokkos::MDRangePolicy<Kokkos::Rank<2>>({0, 0}, {nb_elem_tot, nfe}),
377 KOKKOS_LAMBDA (
int elem,
int indice)
379 int face = elem_faces(elem,indice);
382 if (elem != face_voisins(face,0))
386 for (
int comp = 0; comp < dim; comp++)
387 sigma[comp] = face_normales(face,comp) * signe;
389 for (
int indice2 = 0; indice2 < nfe; indice2++)
391 int face2 = elem_faces(elem,indice2);
392 for (
int comp = 0; comp < dim; comp++)
394 Kokkos::atomic_add(&grad(face2,comp), -(coeff_som(elem) * pre(som_v(elem,indice)) * sigma[comp] * porosite_face(face2)));
398 end_gpu_timer(__KERNEL_NAME__);
400 bool has_sortie_libre =
false;
402 int nb_bords = les_cl.size();
403 for (
int n_bord = 0; n_bord < nb_bords; n_bord++)
409 if (has_sortie_libre)
411 for (
int n_bord = 0; n_bord < nb_bords; n_bord++)
419 int num2 = num1 + le_bord.
nb_faces();
420 CDoubleTabView flux_impose = sortie_libre.flux_impose().view_ro();
421 CIntTabView face_sommets = domaine_VEF.
face_sommets().view_ro();
423 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(num1, num2), KOKKOS_LAMBDA(
const int face)
425 const double P_imp = flux_impose(face - num1, 0);
426 for (
int indice = 0; indice < (nfe - 1); indice++)
428 int som = nps + renum_som_perio(face_sommets(face, indice));
429 for (
int comp = 0; comp < dim; comp++)
430 grad(face, comp) -= 1. / dim * face_normales(face, comp) * (pre(som) - P_imp) *
434 end_gpu_timer(__KERNEL_NAME__);
446 const Domaine& domaine = domaine_VEF.
domaine();
448 const DoubleTab& face_normales = domaine_VEF.
face_normales();
450 const IntTab& som_elem = domaine.les_elems();
451 const IntTab& elem_faces = domaine_VEF.
elem_faces();
452 const IntTab& face_voisins = domaine_VEF.
face_voisins();
457 int nfe = domaine.nb_faces_elem();
458 int nb_elem_tot = domaine.nb_elem_tot();
463 for (
int elem = 0; elem < nb_elem_tot; elem++)
465 for (indice = 0; indice < nfe; indice++)
468 int face = elem_faces(elem, indice);
470 if (elem != face_voisins(face, 0))
472 for (
int comp = 0; comp <
dimension; comp++)
473 sigma[comp] = signe * face_normales(face, comp);
475 for (
int isom = 0; isom < 3; isom++)
477 int somi = som_elem(elem, isom);
478 int facei = elem_faces(elem, isom);
480 if (face_voisins(facei, 0) != elem)
482 for (
int jsom = isom + 1; jsom < 4; jsom++)
484 int somj = som_elem(elem, jsom);
485 int facej = elem_faces(elem, jsom);
487 if (face_voisins(facej, 0) != elem)
489 int arete = chercher_arete(elem, somi, somj, elem_aretes, aretes_som);
490 arete = renum_arete_perio[arete];
493 double pa = pre(npa + arete);
495 for (
int ksom = 0; ksom < 4; ksom++)
497 int face2 = elem_faces(elem, ksom);
498 if ((ksom == isom) || (ksom == jsom))
502 for (
int comp = 0; comp < 3; comp++)
503 grad(face2, comp) += porosite_face(face2) * 1. / 15. * (signei * face_normales(facei, comp) + signej * face_normales(facej, comp)) * pa;
509 while ((niinij == jsom) || (niinij == isom))
512 int facek = elem_faces(elem, niinij);
514 if (face_voisins(facek, 0) != elem)
516 for (
int comp = 0; comp < 3; comp++)
517 grad(face2, comp) += porosite_face(face2) * 2. / 15. * signek * face_normales(facek, comp) * pa;
527 const IntTab& face_sommets = domaine_VEF.
face_sommets();
528 int nb_bords = les_cl.size();
529 for (
int n_bord = 0; n_bord < nb_bords; n_bord++)
535 int num2 = num1 + le_bord.
nb_faces();
538 for (
int face = num1; face < num2; face++)
540 int elem = face_voisins(face, 0);
541 for (
int i = 0; i < 2; i++)
543 int somi = face_sommets(face, i);
544 for (
int j = i + 1; j < 3; j++)
546 int somj = face_sommets(face, j);
547 int arete = chercher_arete(elem, somi, somj, elem_aretes, aretes_som);
548 arete = renum_arete_perio[arete];
549 for (
int comp = 0; comp <
dimension; comp++)
550 grad(face, comp) -= porosite_face(face) * 0 * face_normales(face, comp) * pre(npa + arete);
639 assert_espace_virtuel_vect(pre);
641 assert_invalide_items_non_calcules(grad);
646 verifier(*
this, init, domaine_VEF, pre, grad);
672 const IntTab& face_voisins = domaine_VEF.
face_voisins();
674 const DoubleTab& face_normales = domaine_VEF.
face_normales();
683 la_pression_P1B.
filtrage(domaine_VEF, la_pression_P1B);
687 const DoubleVect& pression_P1B = la_pression_P1B.
champ_filtre();
692 int nb_som_par_face = sommets.
dimension(1);
693 CIntTabView face_voisins_v = face_voisins.
view_ro();
694 CIntTabView sommets_v = sommets.
view_ro();
695 CDoubleTabView face_normales_v = face_normales.
view_ro();
696 CDoubleArrView pression_P1B_v = pression_P1B.view_ro();
697 DoubleTabView flux_bords_v =
flux_bords_.view_wo();
700 auto kern_flux_bords = KOKKOS_LAMBDA(
int
703 int elem = face_voisins_v(face, 0);
704 double pres_tot = 0.;
706 if (alphaE) pres_tot = pression_P1B_v(elem);
710 double pres_som = 0.;
711 for (
int som = 0; som < nb_som_par_face; som++)
712 pres_som += pression_P1B_v(nps + sommets_v(face, som));
713 pres_tot += coeff_P1 * pres_som;
716 for (
int i = 0; i < dim; i++)
717 flux_bords_v(face, i) = pres_tot * face_normales_v(face, i);
720 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_faces_bord, kern_flux_bords);
721 end_gpu_timer(__KERNEL_NAME__);
728 const int impr_sum = (domaine_VEF.
domaine().bords_a_imprimer_sum().est_vide() ? 0 : 1);
729 const int impr_bord = (domaine_VEF.
domaine().bords_a_imprimer().est_vide() ? 0 : 1);
750 for (
int n_bord = 0; n_bord < nb_bord; n_bord++)
754 int impr_boundary = (domaine_VEF.
domaine().bords_a_imprimer_sum().contient(le_bord.
le_nom()) ? 1 : 0);
756 int nfin = ndeb + le_bord.
nb_faces();
757 for (
int face = ndeb; face < nfin; face++)
762 tab_flux_bords(0, n_bord, 0) +=
flux_bords_(face, 0);
763 tab_flux_bords(0, n_bord, 1) +=
flux_bords_(face, 1);
767 tab_flux_bords(2, n_bord, 0) +=
flux_bords_(face, 1) * xgr(face, 0) -
flux_bords_(face, 0) * xgr(face, 1);
770 tab_flux_bords(1, n_bord, 0) +=
flux_bords_(face, 0);
771 tab_flux_bords(1, n_bord, 1) +=
flux_bords_(face, 1);
776 tab_flux_bords(0, n_bord, 0) +=
flux_bords_(face, 0);
777 tab_flux_bords(0, n_bord, 1) +=
flux_bords_(face, 1);
778 tab_flux_bords(0, n_bord, 2) +=
flux_bords_(face, 2);
783 tab_flux_bords(2, n_bord, 0) +=
flux_bords_(face, 2) * xgr(face, 1) -
flux_bords_(face, 1) * xgr(face, 2);
784 tab_flux_bords(2, n_bord, 1) +=
flux_bords_(face, 0) * xgr(face, 2) -
flux_bords_(face, 2) * xgr(face, 0);
785 tab_flux_bords(2, n_bord, 2) +=
flux_bords_(face, 1) * xgr(face, 0) -
flux_bords_(face, 0) * xgr(face, 1);
789 tab_flux_bords(1, n_bord, 0) +=
flux_bords_(face, 0);
790 tab_flux_bords(1, n_bord, 1) +=
flux_bords_(face, 1);
791 tab_flux_bords(1, n_bord, 2) +=
flux_bords_(face, 2);
814 for (
int n_bord = 0; n_bord < nb_bord; n_bord++)
818 Flux_grad.add_col(tab_flux_bords(0, n_bord, 0));
819 Flux_grad.add_col(tab_flux_bords(0, n_bord, 1));
830 Flux_grad.add_col(tab_flux_bords(0, n_bord, 0));
831 Flux_grad.add_col(tab_flux_bords(0, n_bord, 1));
832 Flux_grad.add_col(tab_flux_bords(0, n_bord, 2));
854 const LIST(
Nom) &Liste_bords_a_imprimer = domaine_VEF.
domaine().bords_a_imprimer();
855 if (!Liste_bords_a_imprimer.est_vide())
859 for (
int n_bord = 0; n_bord < nb_bord; n_bord++)
864 int nfin = ndeb + le_bord.
nb_faces();
865 if (domaine_VEF.
domaine().bords_a_imprimer().contient(le_bord.
le_nom()))
869 Flux_grad_face <<
"# Force par face sur " << le_bord.
le_nom() <<
" au temps ";
871 Flux_grad_face <<
" : " << finl;
873 for (
int face = ndeb; face < nfin; face++)
875 Flux_grad_face <<
"# Face a x= " << domaine_VEF.
xv(face, 0) <<
" y= " << domaine_VEF.
xv(face, 1);
877 Flux_grad_face <<
" z= " << domaine_VEF.
xv(face, 2);
881 Flux_grad_face << finl;
DoubleTab & filtrage(const Domaine_VEF &, const Champ_base &, bool implicitCoupling=false) const
const DoubleTab & champ_filtre() const
class Cond_lim Generic class used to represent any class
class Conds_lim This class represents a vector of boundary conditions.
Classe Dirichlet_homogene This class is the base class of the hierarchy of homogeneous Dirichlet-type...
Dirichlet This class is the base class of the hierarchy of Dirichlet-type boundary conditions.
int_t nb_elem_tot() const
const IntTab_t & aretes_som() const
returns the connectivity array edges/vertices.
int_t get_renum_som_perio(int_t i) const
const DoubleTab_t & coord_sommets() const
int_t elem_aretes(int_t i, int j) const
returns the number of the j-th edge of the i-th element.
int_t nb_som_tot() const
Returns the total number of vertices of the domain i.e. the number of real and virtual vertices on th...
int type_elem_Cl(int i) const
class Domaine_Cl_dis_base Domaine_Cl_dis_base objects represent discretized boundary conditions
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
int numero_premiere_arete() const
const IntVect & get_ok_arete() const
IntVect & rang_elem_non_std()
int numero_premier_sommet() const
int get_modif_div_face_dirichlet() const
const ArrOfInt & get_renum_arete_perio() const
DoubleVect & volumes_entrelaces()
virtual double face_normales(int face, int comp) const
double xv(int num_face, int k) const
int face_sommets(int i, int j) const
Returns the index of the i-th vertex of face num_face.
int elem_faces(int i, int j) const
Returns the index of the i-th face of element num_elem; the face numbering convention is.
double xp(int num_elem, int k) const
DoubleTab calculer_xgr() const
Computes the xgr array for the computation of moments of forces at boundaries.
int premiere_face_int() const
A face is internal if and only if it separates two elements.
int face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in direction i.
int nb_faces_bord() const
Returns the number of faces on which boundary conditions are applied:
int moments_a_imprimer() const
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
const Domaine & domaine() const
Sortie & syncfile() override
Triggers writing to disk of the data accumulated on the different processors since the last call to s...
Class defining operators and methods for all reading operation in an input flow (file,...
virtual const Milieu_base & milieu() const =0
Probleme_base & probleme()
Returns the problem associated with the equation.
int num_premiere_face() const
const Nom & le_nom() const override
Returns the name of the geometric boundary.
DoubleVect & porosite_face()
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Navier_Stokes_std This class carries the terms of the momentum equation.
Champ_Inc_base & pression_pa()
virtual bool getCouplingInfoForFiltering() const
Neumann_sortie_libre This class represents an open boundary without imposed velocity.
virtual double flux_impose(int i) const
Returns the value of the imposed flux on the i-th component of the field representing the flux at the...
class Nom: a character string for naming TRUST objects.
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.
class Op_Grad_VEF_P1B_Face
DoubleTab & modifier_grad_pour_Cl(DoubleTab &) const
void associer(const Domaine_dis_base &, const Domaine_Cl_dis_base &, const Champ_Inc_base &) override
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
DoubleTab & ajouter_elem(const DoubleTab &, DoubleTab &) const
void calculer_flux_bords() const override
static double calculer_coef_som(int elem, const Domaine_Cl_VEF &zcl, const Domaine_VEF &domaine_VEF)
int impr(Sortie &) const override
DOES NOTHING - to override in derived classes.
const Domaine_VEF & domaine_vef() const
DoubleTab & ajouter_aretes(const DoubleTab &, DoubleTab &) const
DoubleTab & ajouter_som(const DoubleTab &, DoubleTab &) const
Classe Operateur_Grad_base This class is the base of the hierarchy of operators representing.
SFichier Flux_grad_moment
void ouvrir_fichier_partage(EcrFicPartage &, const Nom &, const int flag=1) const
Opening/creation of a shared file for printing an operator. To override in derived classes.
void ouvrir_fichier(SFichier &os, const Nom &, const int flag=1) const
Opening/creation of a file for printing an operator. To override in derived classes.
class Periodique This class represents a periodic boundary condition.
int face_associee(int i) const
const Schema_Temps_base & schema_temps() const
Returns the time scheme associated with the problem.
static void mp_sum_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
static int me()
Returns the rank of the local processor in the current communication group. See Comm_Group::rank() an...
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
static int je_suis_maitre()
Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
Class Robin_VEF for Robin boundary conditions.
double temps_courant() const
Returns the current time.
void imprimer_temps_courant(SFichier &) const
Base class for output streams.
Symetrie On symmetry faces, the following properties hold:
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, View< _TYPE_, _SHAPE_ > > view_wo()
void ecrit(Sortie &) const override
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, ConstView< _TYPE_, _SHAPE_ > > view_ro() const
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, View< _TYPE_, _SHAPE_ > > view_rw()
_SIZE_ dimension(int d) const