TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Dift_VEF_base.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Modele_turbulence_scal_base.h>
17#include <Modele_turbulence_hyd_base.h>
18#include <Navier_Stokes_std.h>
19#include <Op_Dift_VEF_base.h>
20#include <Domaine_Cl_VEF.h>
21
22
23Implemente_base(Op_Dift_VEF_base, "Op_Dift_VEF_base", Op_Diff_VEF_base);
24
26
28
30{
31 le_modele_turbulence = mod;
32}
33
35{
36 if (sub_type(Navier_Stokes_std, equation())) // on traite l'hydraulique
37 {
38 if (le_modele_turbulence->utiliser_loi_paroi())
39 {
40 // Modif BM: on ne prend la ref que si le tableau a ete initialise, sinon ca bloque l'initialisation
41 const DoubleTab& tab = le_modele_turbulence->loi_paroi().Cisaillement_paroi();
42 if (tab.size_array() > 0) tau_tan_.ref(tab);
43 }
44 }
45}
46
47void Op_Dift_VEF_base::associer(const Domaine_dis_base& domaine_dis, const Domaine_Cl_dis_base& domaine_cl_dis, const Champ_Inc_base& ch_transporte)
48{
49 le_dom_vef = ref_cast(Domaine_VEF, domaine_dis);
50 la_zcl_vef = ref_cast(Domaine_Cl_VEF, domaine_cl_dis);
51 inconnue_ = ch_transporte;
52}
53
55{
57
58 const RefObjU& modele_turbulence = equation().get_modele(TURBULENCE);
59 if (modele_turbulence && sub_type(Modele_turbulence_hyd_base, modele_turbulence.valeur()))
60 {
61 const Modele_turbulence_hyd_base& mod_turb = ref_cast(Modele_turbulence_hyd_base, modele_turbulence.valeur());
62 const Champ_Fonc_base& viscosite_turbulente = mod_turb.viscosite_turbulente();
63 associer_diffusivite_turbulente(viscosite_turbulente);
65 }
66 else if (sub_type(Modele_turbulence_scal_base, modele_turbulence.valeur()))
67 {
68 const Modele_turbulence_scal_base& modele_turbulence_scalaire = ref_cast(Modele_turbulence_scal_base, modele_turbulence.valeur());
69 const Champ_Fonc_base& conductivite_turbulente = modele_turbulence_scalaire.conductivite_turbulente();
70 associer_diffusivite_turbulente(conductivite_turbulente);
71 }
72 else
73 {
74 Cerr << "Error in Op_Dift_VEF_base::completer() " << finl;
75 Cerr << que_suis_je() << " operator is presently associated to " << equation().que_suis_je() << finl;
76 Cerr << "instead of being associated to an equation dedicated to a turbulent flow." << finl;
78 }
79}
80
81void Op_Dift_VEF_base::calculer_borne_locale(DoubleVect& tab_borne_visco_turb, double dt_conv, double dt_diff_sur_dt_conv) const
82{
83 const Domaine_VEF& le_dom_VEF = domaine_vef();
84 int nb_elem = le_dom_VEF.nb_elem();
85 int flag = diffusivite().valeurs().dimension(0) > 1 ? 1 : 0;
86 const double dim = Objet_U::dimension;
87 CDoubleTabView diffu = diffusivite().valeurs().view_ro();
88 CDoubleArrView carre_pas_maille = le_dom_VEF.carre_pas_maille().view_ro();
89 DoubleArrView borne_visco_turb = tab_borne_visco_turb.view_rw();
90 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_elem, KOKKOS_LAMBDA(const int elem)
91 {
92 double h_inv = 1. / carre_pas_maille(elem);
93 // C'est pas tres propre pour recuperer diffu mais ca evite de coder cette methode dans plusieurs classes:
94 double diffu_elem = (flag ? diffu(elem, 0) : diffu(0, 0));
95 double coef = 1. / (2 * (dt_conv + DMINFLOAT) * dim * h_inv * dt_diff_sur_dt_conv) - diffu_elem;
96 if (coef > 0 && coef < borne_visco_turb(elem))
97 borne_visco_turb(elem) = coef;
98 });
99 end_gpu_timer(__KERNEL_NAME__);
100}
101
102// La diffusivite est constante par elements donc il faut calculer dt_diff pour chaque element et dt_stab=Min(dt_diff (K) = h(K)*h(K)/(2*dimension*diffu2_(K)))
103// ou diffu2_ est la somme des 2 diffusivite laminaire et turbulente
104
105//GF : alpha_dt_stab=(alpha+alpha_t)*alpha_dt_stab/alpha ET alpha_dt_stab=(nu+diff_nu_turb)*valeurs_diffusivite_dt/nu
107{
108 remplir_nu(nu_); // On remplit le tableau nu contenant la diffusivite en chaque elem
109
110 //DoubleVect tab_diffu_turb(diffusivite_turbulente().valeurs());
111 DoubleTrav tab_diffu_turb;
112 tab_diffu_turb = diffusivite_turbulente().valeurs();
113 DoubleTrav tab_diffu;
114 tab_diffu = nu_; // XXX : Elie Saikali : Attention pas pareil que DoubleTrav diffu(nu_) !!!!!!!!!
115
116 if (equation().que_suis_je().debute_par("Convection_Diffusion_Temp"))
117 {
118 double rhocp = mon_equation->domaine_dis().nb_elem() > 0 ? mon_equation->milieu().capacite_calorifique().valeurs()(0, 0) * mon_equation->milieu().masse_volumique().valeurs()(0, 0) : 1.0;
119 tab_diffu_turb /= rhocp;
120 tab_diffu /= rhocp;
121 }
122
123 const double deux_dim = 2. * Objet_U::dimension;
124 const Domaine_VEF& le_dom_VEF = domaine_vef();
125 const int le_dom_nb_elem = le_dom_VEF.domaine().nb_elem();
126 double dt_stab = 1.e30;
127 CDoubleTabView diffu = tab_diffu.view_ro();
128 CDoubleArrView diffu_turb = static_cast<const DoubleVect&>(tab_diffu_turb).view_ro();
129 CDoubleArrView carre_pas_maille = le_dom_VEF.carre_pas_maille().view_ro();
131 {
132 const DoubleTab& tab_rho_elem = get_champ_masse_volumique().valeurs();
133 assert(tab_rho_elem.size_array() == le_dom_VEF.nb_elem_tot());
134 CDoubleArrView rho_elem = static_cast<const DoubleVect&>(tab_rho_elem).view_ro();
135 Kokkos::parallel_reduce(start_gpu_timer(__KERNEL_NAME__),
136 Kokkos::RangePolicy<>(0, le_dom_nb_elem), KOKKOS_LAMBDA(
137 const int num_elem, double& dtstab)
138 {
139 double alpha = diffu(num_elem, 0) + diffu_turb(num_elem); // PQ : 06/03
140 alpha /= rho_elem(num_elem);
141 double coef = carre_pas_maille(num_elem) / (deux_dim * (alpha + DMINFLOAT));
142 if (coef < dtstab) dtstab = coef;
143 }, Kokkos::Min<double>(dt_stab));
144 }
145 else
146 {
147 const DoubleTab& tab_valeurs_diffusivite = diffusivite_pour_pas_de_temps().valeurs();
148 const int nb_comp = tab_valeurs_diffusivite.line_size(), cD = (tab_valeurs_diffusivite.dimension(0) == 1); // uniforme ou pas ?
149 CDoubleTabView valeurs_diffusivite = tab_valeurs_diffusivite.view_ro();
150 Kokkos::parallel_reduce(start_gpu_timer(__KERNEL_NAME__),
151 Kokkos::RangePolicy<>(0, le_dom_nb_elem), KOKKOS_LAMBDA(
152 const int num_elem, double& dtstab)
153 {
154 for (int nc = 0; nc < nb_comp; nc++)
155 {
156 double alpha = diffu(num_elem, nc) + diffu_turb(num_elem);
157 const double valeurs_diffusivite_dt = valeurs_diffusivite(!cD * num_elem, nc);
158 alpha *= valeurs_diffusivite_dt / (diffu(num_elem, nc) + DMINFLOAT);
159 double coef = carre_pas_maille(num_elem) / (deux_dim * (alpha + DMINFLOAT));
160 if (coef < dtstab) dtstab = coef;
161 }
162 }, Kokkos::Min<double>(dt_stab));
163 }
164 end_gpu_timer(__KERNEL_NAME__);
165 dt_stab = Process::mp_min(dt_stab);
166 return dt_stab;
167}
168
169// cf Op_Dift_VEF_Face::calculer_dt_stab() pour choix de calcul de dt_stab
170void Op_Dift_VEF_base::calculer_pour_post(Champ_base& espace_stockage, const Nom& option, int comp) const
171{
172 if (Motcle(option) == "stabilite")
173 {
174 DoubleTab& es_valeurs = espace_stockage.valeurs();
175
176 if (le_dom_vef)
177 {
178 remplir_nu(nu_); // On remplit le tableau nu contenant la diffusivite en chaque elem
179
180 const Domaine_VEF& le_dom_VEF = domaine_vef();
181 const Domaine& le_dom = le_dom_VEF.domaine();
182 const DoubleVect& diffu_turb = diffusivite_turbulente().valeurs();
183 double alpha = -123., coef = -123.;
184 ToDo_Kokkos("critical");
185
186 int le_dom_nb_elem = le_dom.nb_elem();
188 {
189 const DoubleTab& rho_elem = get_champ_masse_volumique().valeurs();
190 assert(rho_elem.size_array() == le_dom_VEF.nb_elem_tot());
191 for (int num_elem = 0; num_elem < le_dom_nb_elem; num_elem++)
192 {
193 alpha = nu_[num_elem] + diffu_turb[num_elem]; // PQ : 06/03
194 alpha /= rho_elem[num_elem];
195 coef = le_dom_VEF.carre_pas_maille()(num_elem) / (2. * dimension * alpha);
196 es_valeurs(num_elem) = coef;
197 }
198 }
199 else
200 {
201 const Champ_base& champ_diffusivite = diffusivite_pour_pas_de_temps();
202 const DoubleTab& valeurs_diffusivite = champ_diffusivite.valeurs();
203 const int cD = (valeurs_diffusivite.dimension(0) == 1); // uniforme ou pas ?
204 for (int num_elem = 0; num_elem < le_dom_nb_elem; num_elem++)
205 {
206 const double valeurs_diffusivite_dt = valeurs_diffusivite(!cD * num_elem);
207 alpha = nu_[num_elem] + diffu_turb[num_elem]; // PQ : 06/03
208 alpha *= valeurs_diffusivite_dt / nu_[num_elem];
209 coef = le_dom_VEF.carre_pas_maille()(num_elem) / (2. * dimension * alpha);
210 es_valeurs(num_elem) = coef;
211 }
212 }
213
214 assert(est_egal(mp_min_vect(es_valeurs), calculer_dt_stab()));
215 }
216 }
217 else
218 Op_Diff_VEF_base::calculer_pour_post(espace_stockage, option, comp);
219}
220
221// La diffusivite est constante par elements donc il faut calculer dt_diff pour chaque element et dt_stab=Min(dt_diff (K) = h(K)*h(K)/(2*dimension*diffu2_(K)))
222// ou diffu2_ est la somme des 2 diffusivite laminaire et turbulente
224{
225 const Domaine_VEF& domaine_VEF = domaine_vef();
226 const IntTab& elem_faces = domaine_VEF.elem_faces();
227 const DoubleTab& face_normales = domaine_VEF.face_normales();
228 const DoubleVect& volumes = domaine_VEF.volumes(), &diffu_turb = diffusivite_turbulente().valeurs();
229 const int nb_faces_elem = domaine_VEF.domaine().nb_faces_elem(), le_dom_nb_elem = domaine_VEF.domaine().nb_elem();
230
231 const double diffu = diffusivite(0);
232 double dt_stab = 1.e30, coef, diffu2_;
233 ToDo_Kokkos("critical");
234
235 for (int num_elem = 0; num_elem < le_dom_nb_elem; num_elem++)
236 {
237 double surf_max = 1.e-30;
238 for (int i = 0; i < nb_faces_elem; i++)
239 {
240 const int num_face = elem_faces(num_elem, i);
241 double surf = face_normales(num_face, 0) * face_normales(num_face, 0);
242 for (int j = 1; j < dimension; j++)
243 surf += face_normales(num_face, j) * face_normales(num_face, j);
244 surf_max = (surf > surf_max) ? surf : surf_max;
245 }
246 double vol = volumes(num_elem);
247 vol *= vol / surf_max;
248 diffu2_ = diffu + diffu_turb[num_elem];
249 coef = vol / (2. * dimension * (diffu2_ + DMINFLOAT));
250 dt_stab = (coef < dt_stab) ? coef : dt_stab;
251 }
252
253 return Process::mp_min(dt_stab);
254}
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
classe Champ_Fonc_base Classe de base des champs qui sont fonction d'une grandeur calculee
Classe Champ_Inc_base.
virtual DoubleTab & valeurs()=0
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
int_t nb_elem() const
Definition Domaine.h:131
int nb_faces_elem(int=0) const
Renvoie le nombre de face de type i des elements geometriques constituants le domaine.
Definition Domaine.h:484
classe Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
class Domaine_VEF
Definition Domaine_VEF.h:54
const DoubleVect & carre_pas_maille() const
Definition Domaine_VEF.h:83
virtual double face_normales(int face, int comp) const
Definition Domaine_VF.h:47
double volumes(int i) const
Definition Domaine_VF.h:113
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
Definition Domaine_VF.h:543
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
int nb_elem_tot() const
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual const RefObjU & get_modele(Type_modele type) const
Classe Modele_turbulence_hyd_base Cette classe sert de base a la hierarchie des classes.
const Champ_Fonc_base & viscosite_turbulente() const
Classe Modele_turbulence_scal_base Cette classe represente un modele de turbulence pour une equation ...
const Champ_Fonc_base & conductivite_turbulente() const
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
classe Navier_Stokes_std Cette classe porte les termes de l'equation de la dynamique
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
static int dimension
Definition Objet_U.h:99
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
const Champ_Fonc_base & diffusivite_turbulente() const
void associer_diffusivite_turbulente(const Champ_Fonc_base &)
class Op_Diff_VEF_base
void calculer_pour_post(Champ_base &espace_stockage, const Nom &option, int comp) const override
virtual void remplir_nu(DoubleTab &) const
const Domaine_VEF & domaine_vef() const
void associer(const Domaine_dis_base &, const Domaine_Cl_dis_base &, const Champ_Inc_base &) override
void mettre_a_jour(double temps) override
DOES NOTHING - to override in derived classes.
void completer() override
Associe l'operateur au domaine_dis, le domaine_Cl_dis, et a l'inconnue de son equation.
const Champ_base & diffusivite() const override
void calculer_borne_locale(DoubleVect &, double, double) const override
double calculer_dt_stab() const override
Calcul dt_stab.
double calculer_dt_stab_P1NCP1B() const
void associer_modele_turbulence(const Modele_turbulence_hyd_base &)
void calculer_pour_post(Champ_base &espace_stockage, const Nom &option, int comp) const override
virtual const Champ_base & diffusivite_pour_pas_de_temps() const
Renvoie le champ_don correspondant a la vraie diffusivite du milieu qui sert pour le calcul du pas de...
virtual void completer()
Associe l'operateur au domaine_dis, le domaine_Cl_dis, et a l'inconnue de son equation.
static double mp_min(double)
Definition Process.cpp:386
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
virtual const Champ_base & get_champ_masse_volumique() const
Renvoie le champ de masse volumique.
virtual int has_champ_masse_volumique() const
Renvoie 1 si la masse volumique a ete associee, 0 sinon.
_SIZE_ size_array() const
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, ConstView< _TYPE_, _SHAPE_ > > view_ro() const
Definition TRUSTTab.h:261
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
int line_size() const
Definition TRUSTVect.tpp:67
const Objet_U & valeur() const
Definition TRUST_Ref.h:134