16#include <Op_Conv_Muscl_New_VEF_Face.h>
17#include <Champ_P1NC.h>
18#include <Schema_Temps_base.h>
19#include <Porosites_champ.h>
20#include <Sous_domaine_VF.h>
21#include <Probleme_base.h>
26#include <Dirichlet_homogene.h>
27#include <Neumann_homogene.h>
28#include <Echange_impose_base.h>
29#include <Periodique.h>
30#include <Neumann_sortie_libre.h>
34static KOKKOS_INLINE_FUNCTION
double minmod(
double r)
40static KOKKOS_INLINE_FUNCTION
double optimum(
double a,
double b)
100 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
103 const int nb_faces_elem = domaine_VEF.
elem_faces().dimension(1);
108 assert(tab_Kij.
nb_dim()==3);
109 assert(tab_Kij.
dimension(0)==nb_elem_tot);
111 assert(tab_Kij.
dimension(1)==nb_faces_elem);
113 assert(tab_Cij.
nb_dim()==2);
114 assert(tab_Cij.
dimension(0)==nb_elem_tot);
117 assert(tab_Sij.
nb_dim()==2);
118 assert(tab_Sij.
dimension(0)==nb_elem_tot);
123 assert(tab_Sij2.
nb_dim()==2);
124 assert(tab_Sij2.
dimension(0)==nb_elem_tot);
131 CDoubleTabView3 facette_normales = domaine_VEF.
facette_normales().view_ro<3>();
134 CIntTabView elem_faces = domaine_VEF.
elem_faces().view_ro();
135 CDoubleTabView velocity = tab_velocity.
view_ro();
136 CDoubleTabView
vitesse = vitesse_->valeurs().view_ro();
139 CIntArrView type_elem_Cl = domaine_Cl_VEF.
type_elem_Cl().view_ro();
141 DoubleTabView Cij = tab_Cij.
view_wo();
142 DoubleTabView Sij = tab_Sij.
view_wo();
143 DoubleTabView Sij2 = tab_Sij2.
view_wo();
144 DoubleTabView3 Kij = tab_Kij.
view_rw<3>();
145 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_elem_tot, KOKKOS_LAMBDA(
151 int face[4] = {-1, -1, -1, -1};
152 int rang=rang_elem_non_std(elem);
153 int itypcl=(rang==-1)?0:type_elem_Cl(rang);
155 for (
int facei_loc=0; facei_loc<nb_faces_elem; facei_loc++)
156 face[facei_loc]=elem_faces(elem,facei_loc);
158 for (
int dim=0; dim<nb_dim; dim++)
162 for (
int facei_loc = 0; facei_loc < nb_faces_elem; facei_loc++)
163 vs[dim] += velocity(face[facei_loc], dim);
165 for (
int dim=0; dim<nb_dim; dim++)
166 for (
int facei_loc=0; facei_loc<nb_faces_elem; facei_loc++)
167 vsom[facei_loc*nb_dim+dim]=vs[dim]-nb_dim*velocity(face[facei_loc],dim);
171 calcul_vc_tetra_views(face,vc,vs,vsom,
vitesse,itypcl,porosite_face);
173 calcul_vc_tri_views(face,vc,vs,vsom,
vitesse,itypcl,porosite_face);
177 double porosite=1./porosite_elem(elem);
178 for (
int dim=0; dim<nb_dim; dim++)
180 for (
int facei_loc=0; facei_loc<nb_faces_elem; facei_loc++)
181 vsom[facei_loc*nb_dim+dim] *= porosite;
186 for (
int fa7=0; fa7<nfa7; fa7++)
188 int facei_loc=KEL(0,fa7);
189 int facej_loc=KEL(1,fa7);
194 for (
int dim=0; dim<nb_dim; dim++)
196 double facette_normale = (rang==-1 ? facette_normales(elem, fa7, dim) : facette_normales_Cl(rang,fa7,dim));
197 Cij(elem, fa7) += vc[dim] * facette_normale;
198 Sij(elem, fa7) += vsom[KEL(2, fa7) * nb_dim + dim] * facette_normale;
199 if (nb_dim == 3) Sij2(elem, fa7) += vsom[KEL(3, fa7) * nb_dim + dim] * facette_normale;
201 double psc=Cij(elem,fa7)+Sij(elem,fa7)+Sij2(elem,fa7);
204 Kij(elem,facei_loc,facej_loc)=psc;
205 Kij(elem,facei_loc,facei_loc)-=psc;
206 Kij(elem,facej_loc,facei_loc)=-psc;
207 Kij(elem,facej_loc,facej_loc)+=psc;
210 end_gpu_timer(__KERNEL_NAME__);
218 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
222 if ( (sub_type(
Dirichlet,la_cl.valeur()))
235 else if (sub_type(
Symetrie,la_cl.valeur()))
252 Cerr <<
"Error Op_Conv_Muscl_New_VEF_Face::calculer_coefficients_operateur_centre()" << finl;
253 Cerr <<
"Boundary condition " << la_cl.que_suis_je() <<
" not coded." << finl;
254 Cerr <<
"Exiting program." << finl;
268calculer_flux_operateur_centre(DoubleTab& tab_Fij,
const DoubleTab& tab_Kij,
const DoubleTab& tab_Cij,
const DoubleTab& tab_Sij,
const DoubleTab& tab_Sij2,
const int nb_comp,
const DoubleTab& tab_velocity,
const DoubleTab& tab_transporte)
const
270 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
272 const Domaine& domaine = domaine_VEF.
domaine();
274 const DoubleTab& tab_vecteur_face_facette = ref_cast_non_const(
Domaine_VEF,domaine_VEF).vecteur_face_facette();
276 const DoubleTab& tab_coord_sommets = domaine.coord_sommets();
277 const DoubleTab& tab_xv = domaine_VEF.
xv();
279 const IntTab& tab_elem_faces = domaine_VEF.
elem_faces();
285 const int nb_faces_elem=tab_elem_faces.
dimension(1);
292 assert(tab_Fij.
nb_dim()==4);
293 assert(tab_Fij.
dimension(0)==nb_elem_tot);
295 assert(tab_Fij.
dimension(1)==nb_faces_elem);
304 CIntArrView rang_elem_non_std = tab_rang_elem_non_std.view_ro();
305 CIntTabView elem_faces = tab_elem_faces.
view_ro();
306 CIntTabView KEL = tab_KEL.
view_ro();
307 CDoubleTabView3 Kij = tab_Kij.
view_ro<3>();
308 CDoubleTabView Cij = tab_Cij.
view_ro();
309 CDoubleTabView Sij = tab_Sij.
view_ro();
310 CDoubleTabView Sij2 = tab_Sij2.
view_ro();
311 CDoubleTabView transporteVect = tab_transporte.
view_ro();
312 CDoubleTabView4 vecteur_face_facette = tab_vecteur_face_facette.
view_ro<4>();
313 CDoubleTabView4 vecteur_face_facette_Cl = tab_vecteur_face_facette_Cl.
view_ro<4>();
314 CDoubleTabView coord_sommets = tab_coord_sommets.
view_ro();
315 CDoubleTabView xv = tab_xv.
view_ro();
316 DoubleTabView4 Fij = tab_Fij.
view_wo<4>();
318 CIntTabView sommet_elem = domaine.les_elems().view_ro();
320 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
321 Kokkos::RangePolicy<>(0, nb_elem_tot), KOKKOS_LAMBDA(
const int elem)
323 int rang = rang_elem_non_std(elem);
326 for (
int facei_loc = 0; facei_loc < nb_faces_elem; facei_loc++)
327 face[facei_loc] = elem_faces(elem, facei_loc);
329 for (
int fa7 = 0; fa7 < nfa7; fa7++)
331 int facei_loc = KEL(0, fa7);
332 int facej_loc = KEL(1, fa7);
334 int facei = face[facei_loc];
335 int facej = face[facej_loc];
346 const double psc_m = Kij(elem, facei_loc, facej_loc);
347 const double psc_c = Cij(elem, fa7);
350 double psc_s_array[2];
355 psc_s_array[0] = Sij(elem, fa7);
357 s_array[0] = sommet_elem(elem, KEL(2, fa7));
361 psc_s_array[0] = Sij(elem, fa7);
362 psc_s_array[1] = Sij2(elem, fa7);
363 s_array[0] = sommet_elem(elem, KEL(2, fa7));
364 s_array[1] = sommet_elem(elem, KEL(3, fa7));
369 face_amont = facei, dir = 0;
371 face_amont = facej, dir = 1;
373 for (
int comp = 0; comp < nb_comp; comp++)
376 double inco_m = transporteVect(face_amont, comp);
377 for (
int dim = 0; dim < nb_dim; dim++)
380 inco_m += gradient_elem(elem, comp, dim) * vecteur_face_facette(elem, fa7, dim, dir);
382 inco_m += gradient_elem(elem, comp, dim) * vecteur_face_facette_Cl(rang, fa7, dim, dir);
386 double inco_s_array[2];
387 int num_integration_points = (nb_dim == 2) ? 1 : 2;
388 for (
int ip = 0; ip < num_integration_points; ip++)
390 double inco_s = transporteVect(face_amont, comp);
391 for (
int dim = 0; dim < nb_dim; dim++)
393 inco_s += gradient_elem(elem, comp, dim) *
394 (coord_sommets(s_array[ip], dim) - xv(face_amont, dim));
396 inco_s_array[ip] = inco_s;
400 double inco_c = (nb_dim == 2 ? 2.0 : 3.0) * inco_m;
401 for (
int ip = 0; ip < num_integration_points; ip++)
403 inco_c -= inco_s_array[ip];
410 flux = inco_c * psc_c;
411 flux += 4 * inco_m * psc_m;
412 flux += inco_s_array[0] * psc_s_array[0];
417 double sum1 = (inco_s_array[0] + inco_s_array[1]) * (psc_s_array[0] + psc_s_array[1]);
418 double sum2 = (inco_s_array[0] + inco_c) * (psc_s_array[0] + psc_c);
419 double sum3 = (inco_s_array[1] + inco_c) * (psc_s_array[1] + psc_c);
420 flux = (sum1 + sum2 + sum3) / 12.0;
424 Fij(elem, facei_loc, facej_loc, comp) = flux - psc_m * transporteVect(facei, comp);
425 Fij(elem, facej_loc, facei_loc, comp) = psc_m * transporteVect(facej, comp) - flux;
429 end_gpu_timer(__KERNEL_NAME__);
432void Op_Conv_Muscl_New_VEF_Face::
433modifier_flux_operateur_centre(DoubleTab& Fij,
const DoubleTab& Kij,
const DoubleTab& Cij,
const DoubleTab& Sij,
const DoubleTab& Sij2,
const int nb_comp,
const DoubleTab& velocity,
const DoubleTab& transporte)
const
435 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
438 const DoubleTab& vecteur_face_facette = ref_cast_non_const(
Domaine_VEF,domaine_VEF).vecteur_face_facette();
441 const DoubleVect& transporteVect = transporte;
443 const IntTab& elem_faces = domaine_VEF.
elem_faces();
448 const int nb_faces_elem=elem_faces.
dimension(1);
454 IntTab face(nb_dim+1);
466 ToDo_Kokkos(
"critical");
467 for(
int elem=0; elem<nb_elem_tot; elem++)
469 int rang=rang_elem_non_std(elem);
471 for (
int facei_loc=0; facei_loc<nb_faces_elem; facei_loc++)
472 face(facei_loc)=elem_faces(elem,facei_loc);
475 if (is_element_for_upwinding_(elem))
476 for (
int facei_loc=0; facei_loc<nb_faces_elem; facei_loc++)
477 for (
int facej_loc=0; facej_loc<nb_faces_elem; facej_loc++)
478 for (
int comp=0; comp<nb_comp; comp++)
479 Fij(elem,facei_loc,facej_loc,comp)=0.;
481 if (is_element_for_upwinding_(elem))
484 for (
int fa7=0; fa7<nfa7; fa7++)
486 int facei_loc=KEL(0,fa7);
487 int facej_loc=KEL(1,fa7);
489 int facei=face(facei_loc);
490 int facej=face(facej_loc);
499 const double psc_m = Kij(elem,facei_loc,facej_loc);
503 face_amont=facei,dir=0;
505 face_amont=facej,dir=1;
507 for (
int comp=0; comp<nb_comp; comp++)
510 double inco_m=transporteVect[face_amont*nb_comp+comp];
511 for(
int dim=0; dim<nb_dim; dim++)
512 inco_m+=
gradient_elem_(elem,comp,dim)*vecteur_face_facette(elem,fa7,dim,dir);
515 double flux=inco_m*psc_m;
519 Fij(elem,facei_loc,facej_loc,comp)=flux-psc_m*transporteVect[facei*nb_comp+comp];
520 Fij(elem,facej_loc,facei_loc,comp)=psc_m*transporteVect[facej*nb_comp+comp]-flux;
526 for (
int fa7=0; fa7<nfa7; fa7++)
528 int facei_loc=KEL(0,fa7);
529 int facej_loc=KEL(1,fa7);
531 int facei=face(facei_loc);
532 int facej=face(facej_loc);
541 const double psc_m = Kij(elem,facei_loc,facej_loc);
545 face_amont=facei,dir=0;
547 face_amont=facej,dir=1;
549 for (
int comp=0; comp<nb_comp; comp++)
552 double inco_m=transporteVect[face_amont*nb_comp+comp];
553 for(
int dim=0; dim<nb_dim; dim++)
554 inco_m+=
gradient_elem_(elem,comp,dim)*vecteur_face_facette_Cl(rang,fa7,dim,dir);
557 double flux=inco_m*psc_m;
561 Fij(elem,facei_loc,facej_loc,comp)=flux-psc_m*transporteVect[facei*nb_comp+comp];
562 Fij(elem,facej_loc,facei_loc,comp)=psc_m*transporteVect[facej*nb_comp+comp]-flux;
571 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
572 const int nb_faces = domaine_VEF.
nb_faces();
577 CDoubleTabView face_normales=domaine_VEF.
face_normales().view_ro();
578 CDoubleTabView velocity=vitesse_->valeurs().
view_ro();
579 DoubleArrView fluent =
fluent_.view_wo();
580 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
581 Kokkos::RangePolicy<>(0, nb_faces), KOKKOS_LAMBDA(
585 for (
int i=0; i<dim; i++)
586 psc+=velocity(num_face,i)*face_normales(num_face,i);
587 fluent(num_face)=std::fabs(psc);
589 end_gpu_timer(__KERNEL_NAME__);
594 DoubleTab& resu)
const
596 DoubleTrav sauv(resu);
600 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
602 const DoubleTab& vitesse_2=la_vitesse.
valeurs();
605 const IntTab& elem_faces = domaine_VEF.
elem_faces();
608 const int nb_faces_elem=elem_faces.
dimension(1);
617 DoubleTrav transporte_;
618 DoubleTrav vitesse_face_;
622 const DoubleTab& velocity=modif_par_porosite_si_flag(vitesse_2,vitesse_face_,marq,porosite_face);
624 DoubleTrav Kij(nb_elem_tot,nb_faces_elem,nb_faces_elem);
625 DoubleTrav Fij(nb_elem_tot,nb_faces_elem,nb_faces_elem,nb_comp);
626 DoubleTrav Cij(nb_elem_tot,nfa7);
627 DoubleTrav Sij(nb_elem_tot,nfa7);
628 DoubleTrav Sij2(nb_elem_tot,nfa7);
635 const DoubleTab& transporte=modif_par_porosite_si_flag(transporte_2,transporte_,!marq,porosite_face);
643 if (old_centered_) modifier_flux_operateur_centre(Fij,Kij,Cij,Sij,Sij2,nb_comp,velocity,transporte);
646 if (stabilized_) ajouter_antidiffusion(Kij,Fij,transporte,resu);
665 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
668 const DoubleTab& vitesse_2=la_vitesse.
valeurs();
671 const IntTab& elem_faces = domaine_VEF.
elem_faces();
674 const int nb_faces_elem=elem_faces.
dimension(1);
681 if(
equation().inconnue().valeurs().nb_dim()!=1)
685 double security_coeff=0.95;
686 double dt_corrector=-1.;
691 ToDo_Kokkos(
"critical DoubleTab -> DoubleTrav");
692 DoubleTab vitesse_face_;
693 const DoubleTab& velocity=modif_par_porosite_si_flag(vitesse_2,vitesse_face_,marq,porosite_face);
695 DoubleTab Kij(nb_elem_tot,nb_faces_elem,nb_faces_elem);
696 DoubleTab Cij(nb_elem_tot,nfa7);
697 DoubleTab Sij(nb_elem_tot,nfa7);
701 Sij2.
resize(nb_elem_tot,nfa7);
707 IntTab plus_tab(nb_faces_tot);
708 ToDo_Kokkos(
"critical");
709 for (
int elem=0; elem<nb_elem_tot; elem++)
710 for (
int facei_loc=0; facei_loc<nb_faces_elem; facei_loc++)
712 int facei=elem_faces(elem,facei_loc);
713 for (
int facej_loc=facei_loc+1; facej_loc<nb_faces_elem; facej_loc++)
715 double kij=Kij(elem,facei_loc,facej_loc);
716 int facej=elem_faces(elem,facej_loc);
724 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
734 for (
int ind_face=0; ind_face<num2; ind_face++)
736 int facei=le_bord.
num_face(ind_face);
738 int faceiAss=le_bord.
num_face(ind_face_associee);
742 plus_tab[faceiAss]+=plus_tab[facei];
743 plus_tab[facei]=plus_tab[faceiAss];
754 dt_corrector=1./(1+max_limiteur_*max_int);
755 dt_corrector*=security_coeff;
756 dt_stab*=dt_corrector;
767 const Domaine_VEF& domaine_VEF=le_dom_vef.valeur();
776 CDoubleTabView face_normales = domaine_VEF.
face_normales().view_ro();
777 CDoubleArrView transporte =
static_cast<const DoubleVect&
>(tab_transporte).view_ro();
778 CDoubleTabView velocity = tab_velocity.
view_ro();
780 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
785 CIntArrView le_bord_num_face = le_bord.
num_face().view_ro();
793 CDoubleTabView val_ext = la_sortie_libre.
val_ext().view_ro();
794 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), num2, KOKKOS_LAMBDA(
const int ind_face)
796 int facei = le_bord_num_face(ind_face);
799 for (
int dim=0; dim<nb_dim; dim++)
800 psc-=velocity(facei,dim)*face_normales(facei,dim);
802 for (
int dim=0; dim<nb_comp; dim++)
804 double val = psc < 0. ? transporte[facei*nb_comp+dim] : (nb_comp==1 ? val_ext(ind_face,0) : val_ext(ind_face,dim));
808 end_gpu_timer(__KERNEL_NAME__);
810 else if ( sub_type(
Dirichlet,la_cl.valeur())
811 || sub_type(
Neumann,la_cl.valeur())
813 || sub_type(
Symetrie,la_cl.valeur())
817 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), num2, KOKKOS_LAMBDA(
const int ind_face)
819 int facei = le_bord_num_face(ind_face);
822 for (
int dim=0; dim<nb_dim; dim++)
823 psc-=velocity(facei,dim)*face_normales(facei,dim);
825 for (
int dim=0; dim<nb_comp; dim++)
826 flux_bords(facei,dim)=psc*transporte[facei*nb_comp+dim];
828 end_gpu_timer(__KERNEL_NAME__);
833 CIntArrView face_associee = la_cl_perio.
face_associee().view_ro();
834 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), num2, KOKKOS_LAMBDA(
const int ind_face)
836 int facei = le_bord_num_face(ind_face);
837 int ind_face_voisine = face_associee(ind_face);
838 int facei_voisine = le_bord_num_face(ind_face_voisine);
841 for (
int dim=0; dim<nb_dim; dim++)
842 psc-=velocity(facei,dim)*face_normales(facei,dim);
844 for (
int dim=0; dim<nb_comp; dim++)
846 double flux = psc*transporte[facei*nb_comp+dim];
847 Kokkos::atomic_add(&
flux_bords(facei,dim), 0.5 * flux);
848 Kokkos::atomic_add(&
flux_bords(facei_voisine,dim), -0.5 * flux);
851 end_gpu_timer(__KERNEL_NAME__);
855 Cerr <<
"Error Op_Conv_Muscl_New_VEF_Face::calculer_flux_bords()" << finl;
856 Cerr <<
"Boundary condition " << la_cl.que_suis_je() <<
" not coded." << finl;
857 Cerr <<
"Exiting program." << finl;
866 const Domaine_VEF& domaine_VEF=le_dom_vef.valeur();
870 const int nb_faces = domaine_VEF.
nb_faces();
878 CIntTabView elem_faces = domaine_VEF.
elem_faces().view_ro();
879 CDoubleTabView4 Fij = tab_Fij.
view_ro<4>();
880 DoubleArrView resuV =
static_cast<DoubleVect&
>(tab_resu).view_rw();
881 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
882 Kokkos::RangePolicy<>(0, nb_elem_tot), KOKKOS_LAMBDA(
885 for (
int fa7 = 0; fa7 < nfa7; fa7++)
887 int facei_loc = KEL(0, fa7);
888 int facej_loc = KEL(1, fa7);
890 int facei = elem_faces(elem, facei_loc);
891 int facej = elem_faces(elem, facej_loc);
893 for (
int dim = 0; dim < nb_comp; dim++)
895 double fij = Fij(elem, facei_loc, facej_loc, dim);
896 double fji = Fij(elem, facej_loc, facei_loc, dim);
898 int ligne = facei * nb_comp + dim;
899 int colonne = facej * nb_comp + dim;
901 Kokkos::atomic_add(&resuV[ligne], fij);
902 Kokkos::atomic_add(&resuV[colonne], fji);
906 end_gpu_timer(__KERNEL_NAME__);
911 CIntTabView face_voisins = domaine_VEF.
face_voisins().view_ro();
912 CDoubleArrView transporteV =
static_cast<const DoubleVect&
>(tab_transporte).view_ro();
913 CDoubleTabView3 Kij = tab_Kij.
view_ro<3>();
915 DoubleArrView resuV =
static_cast<DoubleVect&
>(tab_resu).view_rw();
916 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
917 Kokkos::RangePolicy<>(premiere_face_int, nb_faces), KOKKOS_LAMBDA(
921 int elem = face_voisins(facei, 0);
922 int facei_loc = num_fac_loc(facei, 0);
923 double fij = Kij(elem, facei_loc, facei_loc);
926 elem = face_voisins(facei, 1);
927 facei_loc = num_fac_loc(facei, 1);
928 fij += Kij(elem, facei_loc, facei_loc);
930 for (
int dim = 0; dim < nb_comp; dim++)
932 int ligne = facei * nb_comp + dim;
933 resuV[ligne] -= fij * transporteV[ligne];
936 end_gpu_timer(__KERNEL_NAME__);
944 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
953 CIntArrView num_face = le_bord.
num_face().view_ro();
955 CIntTabView face_voisins = domaine_VEF.
face_voisins().view_ro();
956 CDoubleArrView transporteV =
static_cast<const DoubleVect&
>(tab_transporte).view_ro();
957 CDoubleTabView3 Kij = tab_Kij.
view_ro<3>();
958 CDoubleTabView val_ext = la_sortie_libre.
val_ext().view_ro();
959 DoubleArrView resuV =
static_cast<DoubleVect&
>(tab_resu).view_rw();
960 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
961 Kokkos::RangePolicy<>(0, num2), KOKKOS_LAMBDA(
964 int facei=num_face(ind_face);
965 int facei_loc=num_fac_loc(facei,0);
966 int elem=face_voisins(facei,0);
967 double psc=Kij(elem,facei_loc,facei_loc);
974 for (
int dim=0; dim<nb_comp; dim++)
977 int ligne=facei*nb_comp+dim;
983 resuV[ligne]+=psc*(val_ext(ind_face,dim)-transporteV[ligne]);
987 end_gpu_timer(__KERNEL_NAME__);
1001 const Domaine_VEF& domaine_VEF=le_dom_vef.valeur();
1010 CIntTabView elem_faces=domaine_VEF.
elem_faces().view_ro();
1011 CDoubleTabView3 Kij = tab_Kij.
view_ro<3>();
1012 CDoubleTabView4 Fij = tab_Fij.
view_ro<4>();
1013 DoubleArrView resuV =
static_cast<DoubleVect&
>(tab_resu).view_rw();
1014 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
1015 Kokkos::RangePolicy<>(0, nb_elem_tot), KOKKOS_LAMBDA(
1018 for (
int fa7 = 0; fa7 < nfa7; fa7++)
1020 int facei_loc = KEL(0, fa7);
1021 int facej_loc = KEL(1, fa7);
1023 int facei = elem_faces(elem, facei_loc);
1024 int facej = elem_faces(elem, facej_loc);
1026 double psc = Kij(elem, facei_loc, facej_loc);
1028 for (
int dim = 0; dim < nb_comp; dim++)
1030 double fij = alpha * Fij(elem, facei_loc, facej_loc, dim);
1031 double fji = alpha * Fij(elem, facej_loc, facei_loc, dim);
1033 int ligne = facei * nb_comp + dim;
1034 int colonne = facej * nb_comp + dim;
1038 Kokkos::atomic_sub(&resuV[ligne], fij);
1039 Kokkos::atomic_add(&resuV[colonne], fij);
1043 Kokkos::atomic_add(&resuV[ligne], fji);
1044 Kokkos::atomic_sub(&resuV[colonne], fji);
1049 end_gpu_timer(__KERNEL_NAME__);
1059Op_Conv_Muscl_New_VEF_Face::ajouter_antidiffusion(
const DoubleTab& Kij,
const DoubleTab& Fij,
const DoubleTab& transporte, DoubleTab& resu)
const
1072 Cerr<<
"Error in Op_Conv_Muscl_New_VEF_Face::ajouter_antidiffusion()"<<finl;
1073 Cerr<<
"Version number "<<version_<<
" of antidiffusive operator does not exist"<<finl;
1084 const Domaine_VEF& domaine_VEF=le_dom_vef.valeur();
1094 CIntTabView elem_faces=domaine_VEF.
elem_faces().view_ro();
1095 CDoubleArrView transporteV =
static_cast<const DoubleVect&
>(tab_transporte).view_ro();
1096 CIntTabView face_voisins=domaine_VEF.
face_voisins().view_ro();
1098 CDoubleTabView3 Kij = tab_Kij.
view_ro<3>();
1099 CDoubleTabView4 Fij = tab_Fij.
view_ro<4>();
1100 CIntArrView is_dirichlet_faces = is_dirichlet_faces_.view_ro();
1101 DoubleArrView resuV =
static_cast<DoubleVect&
>(tab_resu).view_rw();
1102 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
1103 Kokkos::RangePolicy<>(0, nb_elem_tot), KOKKOS_LAMBDA(
1106 for (
int dim=0; dim<nb_comp; dim++)
1107 for (
int fa7 = 0; fa7 < nfa7; fa7++)
1109 int facei_loc = KEL(0, fa7);
1110 int facej_loc = KEL(1, fa7);
1112 int facei = elem_faces(elem, facei_loc);
1113 int facej = elem_faces(elem, facej_loc);
1115 double kij = Kij(elem, facei_loc, facej_loc);
1117 int face = kij >= 0. ? facei : facej;
1122 calculer_senseur(Kij, Fij, transporteV, dim, nb_comp, face, elem_faces, face_voisins, num_fac_loc, P_plus,
1123 P_moins, Q_plus, Q_moins);
1125 double fij = alpha * Fij(elem, facei_loc, facej_loc, dim);
1126 double fji = alpha * Fij(elem, facej_loc, facei_loc, dim);
1128 int ligne = facei * nb_comp + dim;
1129 int colonne = facej * nb_comp + dim;
1131 double fij_low = transporteV[colonne] - transporteV[ligne];
1133 double fji_low = fij_low;
1138 if (fij >= 0.) R = (std::fabs(P_plus) < DMINFLOAT) ? 0. : Q_plus / P_plus;
1139 else R = (std::fabs(P_moins) < DMINFLOAT) ? 0. : Q_moins / P_moins;
1146 if (!is_dirichlet_faces(facej))
1147 tmp = optimum(R, fji_low);
1151 Kokkos::atomic_add(&resuV[ligne], tmp);
1152 Kokkos::atomic_sub(&resuV[colonne], tmp);
1156 if (fji <= 0.) R = (std::fabs(P_moins) < DMINFLOAT) ? 0. : Q_moins / P_moins;
1157 else R = (std::fabs(P_plus) < DMINFLOAT) ? 0. : Q_plus / P_plus;
1163 if (!is_dirichlet_faces(facei))
1164 tmp = optimum(R, fij_low);
1168 Kokkos::atomic_sub(&resuV[ligne], tmp);
1169 Kokkos::atomic_add(&resuV[colonne], tmp);
1173 end_gpu_timer(__KERNEL_NAME__);
1186 const Domaine_VEF& domaine_VEF=le_dom_vef.valeur();
1196 CIntTabView elem_faces=domaine_VEF.
elem_faces().view_ro();
1197 CDoubleArrView transporteV =
static_cast<const DoubleVect&
>(tab_transporte).view_ro();
1198 CIntTabView face_voisins=domaine_VEF.
face_voisins().view_ro();
1200 CDoubleTabView3 Kij = tab_Kij.
view_ro<3>();
1201 CDoubleTabView4 Fij = tab_Fij.
view_ro<4>();
1202 CIntArrView is_dirichlet_faces = is_dirichlet_faces_.view_ro();
1203 DoubleArrView resuV =
static_cast<DoubleVect&
>(tab_resu).view_rw();
1204 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
1205 Kokkos::RangePolicy<>(0, nb_elem_tot), KOKKOS_LAMBDA(
1208 for (
int dim=0; dim<nb_comp; dim++)
1209 for (
int fa7 = 0; fa7 < nfa7; fa7++)
1211 int facei_loc = KEL(0, fa7);
1212 int facej_loc = KEL(1, fa7);
1214 int facei = elem_faces(elem, facei_loc);
1215 int facej = elem_faces(elem, facej_loc);
1217 double kij = Kij(elem, facei_loc, facej_loc);
1219 double Pi_moins = 0;
1221 double Qi_moins = 0;
1222 calculer_senseur(Kij, Fij, transporteV, dim, nb_comp, facei, elem_faces, face_voisins, num_fac_loc,
1224 Pi_moins, Qi_plus, Qi_moins);
1226 double Pj_moins = 0;
1228 double Qj_moins = 0;
1229 calculer_senseur(Kij, Fij, transporteV, dim, nb_comp, facej, elem_faces, face_voisins, num_fac_loc,
1231 Pj_moins, Qj_plus, Qj_moins);
1233 double fij = alpha * Fij(elem, facei_loc, facej_loc, dim);
1234 double fji = alpha * Fij(elem, facej_loc, facei_loc, dim);
1236 int ligne = facei * nb_comp + dim;
1237 int colonne = facej * nb_comp + dim;
1245 Ri = (std::fabs(Pi_plus) < DMINFLOAT) ? 0. : Qi_plus / Pi_plus;
1246 Rj = (std::fabs(Pj_moins) < DMINFLOAT) ? 0. : Qj_moins /
1251 Ri = (std::fabs(Pi_moins) < DMINFLOAT) ? 0. : Qi_moins / Pi_moins;
1252 Rj = (std::fabs(Pj_plus) < DMINFLOAT) ? 0. : Qj_plus /
1256 if (is_dirichlet_faces(facej))
1258 double R = (Ri <= Rj) ? Ri : Rj;
1261 double tmp = R * fij;
1262 Kokkos::atomic_add(&resuV[ligne], tmp);
1263 Kokkos::atomic_sub(&resuV[colonne], tmp);
1271 Rj = (std::fabs(Pj_moins) < DMINFLOAT) ? 0. : Qj_moins / Pj_moins;
1272 Ri = (std::fabs(Pi_plus) < DMINFLOAT) ? 0. : Qi_plus / Pi_plus;
1276 Rj = (std::fabs(Pj_plus) < DMINFLOAT) ? 0. : Qj_plus / Pj_plus;
1277 Ri = (std::fabs(Pi_moins) < DMINFLOAT) ? 0. : Qi_moins / Pi_moins;
1280 if (is_dirichlet_faces(facei))
1282 double R = (Ri <= Rj) ? Ri : Rj;
1285 double tmp = R * fji;
1286 Kokkos::atomic_sub(&resuV[ligne], tmp);
1287 Kokkos::atomic_add(&resuV[colonne], tmp);
1291 end_gpu_timer(__KERNEL_NAME__);
1303KOKKOS_INLINE_FUNCTION
void
1304Op_Conv_Muscl_New_VEF_Face::calculer_senseur(CDoubleTabView3 Kij, CDoubleTabView4 Fij, CDoubleArrView transporteV,
1305 const int dim,
const int nb_comp,
const int face_i,
1306 CIntTabView elem_faces, CIntTabView face_voisins, CIntTabView num_fac_loc,
1307 double& P_plus,
double& P_moins,
1308 double& Q_plus,
double& Q_moins)
const
1310 const int nb_faces_elem=(int)elem_faces.extent(1);
1311 for (
int elem_voisin=0; elem_voisin<2; elem_voisin++)
1313 int elem = face_voisins(face_i,elem_voisin);
1316 int face_i_loc = num_fac_loc(face_i,elem_voisin);
1317#ifndef TRUST_USE_GPU
1318 assert(face_i_loc>=0);
1319 assert(face_i_loc<nb_faces_elem);
1322 for (
int face_k_loc=0; face_k_loc<nb_faces_elem; face_k_loc++)
1324 int face_k=elem_faces(elem,face_k_loc);
1325 double kik=Kij(elem,face_i_loc,face_k_loc);
1329 double inci=transporteV[face_i*nb_comp+dim];
1330 double inck=transporteV[face_k*nb_comp+dim];
1332 double fik_low=kik*(inck-inci);
1333 double fik_high=Fij(elem,face_i_loc,face_k_loc,dim);
1338 if (fik_low>0) Q_plus+=fik_low;
1339 else Q_moins+=fik_low;
1343 if (fik_high>0) P_plus+=fik_high;
1344 else P_moins+=fik_high;
1346#ifndef TRUST_USE_GPU
1365 const int nb_comp = (tab_resu.
nb_dim()==1) ? 1 : tab_resu.
dimension(1);
1368 int old_centered = old_centered_;
1369 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
1378 if (old_centered)
Process::exit(
"Not available for periodicity.");
1383 CIntArrView le_bord_num_face = le_bord.
num_face().view_ro();
1384 CIntArrView face_associee = la_cl_perio.
face_associee().view_ro();
1385 DoubleArrView resu =
static_cast<DoubleVect&
>(tab_resu).view_rw();
1386 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), num2, KOKKOS_LAMBDA(
const int ind_face)
1388 int facei=le_bord_num_face(ind_face);
1389 int ind_face_associee=face_associee(ind_face);
1390 int faceiAss=le_bord_num_face(ind_face_associee);
1393 for (
int dim=0; dim<nb_comp; dim++)
1395 int ligne=facei*nb_comp+dim;
1396 int ligneAss=faceiAss*nb_comp+dim;
1397 Kokkos::atomic_add(&resu[ligneAss], resu[ligne]);
1398 Kokkos::atomic_store(&resu[ligne], resu[ligneAss]);
1429 end_gpu_timer(__KERNEL_NAME__);
1441void Op_Conv_Muscl_New_VEF_Face::calculer_data_pour_dirichlet()
1443 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
1446 const IntTab& face_sommets = domaine_VEF.
face_sommets();
1450 const int nb_elem_tot = domaine_VEF.
nb_elem_tot();
1452 const int nb_som_faces = domaine_VEF.
nb_som_face();
1459 is_element_for_upwinding_.
resize(nb_elem_tot);
1460 is_element_for_upwinding_=0;
1462 IntTab est_un_sommet_de_bord(domaine_VEF.
nb_som_tot());
1463 est_un_sommet_de_bord=0;
1465 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
1471 if ( (sub_type(
Dirichlet,la_cl.valeur()))
1474 for (
int ind_face=0; ind_face<nb_faces_tot; ind_face++)
1476 int face = le_bord.
num_face(ind_face);
1477 for (
int som_loc=0; som_loc<nb_som_faces; som_loc++)
1479 int som=face_sommets(face,som_loc);
1480 est_un_sommet_de_bord(som)=1;
1484 ToDo_Kokkos(
"critical");
1485 for (
int elem=0; elem<nb_elem_tot; elem++)
1487 int rang=rang_elem_non_std(elem);
1488 if (rang!=-1) is_element_for_upwinding_(elem)=1;
1490 for (
int som_loc=0; som_loc<nb_som_elem; som_loc++)
1492 int som=elem_sommets(elem,som_loc);
1493 if (est_un_sommet_de_bord(som))
1494 is_element_for_upwinding_(elem)=1;
1498 is_dirichlet_faces_.resize(domaine_VEF.
nb_faces_tot());
1499 is_dirichlet_faces_=0;
1501 for (
int n_bord=0; n_bord<nb_bord; n_bord++)
1504 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
1507 if ( (sub_type(Dirichlet,la_cl.valeur()))
1508 || (sub_type(Dirichlet_homogene,la_cl.valeur()))
1510 for (
int ind_face=0; ind_face<nb_faces_tot; ind_face++)
1512 int face = le_bord.
num_face(ind_face);
1513 is_dirichlet_faces_(face)=1;
1521 calculer_data_pour_dirichlet();
DoubleTab & valeurs() override
Returns the array of field values at the current time.
static DoubleTab & calcul_gradient(const DoubleTab &, DoubleTab &, const Domaine_Cl_VEF &)
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_som_elem() const
Returns the number of vertices 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()
int nb_cond_lim() const
Returns the number of boundary conditions.
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.
virtual double face_normales(int face, int comp) const
double xv(int num_face, int k) const
const IntTab & get_num_fac_loc() const
int face_sommets(int i, int j) const
Returns the index of the i-th vertex of face num_face.
int nb_som_face() const
Returns the number of vertices per 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.
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
Echange_impose_base: This boundary condition is used only for the energy equation.
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
virtual const Champ_Inc_base & inconnue() const =0
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.
Classe Neumann_homogene This class is the base class of the hierarchy of homogeneous Neumann-type bou...
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.
Classe Neumann This class is the base class of the hierarchy of Neumann-type boundary conditions.
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_Conv_Muscl_New_VEF_Face
public_for_cuda void calculer_flux_bords(const DoubleTab &, const DoubleTab &, const DoubleTab &) const
DoubleTab & ajouter_antidiffusion_v1(const DoubleTab &, const DoubleTab &, const DoubleTab &, DoubleTab &) const
void completer() override
Associates the operator with the domaine_dis, the domaine_Cl_dis, and the unknown of its equation.
void modifier_pour_Cl(Matrice_Morse &, DoubleTab &) const override
DOES NOTHING - to override in derived classes.
void remplir_fluent() const override
DoubleTab & ajouter_antidiffusion_v2(const DoubleTab &, const DoubleTab &, const DoubleTab &, DoubleTab &) const
void calculer_flux_operateur_centre(DoubleTab &, const DoubleTab &, const DoubleTab &, const DoubleTab &, const DoubleTab &, const int, const DoubleTab &, const DoubleTab &) const
void calculer_coefficients_operateur_centre(DoubleTab &, DoubleTab &, DoubleTab &, DoubleTab &, const int, const DoubleTab &vitesse) const
void ajouter_contribution(const DoubleTab &, Matrice_Morse &) const override
double calculer_dt_stab() const override
Computes dt_stab.
void mettre_a_jour_pour_periodicite(const DoubleTab &, const DoubleTab &, DoubleTab &) const
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
DoubleTab & ajouter_operateur_centre(const DoubleTab &, const DoubleTab &, const DoubleTab &, DoubleTab &) const
DoubleTab & ajouter_diffusion(const DoubleTab &, const DoubleTab &, const DoubleTab &, DoubleTab &) const
void modifier_pour_Cl(Matrice_Morse &, DoubleTab &) const override
Modify the right-hand side and the matrix for Dirichlet conditions.
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_flux(const Operateur_base &) const
void fixer_dt_stab_conv(double dt)
virtual double calculer_dt_stab() const
Computes dt_stab.
class Periodique This class represents a periodic boundary condition.
int face_associee(int i) const
static double mp_max(double)
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:
_SIZE_ size_array() const
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
_TYPE_ mp_max_vect(Mp_vect_options opt=VECT_REAL_ITEMS) const