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 <<
" n'est pas compris par " <<
que_suis_je() << finl;
69 Cerr <<
" choisir parmi : amont - muscl - centre " << finl;
73 if (type_op_lu==
"muscl")
82 Cerr <<
" choisir parmi : minmod - vanleer - vanalbada - chakravarthy - superbee " << finl;
115 Cerr <<
"l'ordre apres " <<
type_lim <<
" dans " <<
que_suis_je() <<
" doit etre soit 1, soit 2, soit 3" << finl;
125 if (type_op_lu==
"centre")
132 Cerr <<
"l'ordre apres " << type_op_lu <<
" dans " <<
que_suis_je() <<
" doit etre soit 1, soit 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
Renvoie le tableau des valeurs du champ au temps courant.
static DoubleTab & calcul_gradient(const DoubleTab &, DoubleTab &, const Domaine_Cl_VEF &)
virtual double valeur_a_sommet_compo(int, int, int) const
renvoi la compo eme corrdonne des valeurs a l'element le_poly au sommet sommet
classe Cond_lim_base Classe de base pour la hierarchie des classes qui representent les differentes c...
virtual Frontiere_dis_base & frontiere_dis()
Renvoie la frontiere discretisee a laquelle les conditions aux limites s'appliquent.
classe Cond_lim Classe generique servant a representer n'importe quelle classe
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.
int type_elem_Cl(int i) const
DoubleTab & vecteur_face_facette_Cl()
DoubleTab & normales_facettes_Cl()
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
IntVect & rang_elem_non_std()
const Elem_VEF_base & type_elem() const
auto & facette_normales()
int nb_faces() const
renvoie le nombre global de faces.
int nb_faces_tot() const
renvoie le nombre total de 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()
renvoie 1 pour les faces appartenant a un bord perio ou un item commun, 0 par defaut
int face_sommets(int i, int j) const
renvoie le numero du ieme sommet de la face num_face.
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
double xp(int num_elem, int k) const
int premiere_face_int() const
une face est interne ssi elle separe deux elements.
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
int nb_faces_bord() const
renvoie le nombre de faces sur lesquelles sont appliquees les conditions limites :
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
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.
Une chaine de caractere (Nom) en majuscules.
classe Neumann_sortie_libre Cette classe represente une frontiere ouverte sans vitesse imposee
double val_ext(int i) const override
Renvoie la valeur de la i-eme composante du champ impose a l'exterieur de la frontiere.
class Nom Une chaine de caractere pour nommer les objets de TRUST
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 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
Associe l'operateur au domaine_dis, le domaine_Cl_dis, et a l'inconnue de son equation.
int phi_u_transportant(const Equation_base &eq) const
definit si l'on convecte psi avec phi*u ou avec u
const Champ_Inc_base & vitesse() const
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
virtual void completer()
Associe l'operateur au domaine_dis, le domaine_Cl_dis, et a l'inconnue de son equation.
classe Periodique Cette classe represente une condition aux limites periodique.
int face_associee(int i) const
static KOKKOS_INLINE_FUNCTION void Kokkos_exit(const char *)
Routine de sortie de TRUST dans une region Kokkos.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Classe de base des flux de sortie.
classe Symetrie Sur les faces de symetrie on a les proprietes suivantes:
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