16#include <Transport_K_Eps_base.h>
17#include <Schema_Temps_base.h>
18#include <Domaine_VF.h>
19#include <Domaine_VEF.h>
20#include <Champ_Inc_P0_base.h>
21#include <communications.h>
22#include <Probleme_base.h>
23#include <Discret_Thyd.h>
51 param.
ajouter_flag(
"exit_on_negative_k_eps", &exit_on_negative_k_eps_);
52 param.
ajouter_flag(
"exit_on_big_eps", &exit_on_big_eps_);
61 Cerr <<
"K,Eps transport equation ("<<
que_suis_je() <<
") discretization" << finl;
62 Cerr <<
"K_Eps field discretization" << finl;
71 le_champ_K_Eps->nommer(
"K_Eps");
82 Cerr<<
" Transport_K_Eps_base::discretiser "<<finl;
96 DoubleTab& tab_K_Eps = le_champ_K_Eps->valeurs();
106 size = le_champ_K_Eps->equation().domaine_dis().domaine().nb_elem();
110 Cerr <<
"Unsupported K_Eps field in Transport_K_Eps_base::controler_K_Eps()" << finl;
116 int count_negative_k = 0;
117 int count_negative_eps = 0;
118 int count_big_eps = 0;
123 Debog::verifier(
"Transport_K_Eps_base::controler_K_Eps K_Eps before", tab_K_Eps);
129 int nb_faces_elem = domaine_vf.
elem_faces().line_size();
139 if (getenv(
"TRUST_CONTROL_KEPS_GPU")==
nullptr)
142 const IntTab& elem_faces = domaine_vf.
elem_faces();
143 ToDo_Kokkos(
"critical");
144 for (
int n = 0; n < size; n++)
146 double& k = tab_K_Eps(n, 0);
147 double& eps = tab_K_Eps(n, 1);
157 if ((k < 0 || eps < 0) )
159 count_negative_k += ( k<0 ? 1 : 0);
160 count_negative_eps += (eps<0 ? 1 : 0);
171 for (
int i = 0; i < 2; i++)
173 int elem = face_voisins(n, i);
175 for (
int j = 0; j < nb_faces_elem; j++)
178 double k_face = tab_K_Eps(elem_faces(elem, j), 0);
184 double e_face = tab_K_Eps(elem_faces(elem, j), 1);
185 if (e_face > EPS_MIN)
194 if (nk != 0) {k /= nk;}
196 if (neps != 0) { eps /= neps; }
197 else { eps = EPS_MIN; }
204 CIntTabView face_voisins = domaine_vf.
face_voisins().view_ro();
205 CIntTabView elem_faces = domaine_vf.
elem_faces().view_ro();
206 DoubleTabView K_Eps = tab_K_Eps.
view_rw();
219 KOKKOS_INLINE_FUNCTION
220 CountValues() : count_k(0), count_eps(0), count_big(0) {}
222 KOKKOS_INLINE_FUNCTION
223 CountValues(
const CountValues& rhs) : count_k(rhs.count_k), count_eps(rhs.count_eps),
224 count_big(rhs.count_big) {}
226 KOKKOS_INLINE_FUNCTION CountValues&
operator=(
const CountValues&) =
default;
228 KOKKOS_INLINE_FUNCTION
229 void operator+=(
const CountValues& rhs)
231 count_k += rhs.count_k;
232 count_eps += rhs.count_eps;
233 count_big += rhs.count_big;
238 Kokkos::parallel_reduce(start_gpu_timer(__KERNEL_NAME__), size,
239 KOKKOS_LAMBDA(
const int n, CountValues &local_count)
241 double& k = K_Eps(n, 0);
242 double& eps = K_Eps(n, 1);
247 local_count.count_big++;
252 if (k < 0) local_count.count_k++;
253 if (eps < 0) local_count.count_eps++;
256 end_gpu_timer(__KERNEL_NAME__);
258 count_negative_k = result.count_k;
259 count_negative_eps = result.count_eps;
260 count_big_eps = result.count_big;
264 DoubleTrav K_Eps_original(tab_K_Eps);
265 CDoubleTabView K_Eps_orig = K_Eps_original.
view_ro();
266 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), size, KOKKOS_LAMBDA(
const int n)
268 double& k = K_Eps(n, 0);
269 double& eps = K_Eps(n, 1);
273 if ((k < 0 || eps < 0))
284 for (
int i = 0; i < 2; i++)
286 int elem = face_voisins(n, i);
289 for (
int j = 0; j < nb_faces_elem; j++)
294 double k_face = K_Eps_orig(elem_faces(elem, j), 0);
300 double e_face = K_Eps_orig(elem_faces(elem, j), 1);
301 if (e_face > EPS_MIN)
313 k = (nk != 0) ? (k_new / nk) : K_MIN;
314 eps = (neps != 0) ? (eps_new / neps) : EPS_MIN;
317 end_gpu_timer(__KERNEL_NAME__);
320 Debog::verifier(
"Transport_K_Eps_base::controler_K_Eps K_Eps after", tab_K_Eps);
324 if (count_negative_k > 0 || count_negative_eps > 0)
326 const double time = le_champ_K_Eps->temps();
328 Journal() <<
"WARNING: Some values values forced for k and eps:" << finl;
329 if (count_negative_k > 0)
330 Journal() <<
"Negative values of k found on :" << count_negative_k <<
"/" << size <<
" nodes at time " << time << finl;
331 if (count_negative_eps > 0)
332 Journal() <<
"Negative values of eps found on :" << count_negative_eps <<
"/" << size <<
" nodes at time " << time << finl;
335 double ratio_k = 100. * count_negative_k / size;
336 double ratio_eps = 100. * count_negative_eps / size;
337 if ((ratio_k > 0.01 || ratio_eps > 0.01))
339 Cerr <<
"WARNING: Found high ratio of invalid values for k and/or epsilon (more that 0.01%) on process" <<
Process::me() << finl;
340 Cerr <<
"Check journal log file for more information. These messages can be disabled with the flag 'quiet' in modele_turbulence." << finl;
342 Journal() <<
"WARNING: Found high ratio of invalid values for k and/or epsilon (more that 0.01%)." << finl;
343 Journal() <<
"It is possible your initial and/or boundary conditions on k and/or eps are wrong." << finl;
344 Journal() <<
"Check the initial and boundary values for k and eps by using:" << finl;
345 Journal() <<
"k~" << (
dimension == 2 ?
"" :
"3/2*") <<
"(t*U)^2 (t turbulence rate, U mean velocity) ";
346 Journal() <<
"and eps~Cmu^0.75 k^1.5/l with l turbulent length scale and Cmu a k-eps model parameter whose value is typically given as 0.09." << finl;
347 Journal() <<
"Remark : by giving the velocity field (u) and the hydraulic diameter (d), by using boundary_field_uniform_keps_from_ud and field_uniform_keps_from_ud, " << finl;
348 Journal() <<
"respectively for boudnaries and initial conditions, TrioCFD will determine automatically values for k and eps." << finl;
351 Journal() <<
"Please, don't forget (sorry for this TrioCFD syntax weakness) that when using Quasi-Compressible module" << finl;
352 Journal() <<
"the unknowns for which you define initial and boundary conditions are rho*k and rho*eps." << finl;
356 if (exit_on_negative_k_eps_)
364 if (count_big_eps> 0)
366 const double time = le_champ_K_Eps->temps();
367 Journal() <<
"WARNING: Some values values forced for k and eps:" << finl;
368 Journal() <<
"Excessive values of eps found on " << count_big_eps <<
"/" << size <<
" nodes at time " << time << finl;
370 if (exit_on_big_eps_)
: class Champ_Inc_P0_base
static void verifier(const char *const msg, double)
classe Discret_Thyd Cette classe est la classe de base representant une discretisation
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
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 face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Class defining operators and methods for all reading operation in an input flow (file,...
void set_calculate_time_derivative(int i)
const Discretisation_base & discretisation() const
Renvoie la discretisation associee a l'equation.
int calculate_time_derivative() const
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
int limpr() const
Demande au schema en temps si il faut effectuer une impression.
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
virtual void discretiser()
Discretise l'equation.
Champs_compris champs_compris_
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise associe a l'equation.
double get_EPS_MAX() const
double get_EPS_MIN() const
Un tableau de chaine de caracteres (VECT(Nom)).
const Objet_U & operator=(const Objet_U &)
Operateur= : ne fait rien (on conserve le numero et l'identifiant).
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.
Helper class to factorize the readOn method of Objet_U classes.
void ajouter_flag(const char *keyword, const bool *value)
Register a boolean flag whose mere presence switches it to true.
int postraiter(int force=1) override
Si force=1, effectue le postraitement sans tenir compte des frequences de postraitement.
static Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
static int me()
renvoie mon rang dans le groupe de communication courant.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Classe de base des flux de sortie.
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")
Classe Transport_2eq_base Classe de base pour les equations.
void set_param(Param &) const override
const Modele_turbulence_hyd_2_eq_base & modele_turbulence() const
Renvoie le modele de turbulence associe a l'equation.
bool disable_VEF_mean_value_corrections_
Classe Transport_K_Eps_base Classe de base pour les equations.
void discretiser() override
Discretise l'equation.
virtual void set_param(Param &) const override
int controler_K_Eps()
Controle le champ inconnue K-epsilon en forcant a zero les valeurs du champ.
void valider_iteration() override
Method to correct the field K_Eps after an iteration.