16#include <Discretisation_tools.h>
17#include <Operateur_Grad.h>
18#include <TRUSTTabs_forward.h>
19#include <Source_Transport_K_Omega_VEF_Face.h>
20#include <Modele_turbulence_hyd_K_Omega.h>
21#include <Transport_K_Omega.h>
22#include <Navier_Stokes_std.h>
23#include <Pb_Hydraulique_Turbulent.h>
24#include <Milieu_base.h>
25#include <VEF_discretisation.h>
26#include <Domaine_VEF.h>
27#include <Domaine_Cl_VEF.h>
28#include <K_Omega_Eps_constants.h>
29#include <Fluide_base.h>
30#include <Dirichlet_paroi_defilante.h>
31#include <Dirichlet_paroi_fixe.h>
32#include <Schema_Euler_Implicite.h>
36 "Source_Transport_K_Omega_VEF_P1NC",
58 noms_compris.add(
"grad_k_grad_omega");
60 if (opt == DESCRIPTION)
61 Cerr <<
que_suis_je() <<
" : " << noms_compris << finl;
63 nom.add(noms_compris);
71 1,
equation().schema_temps().temps_courant(), grad_k_omega_);
83 1,
equation().schema_temps().temps_courant(), production_k_face_);
91 if (nom ==
"production_omega" && !production_omega_face_)
94 1,
equation().schema_temps().temps_courant(), production_omega_face_);
97 else if (nom ==
"dissipation_k" && !dissipation_k_face_)
100 1,
equation().schema_temps().temps_courant(), dissipation_k_face_);
104 else if (nom ==
"dissipation_omega" && !dissipation_omega_face_)
107 1,
equation().schema_temps().temps_courant(), dissipation_omega_face_);
110 else if (nom ==
"cross_diffusion_k_omega" && !cross_diffusion_k_omega_face_)
113 1,
equation().schema_temps().temps_courant(), cross_diffusion_k_omega_face_);
129 return eqn_K_Omega->modele_turbulence().viscosite_turbulente().valeurs();
134 return turbulence_model->loi_paroi().Cisaillement_paroi();
139 return eqn_K_Omega->inconnue().valeurs();
144 return turbulence_model->loi_paroi().
que_suis_je();
156 DoubleTab& tab_F1 = ref_cast_non_const(DoubleTab, turbulence_model->get_tabF1());
157 DoubleTab& tab_F2 = ref_cast_non_const(DoubleTab, turbulence_model->get_tabF2());
158 DoubleTrav tab_visc_face(le_dom_VEF->nb_faces_tot());
159 const double& cst_min_cd_komega = turbulence_model->get_expert_mode().get_cst_cd_komega();
165 CDoubleArrView visc_face;
166 if (is_dilatable) visc_face =
static_cast<ArrOfDouble&
>(tab_visc_face).view_ro();
167 CDoubleTabView K_Omega = eqn_K_Omega->inconnue().valeurs().view_ro();
168 CDoubleArrView distmin =
static_cast<const ArrOfDouble&
>(le_dom_VEF->y_faces()).view_ro();
169 CDoubleArrView gradKgradOmega =
static_cast<const ArrOfDouble&
>(tab_gradKgradOmega).view_ro();
170 DoubleArrView F1 =
static_cast<ArrOfDouble&
>(tab_F1).view_wo();
171 DoubleArrView F2 =
static_cast<ArrOfDouble&
>(tab_F2).view_wo();
172 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), le_dom_VEF->nb_faces(), KOKKOS_LAMBDA(
const int face)
174 double const dmin = Kokkos::fmax(distmin(face), 1e-12);
175 double const enerK = K_Omega(face, 0);
176 double const omega = K_Omega(face, 1);
177 double const kinematic_viscosity = is_dilatable ? visc_face(face) : visc_cst;
178 double const tmp1 = Kokkos::sqrt(enerK)/(BETA_K*omega*dmin);
179 double const tmp2 = 500.0*kinematic_viscosity/(omega*dmin*dmin);
180 double const maxval = Kokkos::fmax(2.*SIGMA_OMEGA2*gradKgradOmega(face)/(omega), cst_min_cd_komega);
181 double const tmp3 = 4.0*SIGMA_OMEGA2*enerK/(maxval*dmin*dmin);
183 double const arg1 = Kokkos::fmin(Kokkos::fmax(tmp1, tmp2), tmp3);
184 F1(face) = Kokkos::tanh(arg1*arg1*arg1*arg1);
186 double const arg2 = Kokkos::fmax(2.*tmp1, tmp2);
187 F2(face) = Kokkos::tanh(arg2*arg2);
189 end_gpu_timer(__KERNEL_NAME__);
192 for (
int i = 0; i < le_dom_Cl_VEF->nb_cond_lim(); i++)
194 const Cond_lim_base& boundary_condition = le_dom_Cl_VEF->les_conditions_limites(i).valeur();
201 int end = start + the_edge.
nb_faces();
202 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
203 Kokkos::RangePolicy<>(start, end),KOKKOS_LAMBDA(
const int num_face)
208 end_gpu_timer(__KERNEL_NAME__);
217 int const face)
const
219 const DoubleTab& F1 = turbulence_model->get_tabF1();
220 return F1(face)*val1 + (1 - F1(face))*val2;
229 const DoubleTab& tab_K_Omega = eqn_K_Omega->inconnue().valeurs();
231 DoubleTrav tab_enerK(size);
232 DoubleTrav tab_omega(size);
233 CDoubleTabView K_Omega = tab_K_Omega.
view_ro();
234 DoubleArrView enerK =
static_cast<ArrOfDouble&
>(tab_enerK).view_wo();
235 DoubleArrView omega =
static_cast<ArrOfDouble&
>(tab_omega).view_wo();
236 DoubleArrView gradKgradOmega =
static_cast<ArrOfDouble&
>(tab_gradKgradOmega).view_rw();
237 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), le_dom_VEF->nb_faces_tot(), KOKKOS_LAMBDA(
const int num_face)
239 enerK(num_face) = K_Omega(num_face, 0);
240 omega(num_face) = K_Omega(num_face, 1);
241 gradKgradOmega(num_face) = 0;
243 end_gpu_timer(__KERNEL_NAME__);
250 const int nbr_velocity_components = velocity_field_face.
dimension(1);
252 DoubleTab& tab_gradK_elem = ref_cast_non_const(DoubleTab, grad_k_elem_->valeurs());
253 DoubleTab& tab_gradOmega_elem = ref_cast_non_const(DoubleTab, grad_omega_elem_->valeurs());
256 const Operateur_Grad& Op_Grad_komega = eqn_K_Omega->gradient_operator_komega();
257 Op_Grad_komega.
calculer(tab_enerK, tab_gradK_elem);
258 Op_Grad_komega.
calculer(tab_omega, tab_gradOmega_elem);
260 const bool has_post_cross_diffusion_k_omega =
has_champ(
"cross_diffusion_k_omega") ;
262 CDoubleTabView gradK_elem = tab_gradK_elem.
view_ro();
263 CDoubleTabView gradOmega_elem = tab_gradOmega_elem.
view_ro();
265 if (has_post_cross_diffusion_k_omega)
267 DoubleArrView chmp_post =
static_cast<ArrOfDouble&
>(ref_cast_non_const(DoubleTab, grad_k_omega_->valeurs())).view_rw();
268 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), le_dom_VEF->nb_elem_tot(), KOKKOS_LAMBDA(
const int num_elem)
270 for (
int ncompo = 0; ncompo < nbr_velocity_components; ++ncompo)
271 chmp_post(num_elem) += gradK_elem(num_elem, ncompo) * gradOmega_elem(num_elem, ncompo);
273 end_gpu_timer(__KERNEL_NAME__);
276 const Domaine_dis_base& domaine_dis = mon_equation->inconnue().domaine_dis_base();
279 DoubleTrav tab_gradK_face(velocity_field_face.
dimension_tot(0), nbr_velocity_components);
282 DoubleTrav tab_gradOmega_face(velocity_field_face.
dimension_tot(0), nbr_velocity_components);
286 CDoubleTabView gradK_face = tab_gradK_face.
view_ro();
287 CDoubleTabView gradOmega_face = tab_gradOmega_face.
view_ro();
288 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), le_dom_VEF->nb_faces_tot(), KOKKOS_LAMBDA(
const int num_face)
290 for (
int ncompo = 0; ncompo < nbr_velocity_components; ++ncompo)
291 gradKgradOmega(num_face) +=
292 gradK_face(num_face, ncompo) * gradOmega_face(num_face, ncompo);
294 end_gpu_timer(__KERNEL_NAME__);
298 const DoubleTrav& tab_ProdK,
299 const DoubleTab& tab_gradKgradOmega,
300 DoubleTab& tab_resu)
const
302 const double LeK_MIN = eqn_K_Omega->modele_turbulence().get_K_MIN();
303 const double& gamma1 = turbulence_model->get_expert_mode().get_gamma1();
304 const double& gamma2 = turbulence_model->get_expert_mode().get_gamma2();
305 const bool is_SST_or_BSL = turbulence_model->is_SST_or_BSL();
306 const bool is_SST = turbulence_model->is_SST();
307 const bool has_post_production_omega =
has_champ(
"production_omega") ;
308 const bool has_post_dissipation_k =
has_champ(
"dissipation_k") ;
309 const bool has_post_dissipation_omega =
has_champ(
"dissipation_omega") ;
310 const bool has_post_cross_diffusion_k_omega =
has_champ(
"cross_diffusion_k_omega") ;
312 CDoubleTabView K_Omega = eqn_K_Omega->inconnue().valeurs().view_ro();
313 CDoubleArrView volumes_entrelaces = tab_volumes_entrelaces.view_ro();
314 CDoubleArrView ProdK =
static_cast<const ArrOfDouble&
>(tab_ProdK).view_ro();
315 CDoubleArrView gradKgradOmega =
static_cast<const ArrOfDouble&
>(tab_gradKgradOmega).view_ro();
316 CDoubleArrView F1 =
static_cast<const ArrOfDouble&
>(turbulence_model->get_tabF1()).view_ro();
317 CDoubleArrView F2 =
static_cast<const ArrOfDouble&
>(turbulence_model->get_tabF2()).view_ro();
318 DoubleArrView production_omega_face, dissipation_k_face, dissipation_omega_face, cross_diffusion_k_omega_face;
320 if (has_post_production_omega)
321 production_omega_face =
static_cast<ArrOfDouble&
>(ref_cast_non_const(DoubleTab,production_omega_face_->valeurs())).view_wo();
323 if (has_post_dissipation_k)
324 dissipation_k_face =
static_cast<ArrOfDouble&
>(ref_cast_non_const(DoubleTab,dissipation_k_face_->valeurs())).view_wo();
326 if (has_post_dissipation_omega)
327 dissipation_omega_face =
static_cast<ArrOfDouble&
>(ref_cast_non_const(DoubleTab,dissipation_omega_face_->valeurs())).view_wo();
329 if (has_post_cross_diffusion_k_omega)
330 cross_diffusion_k_omega_face =
static_cast<ArrOfDouble&
>(ref_cast_non_const(DoubleTab,cross_diffusion_k_omega_face_->valeurs())).view_wo();
332 DoubleTabView resu = tab_resu.
view_rw();
333 CDoubleArrView enstrophy_or_strain_invariant =
static_cast<const ArrOfDouble&
>(turbulence_model->get_expert_mode().get_menter_version()==Menter_version::ORIGINAL_1994 ?
334 turbulence_model->get_enstrophy() : turbulence_model->get_strain_invariant()).view_ro();
335 const double CST_A1 = turbulence_model->get_CST_A1();
336 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), le_dom_VEF->nb_faces(), KOKKOS_LAMBDA(
const int face)
338 const double tke = K_Omega(face, 0);
339 const double omega = K_Omega(face, 1);
340 const double production_k = ProdK(face);
341 const double dissipation_k = BETA_K*tke*omega;
342 resu(face, 0) += (production_k - dissipation_k)*volumes_entrelaces(face);
346 const double cALPHA = is_SST_or_BSL
347 ? F1(face)*gamma1 + (1 - F1(face))*gamma2
349 const double cBETA = is_SST_or_BSL
350 ? F1(face)*BETA1 + (1 - F1(face))*BETA2
354 cSIGMA = 2.*(1. - F1(face))*SIGMA_OMEGA2;
356 cSIGMA = (gradKgradOmega(face) > 0) ? 0.125 : 0.;
359 const double nut = is_SST ? tke * CST_A1 /Kokkos::max(CST_A1*omega, enstrophy_or_strain_invariant[face]*F2[face]) : tke/omega;
360 const double production_omega = cALPHA * ProdK(face) / nut;
361 const double dissipation_omega = cBETA * omega * omega;
362 const double cross_diffusion_k_omega = cSIGMA / omega * gradKgradOmega(face);
364 contrib += production_omega;
365 contrib -= dissipation_omega;
366 contrib += cross_diffusion_k_omega;
367 contrib *= volumes_entrelaces(face);
368 resu(face, 1) += contrib;
370 if (has_post_dissipation_k)
371 dissipation_k_face(face) = dissipation_k;
373 if (has_post_production_omega)
374 production_omega_face(face) = production_omega;
376 if (has_post_dissipation_omega)
377 dissipation_omega_face(face) = dissipation_omega;
379 if (has_post_cross_diffusion_k_omega)
380 cross_diffusion_k_omega_face(face) = cross_diffusion_k_omega;
383 end_gpu_timer(__KERNEL_NAME__);
394 const double LeK_MIN = eqn_K_Omega->modele_turbulence().get_K_MIN();
397 DoubleTrav production_k_face {le_dom_VEF->nb_faces()};
400 eq_hydraulique->domaine_Cl_dis());
402 const DoubleTab& velocity = eq_hydraulique->inconnue().valeurs();
404 const bool& deactivate_production_limiter = turbulence_model->get_expert_mode().get_deactivate_production_limiter();
407 TKE, velocity, visco_turb,
410 deactivate_production_limiter);
412 DoubleTrav tab_gradKgradOmega(le_dom_VEF->nb_faces_tot());
414 if (turbulence_model->is_SST_or_BSL())
416 const double& gamma1 = turbulence_model->get_expert_mode().get_gamma1();
417 const double& gamma2 = turbulence_model->get_expert_mode().get_gamma2();
418 const bool is_SST_or_BSL = turbulence_model->is_SST_or_BSL();
420 CDoubleTabView K_Omega = tab_K_Omega.
view_ro();
421 CDoubleArrView porosite_face = eqn_K_Omega->milieu().porosite_face().view_ro();
422 CDoubleArrView volumes_entrelaces = le_dom_VEF->volumes_entrelaces().view_ro();
423 CDoubleArrView production_k =
static_cast<const ArrOfDouble&
>(production_k_face).view_ro();
424 CDoubleArrView gradKgradOmega =
static_cast<const ArrOfDouble&
>(tab_gradKgradOmega).view_ro();
425 CDoubleArrView F1 = is_SST_or_BSL
426 ?
static_cast<const ArrOfDouble&
>(turbulence_model->get_tabF1()).view_ro()
428 Matrice_Morse_View matrice;
429 matrice.set(tab_matrice);
430 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), tab_K_Omega.
dimension(0), KOKKOS_LAMBDA(
const int face)
432 if (K_Omega(face, 0) >= LeK_MIN)
434 const double tke = K_Omega(face, 0);
435 const double omega = K_Omega(face, 1);
437 const double volporo = porosite_face(face) * volumes_entrelaces(face);
439 const double coef_k = BETA_K*omega*volporo;
440 matrice.add(face*2, face*2, coef_k);
442 const double cALPHA = is_SST_or_BSL
443 ? F1(face)*gamma1 + (1 - F1(face))*gamma2
446 const double cBETA = is_SST_or_BSL
447 ? F1(face)*BETA1 + (1 - F1(face))*BETA2
450 const double cSIGMA = is_SST_or_BSL
451 ? 2.*(1. - F1(face))*SIGMA_OMEGA2
452 : (gradKgradOmega(face) > 0)*0.125;
454 const double coef_omega = (-cALPHA*production_k(face)/tke
456 + cSIGMA/(omega*omega + 1.e-20)*gradKgradOmega(face) ) * volporo;
457 matrice.add(face*2 + 1, face*2 + 1, coef_omega);
460 end_gpu_timer(__KERNEL_NAME__);
DoubleTab & calculer_terme_production_K(const Domaine_VEF &, const Domaine_Cl_VEF &, DoubleTab &, const DoubleTab &, const DoubleTab &, const DoubleTab &, const int &interpol_visco, const double &limiteur, const bool &deactivate_production_limiter=false, const double &cst_production_limiter=0.) const
Compute the production term for the turbulent kinetic energy.
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual void creer_champ(const Motcle &motlu)=0
virtual void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const =0
classe Cond_lim_base Classe de base pour la hierarchie des classes qui representent les differentes c...
virtual Frontiere_dis_base & frontiere_dis()
Renvoie la frontiere discretisee a laquelle les conditions aux limites s'appliquent.
classe Dirichlet_paroi_defilante Impose la vitesse de paroi dnas une equation de type Navier_Stokes.
classe Dirichlet_paroi_fixe Represente une paroi immobile dans une equation de type Navier_Stokes.
classe Discretisation_base Cette classe represente un schema de discretisation en espace,...
void discretiser_champ(const Motcle &directive, const Domaine_dis_base &z, const Nom &nom, const Nom &unite, int nb_comp, int nb_pas_dt, double temps, OWN_PTR(Champ_Inc_base)&champ, const Nom &sous_type=NOM_VIDE) const
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
Class defining operators and methods for all reading operation in an input flow (file,...
const Discretisation_base & discretisation() const
Renvoie la discretisation associee a l'equation.
virtual const Champ_Inc_base & inconnue() const =0
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
const Champ_Don_base & viscosite_cinematique() const
int num_premiere_face() const
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
virtual bool is_dilatable() const
Classe Modele_turbulence_hyd_K_Omega Cette classe represente le modele de turbulence (k,...
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Une chaine de caractere (Nom) en majuscules.
classe Navier_Stokes_std Cette classe porte les termes de l'equation de la dynamique
const Fluide_base & fluide() const
Renvoie le fluide incompressible (milieu physique de l'equation) associe a l'equation.
virtual const Champ_Inc_base & vitesse() const
class Nom Une chaine de caractere pour nommer les objets de TRUST
Un tableau de chaine de caracteres (VECT(Nom)).
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.
Classe Operateur_Grad Classe generique de la hierarchie des operateurs calculant le gradient.
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
Initialise le tableau passe en parametre avec la contribution de l'operateur.
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
virtual const Equation_base & equation(int) const =0
class Schema_Implicite_base Classe de base pour tous les schemas en temps implicite
Classe de base des flux de sortie.
DoubleTab & ajouter_komega(DoubleTab &) const
class Source_Transport_K_Eps_VEF_Face Cette classe represente le terme source qui figure dans l'equat...
void discretiser() override
void creer_champ(const Motcle &) override
void associer_pb(const Probleme_base &pb) override
void compute_cross_diffusion(DoubleTab &gradKgradOmega) const override
DoubleTab & ajouter(DoubleTab &) const override
void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const override
contribution a la matrice implicite des termes sources par defaut pas de contribution
void compute_blending_F1(DoubleTab &gradKgradOmega) const override
double blender(double const val1, double const val2, int const face) const
void fill_resu_k_omega(const DoubleVect &, const DoubleTrav &, const DoubleTab &, DoubleTab &) const override
void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const override
virtual const Nom get_type_paroi() const
virtual const DoubleTab & get_visc_turb() const
virtual const DoubleTab & get_cisaillement_paroi() const
virtual const DoubleTab & get_K_pour_production() const
virtual void associer_pb(const Probleme_base &)=0
Champs_compris champs_compris_
bool has_champ(const Motcle &nom, OBS_PTR(Champ_base) &ref_champ) const override
_SIZE_ dimension_tot(int) const override
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, ConstView< _TYPE_, _SHAPE_ > > view_ro() const
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, View< _TYPE_, _SHAPE_ > > view_rw()
_SIZE_ dimension(int d) const
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
void raise_control_k_omega_flag() const
int controler_K_Omega()
Controle le champ inconnue K-Omega en forcant a zero les valeurs du champ.
classe Transport_K_Omega Cette classe represente l'equation de transport de l'energie cinetique
double _coefficient_limiteur
int _interpolation_viscosite_turbulente
void verifier_pb_komega(const Probleme_base &, const Nom &)