45 if (!
grad_.get_md_vector().non_nul())
54 if (z_class->get_modele_turbulence().utiliser_loi_paroi())
57 grad_.echange_espace_virtuel();
59 if (!
Re_.get_md_vector().non_nul())
66 bool flag = z_class->get_modele_turbulence().calcul_tenseur_Re(tab_nu_turb, grad_, Re_);
67 const int nbr_comp = tab_resu.
line_size();
69 CDoubleTabView nu_turb = tab_nu_turb.
view_ro();
70 DoubleTabView3 Re = Re_.view_rw<3>();
73 Cerr <<
"On utilise une diffusion turbulente non lineaire dans NS" << finl;
74 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_2D({0,0}, {domaine_VEF.
nb_elem(),nbr_comp}), KOKKOS_LAMBDA(
const int elem,
const int i)
77 for (
int j = 0; j < nbr_comp; j++)
78 Re(elem, i, j) *= nu_turb(elem, 0);
83 CDoubleTabView3 grad = grad_.view_ro<3>();
86 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_2D({0,0}, {domaine_VEF.
nb_elem(),nbr_comp}), KOKKOS_LAMBDA(
const int elem,
const int i)
89 for (
int j = 0; j < nbr_comp; j++)
90 Re(elem, i, j) = nu_turb(elem,0) * (grad(elem, i, j) + grad(elem, j, i));
93 end_gpu_timer(__KERNEL_NAME__);
94 Re_.echange_espace_virtuel();
104template <
typename DERIVED_T>
template<Type_Champ _TYPE_,
bool _IS_RANS_>
105std::enable_if_t<_TYPE_ == Type_Champ::VECTORIEL, void>
110 const auto *z_class =
static_cast<const DERIVED_T*
>(
this);
113 const Domaine_VEF& domaine_VEF = z_class->domaine_vef();
114 const int nbr_comp = tab_resu.
line_size();
118 const int nb_cl = les_cl.size();
119 CIntTabView face_voisins = domaine_VEF.
face_voisins().view_ro();;
120 CDoubleTabView face_normale = domaine_VEF.
face_normales().view_ro();;
121 CDoubleTabView nu = tab_nu.
view_ro();
122 CDoubleTabView3 Re =
Re_.view_ro<3>();
123 CDoubleTabView3 grad =
grad_.view_ro<3>();
124 DoubleTabView flux_bords = tab_flux_bords.
view_rw();
125 DoubleTabView resu = tab_resu.
view_rw();
126 for (
int n_bord = 0; n_bord < nb_cl; n_bord++)
133 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
134 Kokkos::RangePolicy<>(ndeb, nfin), KOKKOS_LAMBDA(
137 for (
int kk = 0; kk < 2; kk++)
139 const int elem = face_voisins(num_face, kk), ori = 1 - 2 * kk;
140 for (
int i = 0; i < nbr_comp; i++)
141 for (
int j = 0; j < nbr_comp; j++)
143 ori * face_normale(num_face, j) * (nu(elem, 0) * grad(elem, i, j) + Re(elem, i, j));
149 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
150 Kokkos::RangePolicy<>(ndeb, nfin), KOKKOS_LAMBDA(
153 const int elem = face_voisins(num_face, 0);
154 for (
int i = 0; i < nbr_comp; i++)
155 for (
int j = 0; j < nbr_comp; j++)
157 double flux = face_normale(num_face, j) * (nu(elem, 0) * grad(elem, i, j) + Re(elem, i, j));
158 resu(num_face, i) -= flux;
159 flux_bords(num_face, i) -= flux;
164 flux_bords(num_face, 0) = 0.;
167 end_gpu_timer(__KERNEL_NAME__);
189inline void apply_ajouter_interne_gen_kernel_notemplate(
const AjouterInterneData& data,
const int nbr_comp)
192 const int nint = data.
nint;
198 auto grad = data.
grad;
199 auto resu = data.
resu;
202 bool collapse_loops =
true;
205 Kokkos::MDRangePolicy<Kokkos::Rank<2>> policy({nint, 0}, {nb_faces, 2});
206 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), policy, KOKKOS_LAMBDA(
const int num_face,
const int kk)
208 const int elem = face_voisins(num_face, kk), ori = 1 - 2 * kk;
209 double nu_elem = nu(elem);
210 for (
int i = 0; i < nbr_comp; i++)
211 for (
int j = 0; j < nbr_comp; j++)
212 Kokkos::atomic_add(&resu(num_face, i), - ori * face_normale(num_face, j) * (nu_elem * grad(elem, i, j) + Re(elem, i, j)));
217 Kokkos::RangePolicy<> policy(nint, nb_faces);
218 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), policy, KOKKOS_LAMBDA(
221 for (
int kk = 0; kk < 2; kk++)
223 const int elem = face_voisins(num_face, kk), ori = 1 - 2 * kk;
224 double nu_elem = nu(elem);
225 for (
int i = 0; i < nbr_comp; i++)
226 for (
int j = 0; j < nbr_comp; j++)
228 ori * face_normale(num_face, j) * (nu_elem * grad(elem, i, j) + Re(elem, i, j));
232 end_gpu_timer(__KERNEL_NAME__);
235template<
int nbr_comp>
239 const int nint = data.
nint;
245 auto grad = data.
grad;
246 auto resu = data.
resu;
249 Kokkos::RangePolicy<> policy(nint, nb_faces);
251 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), policy,
252 KOKKOS_LAMBDA(
const int num_face)
254 double resu_loc[2][nbr_comp];
255 double face_normale_loc[nbr_comp];
256 int face_voisins_loc[2];
259 for (
int j = 0; j < nbr_comp; ++j)
260 face_normale_loc[j] = face_normale(num_face, j);
262 for (
int side = 0; side < 2; ++side)
264 face_voisins_loc[side] = face_voisins(num_face, side);
265 for (
int i = 0; i < nbr_comp; ++i) resu_loc[side][i] = 0.0;
269 for (
int side = 0; side < 2; ++side)
271 const int elem = face_voisins_loc[side];
272 const int ori = 1 - 2 * side;
273 const double nu_elem = nu(elem);
275 for (
int i = 0; i < nbr_comp; ++i)
278 for (
int j = 0; j < nbr_comp; ++j)
280 sum -= ori * face_normale_loc[j]
281 * (nu_elem * grad(elem, i, j) + Re(elem, i, j));
283 resu_loc[side][i] += sum;
288 for (
int i = 0; i < nbr_comp; ++i)
291 for (
int side = 0; side < 2; ++side) sum += resu_loc[side][i];
292 resu(num_face, i) += sum;
296 end_gpu_timer(__KERNEL_NAME__);
305template <
typename DERIVED_T>
template<Type_Champ _TYPE_,
bool _IS_RANS_>
306std::enable_if_t<_TYPE_ == Type_Champ::VECTORIEL, void>
309 DoubleTab& flux_bords,
310 const DoubleTab& tab_nu,
311 const DoubleTab& tab_nu_turb)
const
313 const Domaine_VEF& domaine_VEF =
static_cast<const DERIVED_T*
>(
this)->domaine_vef();
314 const int nb_faces = domaine_VEF.
nb_faces();
316 const int nbr_comp = tab_resu.
line_size();
319 CIntTabView face_voisins = domaine_VEF.
face_voisins().view_ro();
320 CDoubleTabView face_normale = domaine_VEF.
face_normales().view_ro();
321 CDoubleArrView nu =
static_cast<const ArrOfDouble&
>(tab_nu).view_ro();
322 CDoubleTabView3 grad =
grad_.view_ro<3>();
323 CDoubleTabView3 Re =
Re_.view_ro<3>();
324 DoubleTabView resu = tab_resu.
view_rw();
325 AjouterInterneData data {nint, nb_faces, face_voisins, face_normale, nu, Re, grad, resu};
328 const bool use_templated_version=
true;
331 if (use_templated_version)
336 apply_ajouter_interne_gen_kernel<1>(data);
339 apply_ajouter_interne_gen_kernel<2>(data);
342 apply_ajouter_interne_gen_kernel<3>(data);
345 apply_ajouter_interne_gen_kernel<4>(data);
348 Cerr <<
"nbr_comp too large (>4), no templated verison of Op_Dift_VEF_Face_Gen<DERIVED_T>::ajouter_interne_gen implemented" << finl;
349 Cerr<<
"Defaulting to the non templated version.";
350 apply_ajouter_interne_gen_kernel_notemplate(data, nbr_comp);
355 apply_ajouter_interne_gen_kernel_notemplate(data, nbr_comp);
360template <
typename DERIVED_T>
template<Type_Champ _TYPE_,
bool _IS_RANS_>
361std::enable_if_t<_TYPE_ == Type_Champ::SCALAIRE, void>
365 const auto *z_class =
static_cast<const DERIVED_T*
>(
this);
368 const Domaine_VEF& domaine_VEF = z_class->domaine_vef();
371 for (
int n_bord = 0; n_bord < nb_front; n_bord++)
375 ajouter_bord_perio_gen__<_TYPE_, Type_Schema::EXPLICITE, false, _IS_RANS_>(n_bord, inconnue, &resu,
nullptr, nu, nu_turb, nu_turb );
379 ajouter_bord_scalaire_impose_gen__<_TYPE_, Type_Schema::EXPLICITE, false>(n_bord, inconnue, &resu,
nullptr, nu, nu_turb, nu_turb , &tab_flux_bords);
382 ajouter_bord_gen__<_TYPE_, Type_Schema::EXPLICITE, false, _IS_RANS_>(n_bord, inconnue, &resu,
nullptr, nu, nu_turb, nu_turb , &tab_flux_bords);
388template <
typename DERIVED_T>
template <
bool _IS_STAB_>
392 const auto *z_class =
static_cast<const DERIVED_T*
>(
this);
393 constexpr bool is_STAB = _IS_STAB_;
396 const Domaine_VEF& domaine_VEF = z_class->domaine_vef();
399 for (
int n_bord = 0; n_bord < nb_front; n_bord++)
405 if (is_STAB && sub_type(
Periodique, la_cl.valeur()))
408 CIntArrView face_associee = la_cl_perio.
face_associee().view_ro();
409 CIntArrView num_face = le_bord.
num_face().view_ro();
410 DoubleTabView resu = tab_resu.
view_rw();
411 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(0, le_bord.
nb_faces()/2), KOKKOS_LAMBDA(
const int ind_face)
413 const int face = num_face(ind_face);
414 const int voisine = num_face(face_associee(ind_face));
415 for (
int nc = 0; nc < nb_comp; nc++)
417 resu(face, nc) += resu(voisine, nc);
418 resu(voisine, nc) = resu(face, nc);
421 end_gpu_timer(__KERNEL_NAME__);
427 CDoubleTabView flux_impose = la_cl_paroi.
flux_impose().view_ro();
428 CDoubleArrView face_surfaces = domaine_VEF.
face_surfaces().view_ro();
429 DoubleTabView flux_bords = tab_flux_bords.
view_wo();
430 DoubleTabView resu = tab_resu.
view_rw();
431 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(ndeb, nfin), KOKKOS_LAMBDA(
const int face)
433 for (
int nc = 0; nc < nb_comp; nc++)
435 const double flux = flux_impose(face - ndeb, nc) * face_surfaces(face);
436 if (is_STAB) resu(face, nc) -= flux;
437 else resu(face, nc) += flux;
438 flux_bords(face, nc) = flux;
441 end_gpu_timer(__KERNEL_NAME__);
449 CDoubleArrView face_surfaces = domaine_VEF.
face_surfaces().view_ro();
450 CDoubleTabView inconnue = tab_inconnue.
view_ro();
451 DoubleTabView flux_bords = tab_flux_bords.
view_wo();
452 DoubleTabView resu = tab_resu.
view_rw();
453 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(ndeb, nfin), KOKKOS_LAMBDA(
const int face)
455 for (
int nc = 0; nc < nb_comp; nc++)
457 const double flux = h_imp(face - ndeb, nc) * (T_ext(face - ndeb, nc) - inconnue(face, nc)) * face_surfaces(face);
458 if (is_STAB) resu(face, nc) -= flux;
459 else resu(face, nc) += flux;
460 flux_bords(face, nc) = flux;
463 end_gpu_timer(__KERNEL_NAME__);
468 DoubleTabView flux_bords = tab_flux_bords.
view_wo();
469 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(ndeb, nfin), KOKKOS_LAMBDA(
const int face)
471 for (
int nc = 0; nc < nb_comp; nc++)
472 flux_bords(face, nc) = 0.;
474 end_gpu_timer(__KERNEL_NAME__);
484template <
typename DERIVED_T>
template <Type_Champ _TYPE_,
bool _IS_STAB_,
bool _IS_RANS_>
486 const DoubleTab& nu_turb,
const DoubleVect& porosite_eventuelle)
const
489 const auto *z_class =
static_cast<const DERIVED_T*
>(
this);
492 const Domaine_VEF& domaine_VEF = z_class->domaine_vef();
495 for (
int n_bord = 0; n_bord < nb_bords; n_bord++)
501 ajouter_bord_perio_gen__<_TYPE_, Type_Schema::IMPLICITE, _IS_STAB_, _IS_RANS_>(n_bord, transporte,
nullptr, &tab_matrice, nu, nu_turb, porosite_eventuelle);
505 ajouter_bord_scalaire_impose_gen__<_TYPE_, Type_Schema::IMPLICITE, _IS_STAB_>(n_bord, transporte,
nullptr, &tab_matrice, nu, nu_turb, porosite_eventuelle);
510 Matrice_Morse_View matrice;
511 matrice.set(tab_matrice);
513 CDoubleArrView face_surfaces = domaine_VEF.
face_surfaces().view_ro();
514 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(ndeb, nfin), KOKKOS_LAMBDA(
const int face)
516 matrice.add(face, face, h_imp(face - ndeb, 0) * face_surfaces(face));
518 end_gpu_timer(__KERNEL_NAME__);
522 ajouter_bord_gen__<_TYPE_, Type_Schema::IMPLICITE, _IS_STAB_, _IS_RANS_>(n_bord, transporte,
nullptr, &tab_matrice, nu, nu_turb, porosite_eventuelle);
528template <
typename DERIVED_T>
template <Type_Champ _TYPE_, Type_Schema _SCHEMA_,
bool _IS_STAB_,
bool _IS_RANS_>
529void Op_Dift_VEF_Face_Gen<DERIVED_T>::ajouter_bord_perio_gen__(
const int n_bord,
const DoubleTab& tab_inconnue, DoubleTab* tab_resu ,
Matrice_Morse* matrice_morse ,
530 const DoubleTab& tab_nu,
const DoubleTab& tab_nu_turb,
const DoubleVect& tab_porosite_eventuelle, DoubleTab* tab_flux_bord)
const
532 constexpr bool is_VECT = (_TYPE_ == Type_Champ::VECTORIEL), is_EXPLICIT = (_SCHEMA_ == Type_Schema::EXPLICITE), is_STAB = _IS_STAB_, is_RANS = _IS_RANS_;
534 const auto *z_class =
static_cast<const DERIVED_T*
>(
this);
537 const Domaine_VEF& domaine_VEF = z_class->domaine_vef();
545 num2 = is_EXPLICIT ? num2 : nb_faces_bord_reel / 2;
547 CIntArrView le_bord_num_face = le_bord.
num_face().view_ro();
548 CIntArrView face_associee = la_cl_perio.
face_associee().view_ro();
549 CIntTabView elem_faces = domaine_VEF.
elem_faces().view_ro();
550 CIntTabView face_voisins = domaine_VEF.
face_voisins().view_ro();
551 CDoubleArrView volumes = domaine_VEF.
volumes().view_ro();
552 CDoubleArrView inverse_volumes = domaine_VEF.
inverse_volumes().view_ro();
553 CDoubleTabView face_normale = domaine_VEF.
face_normales().view_ro();
554 CDoubleArrView porosite_eventuelle = tab_porosite_eventuelle.view_ro();
555 CDoubleTabView nu = tab_nu.
view_ro();
556 CDoubleTabView nu_turb = tab_nu_turb.
view_ro();
557 CDoubleTabView inconnue = tab_inconnue.
view_ro();
559 Matrice_Morse_View matrice;
562 assert(tab_resu !=
nullptr);
563 assert(!is_VECT && !_IS_STAB_);
568 assert(matrice_morse !=
nullptr);
569 matrice.set(*matrice_morse);
571 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
572 Kokkos::RangePolicy<>(num1, num2), KOKKOS_LAMBDA(
575 int fac_asso = face_associee(ind_face);
576 fac_asso = le_bord_num_face(fac_asso);
577 int num_face0 = le_bord_num_face(ind_face);
579 for (
int l = 0; l < 2; l++)
581 int elem = face_voisins(num_face0, l);
582 for (
int i0 = 0; i0 < nb_faces_elem; i0++)
584 int j = elem_faces(elem, i0);
588 if ((j > num_face0) && (j != fac_asso))
589 for (
int nc = 0; nc < nb_comp; nc++)
591 const double d_nu = nu(elem, (is_RANS ? 0 : nc)) + nu_turb(elem, (is_RANS ? nc : 0));
592 const double valA = z_class->viscA(num_face0, j, elem, d_nu, face_voisins, face_normale, inverse_volumes);
593 const double flux = valA * inconnue(j, nc) - valA * inconnue(num_face0, nc);
594 Kokkos::atomic_add(&resu(num_face0, nc), +flux);
596 Kokkos::atomic_add(&resu(j, nc), -0.5 * flux);
603 int orientation = 1, fac_loc = 0, ok = 1, contrib = 1;
605 if ((elem == face_voisins(j, l)) ||
606 (face_voisins(num_face0, (l + 1) % 2) == face_voisins(j, (l + 1) % 2)))
609 while ((fac_loc < nb_faces_elem) && (elem_faces(elem, fac_loc) != num_face0))
612 if (fac_loc == nb_faces_elem)
617 int el1 = face_voisins(j, 0), el2 = face_voisins(j, 1);
618 if ((el1 == -1) || (el2 == -1))
623 for (
int nc = 0; nc < nb_comp; nc++)
625 double d_nu = nu(elem, (is_VECT || is_RANS ) ? 0 : nc) + nu_turb(elem, (is_RANS ? nc : 0));
626 double valA = z_class->viscA(num_face0, j, elem, d_nu, face_voisins, face_normale, inverse_volumes);
627 if (is_STAB && valA < 0.)
630 int n0 = num_face0 * nb_comp + nc;
631 int n0perio = fac_asso * nb_comp + nc;
632 int j0 = j * nb_comp + nc;
633 matrice.atomic_add(n0, n0, + valA * porosite_eventuelle(num_face0));
634 matrice.atomic_add(n0, j0, - valA * porosite_eventuelle(j));
639 matrice.atomic_add(j0, n0, - valA * porosite_eventuelle(num_face0));
641 matrice.atomic_add(j0, n0perio, - valA * porosite_eventuelle(num_face0));
642 matrice.atomic_add(j0, j0, + valA * porosite_eventuelle(j));
647 for (
int nc2 = 0; nc2 < nb_comp; nc2++)
649 int n1 = num_face0 * nb_comp + nc2;
650 int j1 = j * nb_comp + nc2;
651 double coeff_s = orientation * nu_turb(elem,0) / volumes(elem) *
652 face_normale(num_face0, nc2) * face_normale(j, nc);
653 matrice.atomic_add(n0, n1, + coeff_s * porosite_eventuelle(num_face0));
654 matrice.atomic_add(n0, j1, - coeff_s * porosite_eventuelle(j));
658 double coeff_s2 = orientation * nu_turb(elem,0) / volumes(elem) *
659 face_normale(num_face0, nc) * face_normale(j, nc2);
662 matrice.atomic_add(j0, n1, - coeff_s2 * porosite_eventuelle(num_face0));
664 matrice.atomic_add(j0, fac_asso * nb_comp + nc2, - coeff_s2 * porosite_eventuelle(num_face0));
666 matrice.atomic_add(j0, j1, + coeff_s2 * porosite_eventuelle(j));
675 end_gpu_timer(__KERNEL_NAME__);
678template <
typename DERIVED_T>
template <Type_Champ _TYPE_, Type_Schema _SCHEMA_,
bool _IS_STAB_>
679void Op_Dift_VEF_Face_Gen<DERIVED_T>::ajouter_bord_scalaire_impose_gen__(
const int n_bord,
const DoubleTab& tab_inconnue, DoubleTab* tab_resu ,
Matrice_Morse* matrice_morse ,
680 const DoubleTab& tab_nu,
const DoubleTab& tab_nu_turb,
const DoubleVect& tab_porosite_eventuelle, DoubleTab* tab_flux_bords)
const
682 constexpr bool is_EXPLICIT = (_SCHEMA_ == Type_Schema::EXPLICITE);
684 const auto *z_class =
static_cast<const DERIVED_T*
>(
this);
706 const Domaine_VEF& domaine_VEF = z_class->domaine_vef();
715 CIntArrView le_bord_num_face = le_bord.
num_face().view_ro();
716 CIntTabView face_voisins = domaine_VEF.
face_voisins().view_ro();
717 CIntTabView elem_faces = domaine_VEF.
elem_faces().view_ro();
718 CDoubleTabView face_normale = domaine_VEF.
face_normales().view_ro();
719 CDoubleArrView volumes = domaine_VEF.
volumes().view_ro();
720 CDoubleArrView face_surfaces = domaine_VEF.
face_surfaces().view_ro();
721 CDoubleArrView porosite_eventuelle = tab_porosite_eventuelle.view_ro();
722 CDoubleTabView nu = tab_nu.
view_ro();
723 CDoubleTabView nu_turb = tab_nu_turb.
view_ro();
724 CDoubleTabView inconnue = tab_inconnue.
view_ro();
725 DoubleTabView flux_bords;
727 Matrice_Morse_View matrice;
730 assert(tab_resu !=
nullptr);
731 flux_bords = tab_flux_bords->
view_rw();
736 assert(matrice_morse !=
nullptr);
737 matrice.set(*matrice_morse);
739 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
740 Kokkos::RangePolicy<>(num1, num2), KOKKOS_LAMBDA(
743 double le_mauvais_gradient[3] = { 0., 0., 0. };
744 for (
int nc = 0; nc < nb_comp; nc++)
746 int num_face = le_bord_num_face(ind_face);
749 double bon_gradient = 0.;
751 for (
int kk = 0; kk < dim; kk++)
752 le_mauvais_gradient[kk] = 0.;
754 int elem1 = face_voisins(num_face, 0);
755 if (elem1 == -1) elem1 = face_voisins(num_face, 1);
762 bon_gradient = 1. / d_equiv(ind_face) * (-oriente_normale(num_face, elem1, face_voisins));
764 double surface_face = face_surfaces(num_face);
765 double nutotal = nu(elem1, nc) + nu_turb(elem1,0);
769 for (
int i = 0; i < nb_faces_elem; i++)
771 const int j = elem_faces(elem1, i);
774 double surface_pond = 0.;
775 double signe_j = oriente_normale(j, elem1, face_voisins);
776 double signe_num_face = oriente_normale(num_face, elem1, face_voisins);
777 for (
int kk = 0; kk < dim; kk++)
778 surface_pond -= (face_normale(j, kk) * signe_j *
779 face_normale(num_face, kk) * signe_num_face) /
780 (surface_face * surface_face);
782 Tf += inconnue(j, nc) * surface_pond;
785 double signe_j = oriente_normale(j, elem1, face_voisins);
786 for (
int kk = 0; kk < dim; kk++)
787 le_mauvais_gradient[kk] += inconnue(j, nc) * face_normale(j, kk) * signe_j;
789 for (
int kk = 0; kk < dim; kk++)
790 le_mauvais_gradient[kk] /= volumes(elem1);
792 double mauvais_gradient = 0;
793 for (
int kk = 0; kk < dim; kk++)
794 mauvais_gradient += le_mauvais_gradient[kk] * face_normale(num_face, kk) / surface_face;
799 double signe_num_face = oriente_normale(num_face, elem1, face_voisins);
800 bon_gradient = (Tf - inconnue(num_face, nc)) / d_equiv(ind_face) * (-signe_num_face);
802 for (
int i = 0; i < nb_faces_elem; i++)
804 const int j = elem_faces(elem1, i);
805 double correction = 0.;
806 double signe_j = oriente_normale(j, elem1, face_voisins);
807 for (
int kk = 0; kk < dim; kk++)
810 nutotal * (bon_gradient - mauvais_gradient) * face_normale(num_face, kk) *
811 face_normale(j, kk) * (-signe_j) / surface_face;
815 Kokkos::atomic_add(&resu(j, nc), +correction);
816 if (j == num_face && j < size_flux_bords)
817 Kokkos::atomic_add(&flux_bords(j, nc), -correction);
822 for (
int i0 = 0; i0 < nb_faces_elem; i0++)
824 int j = elem_faces(elem1, i0);
825 for (
int ii = 0; ii < nb_faces_elem; ii++)
827 for (
int kk = 0; kk < dim; kk++)
828 le_mauvais_gradient[kk] = 0;
829 int jj = elem_faces(elem1, ii);
830 double surface_pond = 0;
831 double signe_jj = oriente_normale(jj, elem1, face_voisins);
832 double signe_num_face = oriente_normale(num_face, elem1, face_voisins);
833 for (
int kk = 0; kk < dim; kk++)
834 surface_pond -= (face_normale(jj, kk) * signe_jj *
835 face_normale(num_face, kk) * signe_num_face) /
836 (surface_face * surface_face);
839 for (
int kk = 0; kk < dim; kk++)
840 le_mauvais_gradient[kk] += face_normale(jj, kk) * signe_jj;
842 for (
int kk = 0; kk < dim; kk++)
843 le_mauvais_gradient[kk] /= volumes(elem1);
845 double mauvais_gradient = 0;
846 for (
int kk = 0; kk < dim; kk++)
848 le_mauvais_gradient[kk] * face_normale(num_face, kk) / surface_face;
850 double resu1 = 0, resu2 = 0;
851 double signe_j = oriente_normale(j, elem1, face_voisins);
852 for (
int kk = 0; kk < dim; kk++)
854 double coeff = -nutotal * face_normale(num_face, kk) * face_normale(j, kk) * signe_j / surface_face;
855 resu1 += mauvais_gradient * coeff;
856 resu2 += bon_gradient * coeff;
864 int j0 = j * nb_comp + nc, jj0 = jj * nb_comp + nc;
865 matrice.atomic_add(j0, jj0, (resu1 - resu2) * porosite_eventuelle(jj0));
871 end_gpu_timer(__KERNEL_NAME__);
877template <
typename DERIVED_T>
template <Type_Champ _TYPE_, Type_Schema _SCHEMA_,
bool _IS_STAB_,
bool _IS_RANS_>
878void Op_Dift_VEF_Face_Gen<DERIVED_T>::ajouter_bord_gen__(
const int n_bord,
const DoubleTab& tab_inconnue, DoubleTab* tab_resu ,
Matrice_Morse* matrice_morse ,
879 const DoubleTab& tab_nu,
const DoubleTab& tab_nu_turb,
const DoubleVect& tab_porosite_eventuelle, DoubleTab* tab_flux_bords)
const
881 constexpr bool is_VECT = (_TYPE_ == Type_Champ::VECTORIEL), is_EXPLICIT = (_SCHEMA_ == Type_Schema::EXPLICITE), is_STAB = _IS_STAB_, is_RANS = _IS_RANS_;
883 const auto *z_class =
static_cast<const DERIVED_T*
>(
this);
886 const Domaine_VEF& domaine_VEF = z_class->domaine_vef();
892 CIntArrView le_bord_num_face = le_bord.
num_face().view_ro();
893 CIntTabView face_voisins = domaine_VEF.
face_voisins().view_ro();
894 CIntTabView elem_faces = domaine_VEF.
elem_faces().view_ro();
895 CDoubleTabView face_normale = domaine_VEF.
face_normales().view_ro();
896 CDoubleArrView volumes = domaine_VEF.
volumes().view_ro();
897 CDoubleArrView inverse_volumes = domaine_VEF.
inverse_volumes().view_ro();
898 CDoubleArrView porosite_eventuelle = tab_porosite_eventuelle.view_ro();
899 CDoubleTabView nu = tab_nu.
view_ro();
900 CDoubleTabView nu_turb = tab_nu_turb.
view_ro();
901 CDoubleTabView inconnue = tab_inconnue.
view_ro();
902 DoubleTabView flux_bords;
904 Matrice_Morse_View matrice;
907 assert(tab_resu !=
nullptr);
908 assert(!is_VECT && !_IS_STAB_);
909 flux_bords = tab_flux_bords->
view_rw();
914 assert(matrice_morse !=
nullptr);
915 matrice.set(*matrice_morse);
917 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
918 Kokkos::RangePolicy<>(num1, num2), KOKKOS_LAMBDA(
921 const int num_face = le_bord_num_face(ind_face), elem = face_voisins(num_face, 0);
922 for (
int i = 0; i < nb_faces_elem; i++)
924 int j = elem_faces(elem, i);
925 if ((j > num_face) || (ind_face >= nb_faces_bord_reel))
928 if ((elem == face_voisins(j, 0)) || (face_voisins(num_face, (0 + 1) % 2) == face_voisins(j, (0 + 1) % 2)))
931 for (
int nc = 0; nc < nb_comp; nc++)
933 const double d_nu = nu(elem, (is_VECT || is_RANS) ? 0 : nc) + nu_turb(elem, (is_RANS ? nc : 0));
934 double valA = z_class->viscA(num_face, j, elem, d_nu, face_voisins, face_normale, inverse_volumes);
936 if (is_STAB && valA < 0.) valA = 0.;
940 if (ind_face < nb_faces_bord_reel)
942 double flux = valA * (inconnue(j, nc) - inconnue(num_face, nc));
943 Kokkos::atomic_add(&resu(num_face, nc), +flux);
944 Kokkos::atomic_add(&flux_bords(num_face, nc), -flux);
948 double flux = valA * (inconnue(num_face, nc) - inconnue(j, nc));
949 Kokkos::atomic_add(&resu(j, nc), +flux);
950 if (j < premiere_face_int)
951 Kokkos::atomic_add(&flux_bords(j, nc), -flux);
956 const int n0 = num_face * nb_comp + nc, j0 = j * nb_comp + nc;
957 if (ind_face < nb_faces_bord_reel)
959 matrice.atomic_add(n0, n0, + valA * porosite_eventuelle(num_face));
960 matrice.atomic_add(n0, j0, - valA * porosite_eventuelle(j));
965 matrice.atomic_add(j0, n0, - valA * porosite_eventuelle(num_face));
966 matrice.atomic_add(j0, j0, + valA * porosite_eventuelle(j));
971 for (
int nc2 = 0; nc2 < nb_comp; nc2++)
973 const int n1 = num_face * nb_comp + nc2, j1 = j * nb_comp + nc2;
974 if (ind_face < nb_faces_bord_reel)
976 double coeff_s = orientation * nu_turb(elem,0) / volumes(elem) * face_normale(num_face, nc2) * face_normale(j, nc);
977 matrice.atomic_add(n0, n1, + coeff_s * porosite_eventuelle(num_face));
978 matrice.atomic_add(n0, j1, - coeff_s * porosite_eventuelle(j));
983 double coeff_s = orientation * nu_turb(elem,0) / volumes(elem) * face_normale(num_face, nc) * face_normale(j, nc2);
984 matrice.atomic_add(j0, n1, - coeff_s * porosite_eventuelle(num_face));
985 matrice.atomic_add(j0, j1, + coeff_s * porosite_eventuelle(j));
993 end_gpu_timer(__KERNEL_NAME__);
996template <
typename DERIVED_T>
template <Type_Champ _TYPE_, Type_Schema _SCHEMA_,
bool _IS_STAB_,
bool _IS_RANS_>
997void Op_Dift_VEF_Face_Gen<DERIVED_T>::ajouter_interne_gen__(
const DoubleTab& tab_inconnue, DoubleTab* tab_resu ,
Matrice_Morse* matrice_morse ,
998 const DoubleTab& tab_nu,
const DoubleTab& tab_nu_turb,
const DoubleVect& tab_porosite_eventuelle)
const
1000 constexpr bool is_VECT = (_TYPE_ == Type_Champ::VECTORIEL), is_EXPLICIT = (_SCHEMA_ == Type_Schema::EXPLICITE), is_STAB = _IS_STAB_, is_RANS = _IS_RANS_;
1002 const auto *z_class =
static_cast<const DERIVED_T*
>(
this);
1004 const Domaine_VEF& domaine_VEF = z_class->domaine_vef();
1007 CIntTabView face_voisins = domaine_VEF.
face_voisins().view_ro();
1008 CIntTabView elem_faces = domaine_VEF.
elem_faces().view_ro();
1009 CDoubleTabView face_normale = domaine_VEF.
face_normales().view_ro();
1010 CDoubleArrView inverse_volumes = domaine_VEF.
inverse_volumes().view_ro();
1011 CDoubleArrView porosite_eventuelle = tab_porosite_eventuelle.view_ro();
1012 CDoubleTabView nu = tab_nu.
view_ro();
1013 CDoubleTabView nu_turb = tab_nu_turb.
view_ro();
1014 CDoubleTabView inconnue = tab_inconnue.
view_ro();
1016 Matrice_Morse_View matrice;
1019 assert(tab_resu !=
nullptr);
1024 assert(matrice_morse !=
nullptr);
1025 matrice.set(*matrice_morse);
1027 Kokkos::MDRangePolicy<Kokkos::Rank<2>> policy({premiere_face_int, 0}, {nb_faces, 2});
1028 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), policy, KOKKOS_LAMBDA(
const int num_face,
const int kk)
1030 int elem = face_voisins(num_face, kk);
1031 for (
int i0 = 0; i0 < nb_faces_elem; i0++)
1033 int j = elem_faces(elem, i0);
1039 const int el1 = face_voisins(j, 0), el2 = face_voisins(j, 1);
1040 if ((el1 == -1) || (el2 == -1))
1048 if (!is_EXPLICIT && is_VECT)
1050 int orientation = 1;
1051 if ((elem == face_voisins(j, kk)) ||
1052 (face_voisins(num_face, 1 - kk) == face_voisins(j, 1 - kk)))
1054 tmp = orientation * nu_turb(elem,0) * inverse_volumes(elem);
1056 for (
int nc = 0; nc < nb_comp; nc++)
1058 double d_nu = nu(elem, (is_VECT || is_RANS) ? 0 : nc) + nu_turb(elem, (is_RANS ? nc : 0));
1059 double valA = z_class->viscA(num_face, j, elem, d_nu, face_voisins, face_normale, inverse_volumes);
1061 if (is_STAB && valA < 0.) valA = 0.;
1065 const double flux = valA * inconnue(j, nc) - valA * inconnue(num_face, nc);
1066 Kokkos::atomic_add(&resu(num_face, nc), flux);
1068 Kokkos::atomic_sub(&resu(j, nc), flux);
1072 double contrib_num_face = valA * porosite_eventuelle(num_face);
1073 double contrib_j = valA * porosite_eventuelle(j);
1074 const int n0 = num_face * nb_comp + nc, j0 = j * nb_comp + nc;
1075 matrice.atomic_add(n0, n0, contrib_num_face);
1076 matrice.atomic_add(n0, j0, -contrib_j);
1079 matrice.atomic_add(j0, n0, -contrib_num_face);
1080 matrice.atomic_add(j0, j0, contrib_j);
1086 double poro_num_face = porosite_eventuelle(num_face);
1087 double poro_j = porosite_eventuelle(j);
1088 double face_normale_num_face = face_normale(num_face, nc);
1089 double face_normale_j = face_normale(j, nc);
1090 for (
int nc2 = 0; nc2 < nb_comp; nc2++)
1092 const int n1 = num_face * nb_comp + nc2;
1093 const int j1 = j * nb_comp + nc2;
1094 double coeff_s = is_STAB ? 0. : tmp * face_normale(num_face, nc2) * face_normale_j;
1096 matrice.atomic_add(n0, n1, coeff_s * poro_num_face);
1097 matrice.atomic_add(n0, j1, -coeff_s * poro_j);
1100 double coeff_s2 = is_STAB ? 0. : tmp * face_normale_num_face * face_normale(j, nc2);
1101 matrice.atomic_add(j0, n1, -coeff_s2 * poro_num_face);
1102 matrice.atomic_add(j0, j1, coeff_s2 * poro_j);
1112 end_gpu_timer(__KERNEL_NAME__);