16#include <Op_Conv_VEF_Face.h>
17#include <Champ_P1NC.h>
18#include <Porosites_champ.h>
19#include <Convection_tools.h>
20#include <Dirichlet_homogene.h>
21#include <Periodique.h>
23#include <Neumann_sortie_libre.h>
28#include <Comm_Group_MPI.h>
34#if defined(__cpp_if_constexpr)
35#define TRUST_IFCONSTEXPR if constexpr
37#define TRUST_IFCONSTEXPR if
38#pragma message("Warning: your C++ std is old and does not enables 'if constexpr', switching to plain 'if'. Think about upgrading to C++ 17.")
66 if (!(type_op_lu==
"amont") && !(type_op_lu==
"muscl") && !(type_op_lu==
"centre"))
68 Cerr << type_op_lu <<
" is not understood by " <<
que_suis_je() << finl;
69 Cerr <<
" choose among: amont - muscl - centre " << finl;
73 if (type_op_lu==
"muscl")
82 Cerr <<
" choose among: minmod - vanleer - vanalbada - chakravarthy - superbee " << finl;
115 Cerr <<
"the order after " <<
type_lim <<
" in " <<
que_suis_je() <<
" must be 1, 2, or 3" << finl;
125 if (type_op_lu==
"centre")
132 Cerr <<
"the order after " << type_op_lu <<
" in " <<
que_suis_je() <<
" must be 1 or 2 " << finl;
137 if (type_op_lu==
"amont")
158 for (
int poly = 0; poly < nb_elem_tot; poly++)
160 int rang = rang_elem_non_std(poly);
207template<
int ordre,
bool isMuscl,
bool virtual_only>
215 const double third = 1.0/3;
216 const double twelvth = 1.0/(3+3*3);
219 int nb_faces = kernel_data.
nb_faces;
223 double alpha = kernel_data.
alpha;
224 int marq = kernel_data.
marq;
227 bool isAmont = kernel_data.
isAmont;
238 CDoubleTabView xp_v = kernel_data.
xp_v;
239 CDoubleTabView xv_v = kernel_data.
xv_v;
242 CIntTabView KEL_v = kernel_data.
KEL_v;
245 CDoubleTabView vitesse_v = kernel_data.
vitesse_v;
247 CDoubleTabView3 gradient_v = kernel_data.
gradient_v;
250 DoubleTabView resu_v = kernel_data.
resu_v;
251 DoubleTabView flux_b_v = kernel_data.
flux_b_v;
254 const int nbeg = virtual_only ? kernel_data.
nb_elem : 0;
261 start_gpu_timer(__KERNEL_NAME__);
265 Kokkos::parallel_for(Kokkos::MDRangePolicy<Kokkos::Rank<2>>({nbeg,0}, {nend, kernel_data.
nfa7}), KOKKOS_LAMBDA(
const int poly,
const int fa7)
267 Kokkos::parallel_for(Kokkos::RangePolicy<>(nbeg, nend), KOKKOS_LAMBDA(
const int poly)
273 for (
int face_adj = 0; face_adj < nfac_; face_adj++)
275 int fac = elem_faces_v(poly, face_adj);
276 face[face_adj] = fac;
277 if (fac < nb_faces) contrib = 1;
283 bool calcul_flux_en_un_point = (ordre != 3) && (ordre == 1 || traitement_pres_bord_v(poly));
284 bool flux_en_un_point = calcul_flux_en_un_point || option_calcul_flux_en_un_point;
285 double vs[3] = {0.0, 0.0, 0.0};
289 int les_elems_[4] = { les_elems_v(poly,0), les_elems_v(poly,1), les_elems_v(poly,2), les_elems_v(poly,3) };
291 double coeff = (marq == 0) ? 1. / porosite_elem_v(poly) : 1.0;
292 int itypcl = type_elem_Cl_v(poly);
294 int rang = rang_elem_non_std_v(poly);
296 TRUST_IFCONSTEXPR (ordre == 3)
299 for (
int i = 0; i < nsom_; i++)
300 for (
int j = 0; j < dim; j++)
301 xsom[i * 3 + j] = coord_sommets_v(les_elems_[i], j);
302 int idirichlet, n1, n2, n3;
303 calcul_xg_tetra(xc, xsom, itypcl, idirichlet, n1, n2, n3);
306 double xp[3] = { xp_v(poly,0), xp_v(poly,1), xp_v(poly,2) };
309 for (
int i = 0; i < nfac_; i++)
311 poro[i] = porosite_face_v(face[i]);
313 for (
int j = 0; j < dim; j++)
315 double vf = vitesse_v(face[i], j);
317 vs[j] += vf * poro[i];
320 for (
int i = 0; i < nfac_; i++)
322 for (
int j = 0; j < dim; j++)
324 vsom[i*3 + j] = vs[j] - 3.0 * vfa[i*3 + j] * poro[i];
329 calcul_vc_tetra(face, vc, vs, vsom, vfa, itypcl, poro);
333 for (
int fa7 = 0; fa7 < kernel_data.
nfa7; fa7++)
336 int KEL_v_[4] = {KEL_v(0, fa7), KEL_v(1, fa7),KEL_v(2, fa7),KEL_v(3, fa7)};
337 int les_kel_elems_[2]= {0,0};
342 double psc_c = 0, psc_s = 0, psc_s2 = 0;
346 for (
int j = 0; j < 3; j++)
349 ? facette_normales_v(poly, fa7, j)
350 : normales_facettes_Cl_v(rang, fa7, j);
354 for (
int i = 0; i < 3; i++)
356 psc_c += vc[i] * cc[i];
397 psc_s += vsom[0] * cc[0] + vsom[1] * cc[1] + vsom[2] * cc[2];
398 les_kel_elems_[0]=les_elems_[0];
402 psc_s += vsom[3] * cc[0] + vsom[4] * cc[1] + vsom[5] * cc[2];
403 les_kel_elems_[0]=les_elems_[1];
406 psc_s += vsom[6] * cc[0] + vsom[7] * cc[1] + vsom[8] * cc[2];
407 les_kel_elems_[0]=les_elems_[2];
411 psc_s += vsom[9] * cc[0] + vsom[10] * cc[1] + vsom[11] * cc[2];
412 les_kel_elems_[0]=les_elems_[3];
419 psc_s2 += vsom[0] * cc[0] + vsom[1] * cc[1] + vsom[2] * cc[2];
420 les_kel_elems_[1]=les_elems_[0];
423 psc_s2 += vsom[3] * cc[0] + vsom[4] * cc[1] + vsom[5] * cc[2];
424 les_kel_elems_[1]=les_elems_[1];
427 psc_s2 += vsom[6] * cc[0] + vsom[7] * cc[1] + vsom[8] * cc[2];
428 les_kel_elems_[1]=les_elems_[2];
431 psc_s2 += vsom[9] * cc[0] + vsom[10] * cc[1] + vsom[11] * cc[2];
432 les_kel_elems_[1]=les_elems_[3];
436 int sommet_s = les_kel_elems_[0];
437 int sommet_s2 = les_kel_elems_[1];
441 double psc_m = (psc_c + psc_s + psc_s2) *third;
445 int appliquer_cl_dirichlet = 0;
446 if (option_appliquer_cl_dirichlet)
447 if (est_une_face_de_dirichlet_v(num10) || est_une_face_de_dirichlet_v(num20))
449 appliquer_cl_dirichlet = 1;
454 int face_amont_m = (psc_m >= 0) ? num10 : num20;
456 [[maybe_unused]]
int face_amont_c;
457 int face_amont_s, face_amont_s2;
458 TRUST_IFCONSTEXPR (ordre == 3 && isMuscl)
460 face_amont_c = ((psc_c >= 0) ? num10 : num20);
461 face_amont_s = ((psc_s >= 0) ? num10 : num20) ;
462 face_amont_s2 = ((psc_s2 >= 0) ? num10 : num20) ;
466 face_amont_c= face_amont_m;
467 face_amont_s= face_amont_m;
468 face_amont_s2= face_amont_m;
471 int item_m, item_s, item_s2;
472 [[maybe_unused]]
int item_c;
474 TRUST_IFCONSTEXPR (isMuscl)
477 item_m = face_amont_m;
478 item_c = face_amont_c;
479 item_s = face_amont_s;
480 item_s2 = face_amont_s2;
491 int dir = (psc_m >= 0) ? 0 : 1;
492 int kel = (psc_m >= 0) ? KEL_v_[0] : KEL_v_[1];
510 double centre_fa7[3];
513 int isom_glob_0 = les_kel_elems_[0];
514 int isom_glob_1 = les_kel_elems_[1];
516 for (
int j = 0; j < 3; j++)
518 centre_fa7[j] = xp[j]
519 + coord_sommets_v(isom_glob_0, j)
520 + coord_sommets_v(isom_glob_1, j);
521 centre_fa7[j] *= third;
524 bool flux_avec_m = isAmont || appliquer_cl_dirichlet;
532 for (
int j = 0; j < 3; j++)
534 xv_m_arr[j] = xv_v(num_face, j);
535 xv_s_arr[j] = xv_v(face_amont_s, j);
536 xv_s2_arr[j] = xv_v(face_amont_s2, j);
537 cs_s_arr[j] = coord_sommets_v(sommet_s, j);
538 cs_s2_arr[j] = coord_sommets_v(sommet_s2, j);
541 for (
int comp0 = 0; comp0 < ncomp_ch_transporte; comp0++)
543 double inco_m = transporte_face_v(face_amont_m, comp0);
546 flux = inco_m * psc_m;
550 double inco_s = transporte_face_v(face_amont_s, comp0);
551 double inco_s2 = transporte_face_v(face_amont_s2, comp0) ;
552 for (
int j = 0; j < dim; j++)
554 double gm = gradient_v(item_m, comp0, j);
555 double gs = gradient_v(item_s, comp0, j);
556 double gs2 = gradient_v(item_s2, comp0, j);
560 inco_m += gm * (rang == -1 ? centre_fa7[j] - xv_m_arr[j]
561 : vecteur_face_facette_Cl_v(rang, fa7, j, dir));
562 inco_s += gs * (cs_s_arr[j] - xv_s_arr[j]);
563 inco_s2+= gs2 * (cs_s2_arr[j] - xv_s2_arr[j]);
569 TRUST_IFCONSTEXPR (ordre == 3)
571 inco_c = transporte_face_v(face_amont_c, comp0);
572 for (
int j = 0; j < dim; j++)
573 inco_c += gradient_v(item_c, comp0, j) * (-xv_v(face_amont_c, j) + xc[j]);
576 inco_c = dim * inco_m - inco_s - inco_s2;
578 if (flux_en_un_point)
580 flux = inco_m * psc_m;
583 flux = (inco_c * psc_c + inco_s * psc_s + inco_s2 * psc_s2 + 9 * inco_m * psc_m)*twelvth;
589 int compo = ncomp_ch_transporte == 1 ? 0 : comp0;
590 Kokkos::atomic_sub(&resu_v(num10, compo), flux);
591 Kokkos::atomic_add(&resu_v(num20, compo), flux);
592 if (num10 < nb_faces_bord)
593 Kokkos::atomic_add(&flux_b_v(num10, compo), flux);
594 if (num20 < nb_faces_bord)
595 Kokkos::atomic_sub(&flux_b_v(num20, compo), flux);
601 if (virtual_only) end_gpu_timer(__KERNEL_NAME__);
606template<
int ordre,
bool isMuscl>
607void compute_flux_tetra_kernel(
const FluxTetraKernelData& kernel_data, DoubleTab& tab_gradient)
613 compute_flux_tetra_kernel<ordre, isMuscl,
false>(kernel_data);
617 compute_flux_tetra_kernel<ordre, isMuscl,
true>(kernel_data);
633 return ajouter_gen(transporte, la_vitesse_aux_faces, resu);
642 const DoubleTab& velocity_tab=la_vitesse.
valeurs();
646 DoubleTab transporte_face_;
647 DoubleTab vitesse_face_;
651 const DoubleTab& transporte_face = modif_par_porosite_si_flag(transporte,transporte_face_,!marq,porosite_face);
652 const DoubleTab& vitesse_face = modif_par_porosite_si_flag(la_vitesse.
valeurs(),vitesse_face_,marq,porosite_face);
654 const IntTab& elem_faces = domaine_VEF.
elem_faces();
656 const Domaine& domaine = domaine_VEF.
domaine();
659 const int nb_elem = domaine_VEF.
nb_elem();
663 int nb_faces = domaine_VEF.
nb_faces();
664 int nfac = domaine.nb_faces_elem();
665 int nsom = domaine.nb_som_elem();
668 const IntTab& les_elems=domaine.les_elems();
672 int option_appliquer_cl_dirichlet = (
ordre_==3 ? 1 : 0);
673 int option_calcul_flux_en_un_point = 0;
682 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
689 const IntTab& face_voisins = domaine_VEF.
face_voisins();
690 for (
int ind_face=0; ind_face<nb_faces_tot; ind_face++)
692 int num_face = le_bord.
num_face(ind_face);
693 int elem = face_voisins(num_face,0);
703 ArrOfInt est_un_sommet_de_bord_(domaine_VEF.
nb_som_tot());
704 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
712 for (
int ind_face=0; ind_face<nb_faces_tot; ind_face++)
713 for (
int som=0; som<size; som++)
715 int face = le_bord.
num_face(ind_face);
716 est_un_sommet_de_bord_[domaine_VEF.
face_sommets(face,som)]=1;
720 for (
int elem=0; elem<nb_elem_tot; elem++)
722 if (rang_elem_non_std(elem)!=-1)
726 for (
int n_som=0; n_som<nsom; n_som++)
727 if (est_un_sommet_de_bord_[les_elems(elem,n_som)])
735 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
742 for (
int ind_face=0; ind_face<nb_faces_tot; ind_face++)
744 int num_face = le_bord.
num_face(ind_face);
764 if ((nom_elem==
"Tetra_VEF")||(nom_elem==
"Tri_VEF"))
768 int ncomp_ch_transporte=(transporte_face.
nb_dim() == 1?1:transporte_face.
dimension(1));
771 DoubleTrav resu_perio;
772 int nb_faces_perio = 0;
773 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
782 if (nb_faces_perio>0)
784 resu_perio.
resize(nb_faces_perio,ncomp_ch_transporte);
786 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
793 int num2 = num1 + le_bord.
nb_faces();
794 CDoubleTabView resu_v = resu.
view_ro();
795 DoubleTabView resu_perio_v = resu_perio.
view_wo();
796 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(num1, num2), KOKKOS_LAMBDA(
const int num_face)
798 int ind_face = nb_faces_perio + num_face - num1;
799 for (
int comp = 0; comp < ncomp_ch_transporte; comp++)
800 resu_perio_v(ind_face, comp) = resu_v(num_face, comp);
802 end_gpu_timer(__KERNEL_NAME__);
803 nb_faces_perio+=num2-num1;
808 DoubleTab tab_gradient;
833 for (
int n_bord = 0; n_bord < nb_bord; n_bord++)
838 int num2 = num1 + le_bord.
nb_faces();
839 if (sub_type(
Symetrie, la_cl.valeur()))
843 CIntTabView face_voisins = domaine_VEF.
face_voisins().view_ro();
844 CDoubleTabView face_normale = domaine_VEF.
face_normales().view_ro();
847 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(num1, num2), KOKKOS_LAMBDA(
const int fac)
849 int elem1 = face_voisins(fac, 0);
850 for (
int comp0 = 0; comp0 < ncomp_ch_transporte; comp0++)
851 for (
int i = 0; i < dim; i++)
852 gradient_face(fac, comp0, i) = gradient_elem(elem1, comp0, i);
858 for (
int comp0 = 0; comp0 < ncomp_ch_transporte; comp0++)
859 for (
int i = 0; i < dim; i++)
861 double carre_surface = 0;
863 for (
int j = 0; j < dim; j++)
865 double ndS = face_normale(fac, j);
866 carre_surface += ndS * ndS;
867 tmp += gradient_face(fac, comp0, j) * ndS;
869 gradient_face(fac, comp0, i) -= tmp * face_normale(fac, i) / carre_surface;
873 end_gpu_timer(__KERNEL_NAME__);
879 CIntTabView face_voisins = domaine_VEF.
face_voisins().view_ro();
881 CIntArrView faces_doubles = domaine_VEF.
faces_doubles().view_ro();
883 DoubleTabView3 gradient = tab_gradient.
view_wo<3>();
885 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_2D({0,0}, {nb_faces, ncomp_ch_transporte}), KOKKOS_LAMBDA(
const int fac,
const int comp0)
887 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, nb_faces), KOKKOS_LAMBDA(
const int fac)
890 if (faces_doubles[fac] || fac>=premiere_face_int )
892 int elem1 = face_voisins(fac, 0);
893 int elem2 = face_voisins(fac, 1);
895 if (ordre == 3 && (traitement_pres_bord[elem1] || traitement_pres_bord[elem2]))
898 for (
int comp0 = 0; comp0 < ncomp_ch_transporte; comp0++)
900 for (
int i = 0; i < dim; i++)
902 double grad1 = gradient_elem(elem1, comp0, i);
903 double grad2 = gradient_elem(elem2, comp0, i);
904 gradient(fac, comp0, i) = FCT_LIMITEUR(grad1, grad2, limiteur);
908 end_gpu_timer(__KERNEL_NAME__);
909 if(nom_elem==
"Tetra_VEF")
923 flux_b.
resize(nb_faces_bord,ncomp_ch_transporte);
928 const IntTab& KEL=type_elemvef.
KEL();
929 const DoubleTab& xv=domaine_VEF.
xv();
930 const DoubleTab& coord_sommets=domaine.coord_sommets();
939 int nombre_passes = (alpha==1 ? 1 : 2);
940 for (
int passe=1; passe<=nombre_passes; passe++)
954 if(nom_elem==
"Tetra_VEF")
964 kernel_data.
nfa7 = nfa7;
966 kernel_data.
alpha = alpha;
967 kernel_data.
marq = marq;
981 kernel_data.
xp_v = domaine_VEF.
xp().view_ro();
995 if (type_op_boucle ==
muscl)
1000 compute_flux_tetra_kernel< 1,
true>(kernel_data, tab_gradient);
1005 compute_flux_tetra_kernel< 2,
true>(kernel_data, tab_gradient);
1009 compute_flux_tetra_kernel< 3,
true>(kernel_data, tab_gradient);
1016 compute_flux_tetra_kernel< 1,
false>(kernel_data, tab_gradient);
1020 compute_flux_tetra_kernel< 2,
false>(kernel_data, tab_gradient);
1024 compute_flux_tetra_kernel< 3,
false>(kernel_data, tab_gradient);
1031 const DoubleTab& vecteur_face_facette = ref_cast_non_const(
Domaine_VEF,domaine_VEF).vecteur_face_facette();
1032 ArrOfInt face(nfac);
1039 for (
int poly=0; poly<nb_elem_tot; poly++)
1043 for (
int face_adj=0; face_adj<nfac; face_adj++)
1045 int face_ = elem_faces(poly,face_adj);
1046 face(face_adj)= face_;
1047 if (face_<nb_faces) contrib=1;
1055 vs(j) = velocity_tab(face(0),j)*porosite_face(face(0));
1056 for (
int i=1; i<nfac; i++)
1057 vs(j)+= velocity_tab(face(i),j)*porosite_face(face(i));
1063 for (
int i=0; i<nsom; i++)
1065 vsom(i,j) = (vs(j) -
dimension*velocity_tab(face(i),j)*porosite_face(face(i)));
1070 for (
int j=0; j<nsom; j++)
1072 int num_som = les_elems(poly,j);
1073 for (
int ncomp=0; ncomp<
dimension; ncomp++)
1079 int rang = rang_elem_non_std(poly);
1080 int itypcl = (rang==-1 ? 0 : domaine_Cl_VEF.
type_elem_Cl(rang));
1083 type_elemvef.
calcul_vc(face, vc, vs, vsom, la_vitesse, itypcl, porosite_face);
1090 for (
int i=0; i<nsom; i++)
1092 xsom(i,j) = coord_sommets(les_elems(poly,i),j);
1093 type_elemvef.
calcul_xg(xc,xsom,itypcl,idirichlet,n1,n2,n3);
1099 double coeff=1./porosite_elem(poly);
1104 for (
int fa7=0; fa7<nfa7; fa7++)
1106 int num10 = face(KEL(0,fa7));
1107 int num20 = face(KEL(1,fa7));
1111 cc[i] = facette_normales(poly, fa7, i);
1114 cc[i] = normales_facettes_Cl(rang,fa7,i);
1117 double psc_c=0,psc_s=0,psc_m,psc_s2=0;
1120 for (
int i=0; i<2; i++)
1123 psc_s+=vsom(KEL(2,fa7),i)*cc[i];
1125 psc_m=(psc_c+psc_s)/2.;
1129 for (
int i=0; i<3; i++)
1132 psc_s+=vsom(KEL(2,fa7),i)*cc[i];
1133 psc_s2+=vsom(KEL(3,fa7),i)*cc[i];
1135 psc_m=(psc_c+psc_s+psc_s2)/3.;
1139 int appliquer_cl_dirichlet=0;
1140 if (option_appliquer_cl_dirichlet)
1143 appliquer_cl_dirichlet = 1;
1148 int face_amont_m,dir;
1151 face_amont_m = num10;
1156 face_amont_m = num20;
1160 int face_amont_c=face_amont_m;
1161 int face_amont_s=face_amont_m;
1162 int face_amont_s2=face_amont_m;
1165 face_amont_c = (psc_c >= 0) ? num10 : num20;
1166 face_amont_s = (psc_s >= 0) ? num10 : num20;
1167 face_amont_s2 = (psc_s2 >= 0) ? num10 : num20;
1174 if (type_op_boucle==
muscl)
1176 item_m = face_amont_m;
1177 item_c = face_amont_c;
1178 item_s = face_amont_s;
1179 item_s2 = face_amont_s2;
1182 for (
int comp0=0; comp0<ncomp_ch_transporte; comp0++)
1185 double inco_m = (ncomp_ch_transporte==1?transporte_face(face_amont_m):transporte_face(face_amont_m,comp0));
1186 if (type_op_boucle==
amont || appliquer_cl_dirichlet)
1188 flux = inco_m*psc_m;
1195 inco_m+= tab_gradient(item_m,comp0,j)*vecteur_face_facette(poly,fa7,j,dir);
1198 inco_m+= tab_gradient(item_m,comp0,j)*vecteur_face_facette_Cl(rang,fa7,j,dir);
1201 double inco_s = (ncomp_ch_transporte==1?transporte_face(face_amont_s):transporte_face(face_amont_s,comp0));
1202 int sommet_s = les_elems(poly,KEL(2,fa7));
1204 inco_s+= tab_gradient(item_s,comp0,j)*(-xv(face_amont_s,j)+coord_sommets(sommet_s,j));
1210 inco_s2 = (ncomp_ch_transporte==1?transporte_face(face_amont_s2):transporte_face(face_amont_s2,comp0));
1211 int sommet_s2 = les_elems(poly,KEL(3,fa7));
1213 inco_s2+= tab_gradient(item_s2,comp0,j)*(-xv(face_amont_s2,j)+coord_sommets(sommet_s2,j));
1222 inco_c = (ncomp_ch_transporte==1?transporte_face(face_amont_c):transporte_face(face_amont_c,comp0));
1224 inco_c+= tab_gradient(item_c,comp0,j)*(-xv(face_amont_c,j)+xc(j));
1228 inco_c =
dimension*inco_m-inco_s-inco_s2;
1232 if (calcul_flux_en_un_point || option_calcul_flux_en_un_point)
1234 flux = inco_m*psc_m;
1239 flux = (
dimension==2) ? (inco_c*psc_c + inco_s*psc_s + 4*inco_m*psc_m)/6
1240 : (inco_c*psc_c + inco_s*psc_s + inco_s2*psc_s2 + 9*inco_m*psc_m)/12;
1247 if (ncomp_ch_transporte == 1)
1249 resu(num10) -= flux;
1250 resu(num20) += flux;
1251 if (num10<nb_faces_bord) flux_b(num10,0) += flux;
1252 if (num20<nb_faces_bord) flux_b(num20,0) -= flux;
1256 resu(num10,comp0) -= flux;
1257 resu(num20,comp0) += flux;
1258 if (num10<nb_faces_bord) flux_b(num10,comp0) += flux;
1259 if (num20<nb_faces_bord) flux_b(num20,comp0) -= flux;
1274 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
1283 int num2 = num1 + le_bord.
nb_faces();
1285 CDoubleTabView face_normale = domaine_VEF.
face_normales().view_ro();
1286 CDoubleTabView val_ext = la_sortie_libre.
val_ext().view_ro();
1287 CDoubleTabView transporte_face_v = transporte_face.
view_ro();
1288 CDoubleTabView vitesse_face_v = vitesse_face.
view_ro();
1289 DoubleTabView flux_b_v = flux_b.
view_wo();
1290 DoubleTabView resu_v = resu.
view_rw();
1291 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(num1, num2), KOKKOS_LAMBDA(
const int num_face)
1294 for (
int i=0; i<dim; i++)
1295 psc += vitesse_face_v(num_face,i)*face_normale(num_face,i);
1296 for (
int i=0; i<ncomp_ch_transporte; i++)
1298 double val = psc > 0 ? transporte_face_v(num_face,i) : val_ext(num_face-num1,i);
1299 resu_v(num_face,i) -= psc*val;
1300 flux_b_v(num_face,i) = -psc*val;
1303 end_gpu_timer(__KERNEL_NAME__);
1305 else if (sub_type(
Periodique,la_cl.valeur()))
1310 int num2 = num1 + le_bord.
nb_faces();
1311 CIntArrView face_associee = la_cl_perio.
face_associee().view_ro();
1312 CDoubleTabView resu_perio_v = resu_perio.
view_ro();
1313 DoubleTabView resu_v = resu.
view_rw();
1314 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(num1, num1+le_bord.
nb_faces()/2), KOKKOS_LAMBDA(
const int num_face)
1316 int ind_face = num_face - num1;
1317 int voisine = face_associee(ind_face) + num1;
1318 for (
int comp=0; comp<ncomp_ch_transporte; comp++)
1320 double diff1 = resu_v(num_face,comp) - resu_perio_v(nb_faces_perio+ind_face,comp);
1321 double diff2 = resu_v(voisine,comp) - resu_perio_v(nb_faces_perio+ind_face+voisine-num_face,comp);
1322 resu_v(voisine,comp) += diff1;
1323 resu_v(num_face,comp) += diff2;
1329 end_gpu_timer(__KERNEL_NAME__);
1330 nb_faces_perio+=num2-num1;
1338KOKKOS_INLINE_FUNCTION
void convbisimplicite_dec(
const double psc_,
const int num1,
const int num2,
1339 CDoubleTabView transporte,
const int ncomp,
1340 Matrice_Morse_View matrice,
1341 CDoubleArrView porosite_face,
int phi_u_transportant)
1344 if (!phi_u_transportant)
1345 psc*=porosite_face(psc_>=0 ? num1 : num2);
1346 for (
int comp=0; comp<ncomp; comp++)
1348 int n1=num1*ncomp+comp;
1349 int n2=num2*ncomp+comp;
1350 int n = psc_>=0 ? n1 : n2;
1351 matrice.atomic_add(n1,n,psc);
1352 matrice.atomic_add(n2,n,-psc);
1366 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
1368 const Domaine& domaine = domaine_VEF.
domaine();
1371 const int nb_elem_tot = domaine_VEF.
nb_elem_tot();
1373 int nfac = domaine.nb_faces_elem();
1374 int nsom = domaine.nb_som_elem();
1386 int ncomp_ch_transporte = tab_transporte.
nb_dim() == 1 ? 1 : tab_transporte.
dimension(1);
1390 DoubleTab vitesse_face_;
1394 const DoubleTab& tab_velocity_tab = la_vitesse.
valeurs();
1396 const DoubleTab& tab_vitesse_face=modif_par_porosite_si_flag(tab_velocity_tab,vitesse_face_,marq,tab_porosite_face);
1400 if ((nom_elem==
"Tetra_VEF")||(nom_elem==
"Tri_VEF"))
1412 CIntTabView KEL = type_elemvef.
KEL().
view_ro();
1414 CIntArrView type_elem_Cl = domaine_Cl_VEF.
type_elem_Cl().view_ro();
1415 CIntTabView elem_faces = domaine_VEF.
elem_faces().view_ro();
1417 CDoubleTabView3 facette_normales = domaine_VEF.
facette_normales().view_ro<3>();
1418 CDoubleArrView porosite_face = tab_porosite_face.view_ro();
1421 CDoubleTabView velocity_tab = tab_velocity_tab.
view_ro();
1422 CDoubleTabView transporte = tab_transporte.
view_ro();
1423 Matrice_Morse_View matrice;
1424 matrice.set(matrice_morse);
1425 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, nb_elem_tot), KOKKOS_LAMBDA(
const int poly)
1427 int rang = rang_elem_non_std(poly);
1428 int itypcl= rang==-1 ? 0 : type_elem_Cl(rang);
1432 for (
int face_adj=0; face_adj<nfac; face_adj++)
1433 face[face_adj] = elem_faces(poly,face_adj);
1436 for (
int j=0; j<dim; j++)
1438 vs[j] = velocity_tab(face[0],j)*porosite_face[face[0]];
1439 for (
int i=1; i<nfac; i++)
1440 vs[j] += velocity_tab(face[i],j)*porosite_face[face[i]];
1447 for (
int i=0; i<nsom; i++)
1448 for (
int j=0; j<dim; j++)
1449 vsom[i * dim + j] = (vs[j] - dim*velocity_tab(face[i],j)*porosite_face[face[i]]);
1467 calcul_vc_tetra_views(face,vc,vs,vsom,
vitesse,itypcl,porosite_face);
1469 calcul_vc_tri_views(face,vc,vs,vsom,
vitesse,itypcl,porosite_face);
1472 const double porosite_poly=porosite_elem(poly);
1473 for (
int j=0; j<dim; j++)
1475 vs[j]/=porosite_poly;
1476 vc[j]/=porosite_poly;
1477 for (
int i=0; i<nsom; i++)
1478 vsom[i * dim + j]/=porosite_poly;
1482 double cc[3] = { 0., 0., 0. };
1483 for (
int fa7=0; fa7<nfa7; fa7++)
1486 for (
int i=0; i<dim; i++)
1487 cc[i] = rang==-1 ? facette_normales(poly,fa7,i) : normales_facettes_Cl(rang,fa7,i);
1490 double psc_c=0,psc_s=0,psc_s2=0;
1491 for (
int i=0; i<dim; i++)
1493 psc_c += vc[i]*cc[i];
1494 psc_s += vsom[KEL(2,fa7) * dim + i]*cc[i];
1495 psc_s2 += dim==3 ? vsom[KEL(3,fa7) * dim + i]*cc[i] : 0;
1497 double psc_m=(psc_c+psc_s+psc_s2)/dim;
1498 int num10 = face[KEL(0,fa7)];
1499 int num20 = face[KEL(1,fa7)];
1500 convbisimplicite_dec(psc_m,num10,num20,transporte,ncomp_ch_transporte,matrice,porosite_face,phi_u_transportant_yes);
1504 end_gpu_timer(__KERNEL_NAME__);
1510 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
1517 int num2 = num1 + le_bord.
nb_faces();
1518 CDoubleTabView face_normales = domaine_VEF.
face_normales().view_ro();
1519 CDoubleTabView vitesse_face = tab_vitesse_face.
view_ro();
1520 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(num1, num2), KOKKOS_LAMBDA(
const int num_face)
1523 for (
int i=0; i<dim; i++)
1524 psc += vitesse_face(num_face,i)*face_normales(num_face,i);
1525 if (!phi_u_transportant_yes)
1526 psc*=porosite_face(num_face);
1529 for (
int j=0; j<ncomp_ch_transporte; j++)
1531 int n0=num_face*ncomp_ch_transporte+j;
1532 matrice.atomic_add(n0,n0,psc);
1536 end_gpu_timer(__KERNEL_NAME__);
1545 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
1547 const DoubleTab& face_normales = domaine_VEF.
face_normales();
1565 int nb_faces_perio = 0;
1570 for (n_bord=0; n_bord<domaine_VEF.
nb_front_Cl(); n_bord++)
1576 nb_faces_perio += le_bord.
nb_faces();
1582 tab.
resize(nb_faces_perio);
1584 tab.
resize(nb_faces_perio,ncomp);
1588 for (n_bord=0; n_bord<domaine_VEF.
nb_front_Cl(); n_bord++)
1595 int num2 = num1 + le_bord.
nb_faces();
1596 for (num_face=num1; num_face<num2; num_face++)
1599 tab(nb_faces_perio) = resu(num_face);
1601 for (
int comp=0; comp<ncomp; comp++)
1602 tab(nb_faces_perio,comp) = resu(num_face,comp);
1611 for (n_bord=0; n_bord<domaine_VEF.
nb_front_Cl(); n_bord++)
1621 int num2 = num1 + le_bord.
nb_faces();
1622 for (num_face=num1; num_face<num2; num_face++)
1626 psc += la_vitesse.
valeurs()(num_face,i)*face_normales(num_face,i);
1629 resu(num_face) += 0;
1631 for (i=0; i<ncomp; i++)
1632 resu(num_face,i) += 0;
1636 resu(num_face) -= psc*la_sortie_libre.
val_ext(num_face-num1);
1638 for (i=0; i<ncomp; i++)
1639 resu(num_face,i) -= psc*la_sortie_libre.
val_ext(num_face-num1,i);
1643 else if (sub_type(
Periodique,la_cl.valeur()))
1648 int num2 = num1 + le_bord.
nb_faces();
1651 for (num_face=num1; num_face<num2; num_face++)
1653 if (fait[num_face-num1] == 0)
1659 diff1 = resu(num_face)-tab(nb_faces_perio);
1660 diff2 = resu(voisine)-tab(nb_faces_perio+voisine-num_face);
1661 resu(voisine) += diff1;
1662 resu(num_face) += diff2;
1665 for (
int comp=0; comp<ncomp; comp++)
1667 diff1 = resu(num_face,comp)-tab(nb_faces_perio,comp);
1668 diff2 = resu(voisine,comp)-tab(nb_faces_perio+voisine-num_face,comp);
1669 resu(voisine,comp) += diff1;
1670 resu(num_face,comp) += diff2;
1673 fait[num_face-num1]= 1;
1674 fait[voisine-num1] = 1;
1689 const Domaine& domaine = domaine_VEF.
domaine();
1691 int nsom = domaine.nb_som_elem();
1693 const int nb_elem_tot = domaine_VEF.
nb_elem_tot();
1710 if ((nom_elem==
"Tetra_VEF")||(nom_elem==
"Tri_VEF"))
1722 if (nom_elem==
"Tetra_VEF")
1727 CIntTabView elem_faces = domaine_VEF.
elem_faces().view_ro();
1728 CDoubleTabView3 facette_normales = domaine_VEF.
facette_normales().view_ro<3>();
1730 CIntTabView KEL = type_elemvef.
KEL().
view_ro();
1735 DoubleArrView fluent =
fluent_.view_rw();
1737 auto kernel = KOKKOS_LAMBDA(
const int poly)
1741 for (
int face_adj = 0; face_adj < nfac; face_adj++)
1742 face[face_adj] = elem_faces(poly, face_adj);
1745 for (
int j = 0; j < dim; j++)
1748 for (
int i = 0; i < nfac; i++)
1749 vs[j] += vitesse_face(face[i], j) * porosite_face(face[i]);
1754 for (
int i = 0; i < 4; i++)
1755 for (
int j = 0; j < 3; j++)
1756 vsom[i * 3 + j] = (vs[j] - 3 * vitesse_face(face[i], j) * porosite_face(face[i]));
1758 int itypcl = type_elem_Cl(poly);
1761 calcul_vc_tetra_views(face, vc, vs, vsom, vitesse_face, itypcl, porosite_face);
1764 double inv_porosite_poly = 1.0 / porosite_elem(poly);
1765 for (
int j = 0; j < dim; j++)
1767 vs[j] *= inv_porosite_poly;
1768 vc[j] *= inv_porosite_poly;
1769 for (
int i = 0; i < nsom; i++)
1770 vsom[i * dim + j] *= inv_porosite_poly;
1773 int rang = rang_elem_non_std(poly);
1775 for (
int fa7 = 0; fa7 < nfa7; fa7++)
1777 int num1 = face[KEL(0, fa7)];
1778 int num2 = face[KEL(1, fa7)];
1780 double psc_c = 0, psc_s = 0, psc_s2 = 0;
1781 for (
int i = 0; i < dim; i++)
1783 double cc = rang == -1 ? facette_normales(poly, fa7, i) : normales_facettes_Cl(rang, fa7, i);
1784 psc_c += vc[i] * cc;
1785 psc_s += vsom[KEL(2, fa7) * dim + i] * cc;
1786 psc_s2 += vsom[KEL(3, fa7) * dim + i] * cc;
1788 double psc_m = (psc_c + psc_s + psc_s2) / dim;
1790 int num = (psc_m >= 0 ? num2 : num1);
1791 Kokkos::atomic_add(&fluent[num], std::abs(psc_m));
1794 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_elem_tot, kernel);
1795 end_gpu_timer(__KERNEL_NAME__);
1800 const IntTab& KEL = type_elemvef.
KEL();
1802 const IntTab& elem_faces = domaine_VEF.
elem_faces();
1804 const IntTab& les_elems = domaine.les_elems();
1807 ArrOfInt face(nfac);
1814 for (
int poly=0; poly<nb_elem_tot; poly++)
1816 int rang = rang_elem_non_std(poly);
1826 for (
int face_adj=0; face_adj<nfac; face_adj++)
1827 face[face_adj]= elem_faces(poly,face_adj);
1831 vs[j] = vitesse_face(face[0],j)*porosite_face[face[0]];
1832 for (
int i=1; i<nfac; i++)
1833 vs[j]+= vitesse_face(face[i],j)*porosite_face[face[i]];
1839 for (
int i=0; i<nsom; i++)
1841 vsom(i,j) = (vs[j] -
dimension*vitesse_face(face[i],j)*porosite_face[face[i]]);
1847 for (
int j=0; j<nsom; j++)
1849 int num_som = les_elems(poly,j);
1859 double porosite_poly=porosite_elem(poly);
1860 for (
int i=0; i<nsom; i++)
1862 vsom(i,j)/=porosite_poly;
1865 vs[j]/= porosite_poly;
1866 vc[j]/=porosite_poly;
1870 for (
int fa7=0; fa7<nfa7; fa7++)
1872 int num1 = face[KEL(0,fa7)];
1873 int num2 = face[KEL(1,fa7)];
1878 cc[i] = facette_normales(poly, fa7, i);
1883 cc[i] = normales_facettes_Cl(rang,fa7,i);
1887 double psc_c=0,psc_s=0,psc_m,psc_s2=0;
1893 psc_s+=vsom(KEL(2,fa7),i)*cc[i];
1895 psc_m=(psc_c+psc_s)/2.;
1902 psc_s+=vsom(KEL(2,fa7),i)*cc[i];
1903 psc_s2+=vsom(KEL(3,fa7),i)*cc[i];
1905 psc_m=(psc_c+psc_s+psc_s2)/3.;
1931 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
1938 int num2b = num1b + le_bord.
nb_faces();
1939 CDoubleTabView face_normales = domaine_VEF.
face_normales().view_ro();
1941 DoubleArrView fluent =
fluent_.view_rw();
1942 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
1943 Kokkos::RangePolicy<>(num1b, num2b), KOKKOS_LAMBDA(
1947 for (
int i=0; i<nb_comp; i++)
1948 psc += vitesse_face(num_face,i)*face_normales(num_face,i);
1951 fluent(num_face) -= psc;
1953 end_gpu_timer(__KERNEL_NAME__);
DoubleTab & valeurs() override
Returns the array of field values at the current time.
static DoubleTab & calcul_gradient(const DoubleTab &, DoubleTab &, const Domaine_Cl_VEF &)
virtual double valeur_a_sommet_compo(int, int, int) const
Returns the compo-th coordinate of the values at the element le_poly at the vertex sommet.
class Cond_lim_base Base class for the hierarchy of classes that represent the different boundary con...
virtual Frontiere_dis_base & frontiere_dis()
Returns the discretized boundary to which the boundary conditions apply.
class Cond_lim Generic class used to represent any class
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 nb_faces_elem(int=0) const
Returns the number of faces of type i of the geometric elements that make up the domain.
int type_elem_Cl(int i) const
DoubleTab & vecteur_face_facette_Cl()
DoubleTab & normales_facettes_Cl()
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
IntVect & rang_elem_non_std()
const Elem_VEF_base & type_elem() const
auto & facette_normales()
int nb_faces() const
Returns the total number of faces.
int nb_faces_tot() const
Returns the total number of faces.
void creer_tableau_faces(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
virtual double face_normales(int face, int comp) const
double xv(int num_face, int k) const
ArrOfInt & faces_doubles()
Returns 1 for faces belonging to a periodic boundary or a shared item, 0 by default.
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
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:
const Domaine & domaine() const
virtual void calcul_xg(DoubleVect &, const DoubleTab &, const int, int &, int &, int &, int &) const =0
virtual void calcul_vc(const ArrOfInt &, ArrOfDouble &, const ArrOfDouble &, const DoubleTab &, const Champ_Inc_base &, int, const DoubleVect &) const =0
const IntTab & KEL() const
virtual int nb_facette() const =0
Class defining operators and methods for all reading operation in an input flow (file,...
virtual const Milieu_base & milieu() const =0
int num_premiere_face() const
int num_face(const int) const
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
DoubleVect & porosite_elem()
DoubleVect & porosite_face()
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
A character string (Nom) in uppercase.
Neumann_sortie_libre This class represents an open boundary without imposed velocity.
double val_ext(int i) const override
Returns the value of the i-th component of the field imposed on the exterior of the boundary.
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.
void ajouter_contribution_gen(const DoubleTab &transporte, const Champ_Inc_base &la_vitesse, Matrice_Morse &matrice) const
ArrOfInt est_une_face_de_dirichlet_
void contribue_au_second_membre(DoubleTab &) const
ArrOfInt traitement_pres_bord_
void get_type_op(int &) const
void get_type_lim(Motcle &) const
void remplir_fluent() const override
DoubleTab & ajouter_gen(const DoubleTab &transporte, const Champ_Inc_base &la_vitesse, DoubleTab &resu) const
type_lim_type type_lim_int
double(* LIMITEUR)(double, double)
void get_ordre(int &) const
void get_alpha(double &) const
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
virtual void ajouter_contribution(const DoubleTab &, Matrice_Morse &) const
void completer() override
Associates the operator with the domaine_dis, the domaine_Cl_dis, and the unknown of its equation.
int phi_u_transportant(const Equation_base &eq) const
Defines whether psi is convected with phi*u or with u.
const Champ_Inc_base & vitesse() const
void modifier_matrice_pour_periodique_apres_contribuer(Matrice_Morse &matrice, const Equation_base &) const
Sums the 2 rows of the associated periodic faces, allowing computations in the code without needing t...
void modifier_matrice_pour_periodique_avant_contribuer(Matrice_Morse &matrice, const Equation_base &) const
Divides the coefficients on the periodic face rows by 2 in preparation for applying modifier_matrice_...
void modifier_flux(const Operateur_base &) const
virtual void completer()
Associates the operator with the domaine_dis, the domaine_Cl_dis, and the unknown of its equation.
class Periodique This class represents a periodic boundary condition.
int face_associee(int i) const
static KOKKOS_INLINE_FUNCTION void Kokkos_exit(const char *)
Exit routine for TRUST within a Kokkos region.
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Base class for output streams.
Symetrie On symmetry faces, the following properties hold:
virtual void ref(const TRUSTTab &)
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, View< _TYPE_, _SHAPE_ > > view_wo()
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
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
virtual void finish_echange_espace_virtuel_async(const std::string kernel_name)
virtual void start_echange_espace_virtuel_async(const std::string kernel_name)
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
CIntArrView type_elem_Cl_v
CDoubleTabView4 vecteur_face_facette_Cl_v
CIntArrView traitement_pres_bord_v
bool option_calcul_flux_en_un_point
CDoubleArrView porosite_elem_v
CDoubleTabView3 normales_facettes_Cl_v
bool option_appliquer_cl_dirichlet
CIntArrView rang_elem_non_std_v
CDoubleTabView3 facette_normales_v
CDoubleArrView porosite_face_v
CDoubleTabView transporte_face_v
CIntArrView est_une_face_de_dirichlet_v
CDoubleTabView3 gradient_v
CDoubleTabView coord_sommets_v