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 <<
"Erreur Op_Conv_Muscl_New_VEF_Face::calculer_coefficients_operateur_centre()" << finl;
253 Cerr <<
"Condition aux limites " << la_cl.que_suis_je() <<
" non codee." << finl;
254 Cerr <<
"Sortie du programme." << 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 <<
"Erreur Op_Conv_Muscl_New_VEF_Face::calculer_flux_bords()" << finl;
856 Cerr <<
"Condition aux limites " << la_cl.que_suis_je() <<
" non codee." << finl;
857 Cerr <<
"Sortie du programme." << 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
Renvoie le tableau des valeurs du champ au temps courant.
static DoubleTab & calcul_gradient(const DoubleTab &, DoubleTab &, const Domaine_Cl_VEF &)
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_som_elem() const
Renvoie le nombre de sommets des elements geometriques constituants le domaine.
int type_elem_Cl(int i) const
DoubleTab & vecteur_face_facette_Cl()
DoubleTab & normales_facettes_Cl()
int nb_cond_lim() const
Renvoie le nombre de conditions aux limites.
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.
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
renvoie le numero du ieme sommet de la face num_face.
int nb_som_face() const
renvoie le nombre de sommets par 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
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
classe Echange_impose_base: Cette condition limite sert uniquement pour l'equation d'energie.
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
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.
Classe Neumann_homogene Cette classe est la classe de base de la hierarchie des conditions aux limite...
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.
Classe Neumann Cette classe est la classe de base de la hierarchie des conditions aux limites de type...
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.
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
Associe l'operateur au domaine_dis, le domaine_Cl_dis, et a l'inconnue de son 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
Calcul 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
On modifie le second membre et la matrice dans le cas des conditions de dirichlet.
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_flux(const Operateur_base &) const
void fixer_dt_stab_conv(double dt)
virtual double calculer_dt_stab() const
Calcul dt_stab.
classe Periodique Cette classe represente une condition aux limites periodique.
int face_associee(int i) const
static double mp_max(double)
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:
_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