TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Paroi_scal_hyd_base_VEF.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 <Modifier_pour_fluide_dilatable.h>
17#include <Modele_turbulence_scal_base.h>
18#include <Fluide_Quasi_Compressible.h>
19#include <Dirichlet_paroi_defilante.h>
20#include <Convection_Diffusion_std.h>
21#include <Paroi_scal_hyd_base_VEF.h>
22#include <Dirichlet_paroi_fixe.h>
23#include <Paroi_decalee_Robin.h>
24#include <Domaine_Cl_VEF.h>
25#include <Champ_Uniforme.h>
26#include <EcrFicPartage.h>
27#include <Probleme_base.h>
28#include <Neumann_paroi.h>
29#include <Fluide_base.h>
30#include <Domaine_VEF.h>
31#include <SFichier.h>
32
33Implemente_base(Paroi_scal_hyd_base_VEF, "Paroi_scal_hyd_base_VEF", Turbulence_paroi_scal_base);
34
35Sortie& Paroi_scal_hyd_base_VEF::printOn(Sortie& s) const { return s << que_suis_je() << " " << le_nom(); }
36
38
39void Paroi_scal_hyd_base_VEF::associer(const Domaine_dis_base& domaine_dis, const Domaine_Cl_dis_base& domaine_Cl_dis)
40{
41 le_dom_dis_ = ref_cast(Domaine_VF, domaine_dis);
42 le_dom_Cl_dis_ = domaine_Cl_dis;
43 // Initialize the wall law immediately
45}
46
47DoubleVect& Paroi_scal_hyd_base_VEF::equivalent_distance_name(DoubleVect& d_eq, const Nom& nom_bord) const
48{
49 int nb_boundaries = le_dom_dis_->domaine().nb_front_Cl();
50 for (int n_bord = 0; n_bord < nb_boundaries; n_bord++)
51 {
52 const Front_VF& fr_vf = le_dom_dis_->front_VF(n_bord);
53 int nb_faces = fr_vf.nb_faces();
54 if (fr_vf.le_nom() == nom_bord)
55 {
56 d_eq.resize(fr_vf.nb_faces());
57 for (int ind_face = 0; ind_face < nb_faces; ind_face++)
58 d_eq(ind_face) = equivalent_distance(n_bord, ind_face);
59 }
60 }
61 return d_eq;
62}
63
65{
66 int nb_faces_bord_reelles = le_dom_dis_->nb_faces_bord();
67 tab_d_reel_.resize(nb_faces_bord_reelles);
68 tab_.resize(nb_faces_bord_reelles, nb_fields_);
69 // positions_Pf_.resize(nb_faces_bord_reelles,dimension);
70 // elems_plus_.resize(nb_faces_bord_reelles);
71
72 // Initialize equivalent_distance_, tab_d_reel, positions_Pf, elems_plus
73 // Initialize the equivalent distances with the geometric distances
74 const DoubleTab& face_normales = le_dom_dis_->face_normales();
75 // const DoubleTab& xv = le_dom_dis_->xv();
76 const IntTab& elem_faces = le_dom_dis_->elem_faces();
77 const IntTab& face_voisins = le_dom_dis_->face_voisins();
78 const DoubleVect& volumes_maille = le_dom_dis_->volumes();
79 const DoubleVect& surfaces_face = le_dom_dis_->face_surfaces();
80
81 if (axi)
82 {
83 Cerr << "Warning, nothing is implemented for Axi in VEF" << finl;
84 exit();
85 }
86 else
87 {
88 int nb_front = le_dom_dis_->nb_front_Cl();
89 equivalent_distance_.dimensionner(nb_front);
90 for (int n_bord = 0; n_bord < nb_front; n_bord++)
91 {
92 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
93 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
94
95 int size = le_bord.nb_faces();
96 DoubleVect& dist_equiv = equivalent_distance_[n_bord];
97 // Note B.M.: this is called twice: once at readOn (by Paroi_scal_hyd_base_VEF::associer())
98 // and once by Modele_turbulence_scal_base::preparer_calcul())
99 // therefore check if it has already been done:
100 if (!dist_equiv.get_md_vector())
101 le_bord.frontiere().creer_tableau_faces(dist_equiv, RESIZE_OPTIONS::NOCOPY_NOINIT);
102 //assert(dist_equiv.get_md_vector() == le_bord.frontiere().md_vector_faces());
103
104 for (int ind_face = 0; ind_face < size; ind_face++)
105 {
106 int num_face = le_bord.num_face(ind_face);
107 int elem, autre_face;
108 elem = face_voisins(num_face, 0);
109 if (elem == -1)
110 elem = face_voisins(num_face, 1);
111
112 // Find a face other than the wall face belonging to element
113 // elem.
114 autre_face = elem_faces(elem, 0);
115 if (autre_face == num_face)
116 autre_face = elem_faces(elem, 1);
117
118 double distance = volumes_maille(elem) / surfaces_face(num_face);
119
120 tab_d_reel_[num_face] = distance;
121
122 dist_equiv(ind_face) = distance;
123
124 double ratio = 0.;
125 int i;
126 for (i = 0; i < dimension; i++)
127 ratio += (face_normales(num_face, i) * face_normales(num_face, i));
128 ratio = sqrt(ratio);
129 /*
130 // The arrays positions_Pf_, elems_plus_ are computed only on real faces
131 for (i=0; i<dimension; i++)
132 positions_Pf_(num_face,i)=xv(num_face,i) - tab_d_reel_[num_face]*(face_normales(num_face,i)/ratio);
133
134 if (dimension == 2)
135 elems_plus_(num_face) = le_dom_dis_->domaine().chercher_elements(positions_Pf_(num_face,0), positions_Pf_(num_face,1));
136 else
137 elems_plus_(num_face) = le_dom_dis_->domaine().chercher_elements(positions_Pf_(num_face,0), positions_Pf_(num_face,1),positions_Pf_(num_face,2));
138
139
140 if (elems_plus_(num_face) < 0)
141 {
142 for (i=0; i<dimension; i++)
143 positions_Pf_(num_face,i)=xv(num_face,i) - tab_d_reel_[num_face]*(face_normales(num_face,i)/ratio);
144
145 if (dimension == 2)
146 elems_plus_(num_face) = le_dom_dis_->domaine().chercher_elements(positions_Pf_(num_face,0), positions_Pf_(num_face,1));
147 else
148 elems_plus_(num_face) = le_dom_dis_->domaine().chercher_elements(positions_Pf_(num_face,0), positions_Pf_(num_face,1),positions_Pf_(num_face,2));
149 }
150 */
151 }
152
153 dist_equiv.echange_espace_virtuel();
154 }
155 }
156
157 return 1;
158}
159
161{
162 for (int n_bord = 0; n_bord < le_dom_dis_->nb_front_Cl(); n_bord++)
163 {
164 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
165 if ((sub_type(Dirichlet_paroi_fixe, la_cl.valeur())) || (sub_type(Dirichlet_paroi_defilante, la_cl.valeur())) || (sub_type(Paroi_decalee_Robin, la_cl.valeur())))
166 {
167 const Convection_Diffusion_std& eqn = mon_modele_turb_scal->equation();
168 const Domaine_Cl_VEF& domaine_Cl_VEF_th = ref_cast(Domaine_Cl_VEF, eqn.probleme().equation(1).domaine_Cl_dis());
169 const Cond_lim& la_cl_th = domaine_Cl_VEF_th.les_conditions_limites(n_bord);
170 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
171
172 int ndeb = le_bord.num_premiere_face();
173 int nfin = ndeb + le_bord.nb_faces();
174 int nb_faces_elem = le_dom_dis_->domaine().nb_faces_elem();
175 int dim = dimension;
176 DoubleTrav lambda(nfin-ndeb);
177 DoubleTrav lambda_t(nfin-ndeb);
178 DoubleTrav tfluide(nfin-ndeb);
179 const Equation_base& eqn_hydr = eqn.probleme().equation(0);
180 const Fluide_base& le_fluide = ref_cast(Fluide_base, eqn_hydr.milieu());
181 const DoubleTab& temperature = eqn.probleme().equation(1).inconnue().valeurs();
182 bool unif = sub_type(Champ_Uniforme, le_fluide.conductivite());
183 CDoubleArrView conductivite = static_cast<const DoubleVect&>(le_fluide.conductivite().valeurs()).view_ro();
184 CDoubleArrView conductivite_turbulente = static_cast<const DoubleVect&>(mon_modele_turb_scal->conductivite_turbulente().valeurs()).view_ro();
185 CDoubleArrView face_surfaces = le_dom_dis_->face_surfaces().view_ro();
186 CDoubleTabView face_normales = le_dom_dis_->face_normales().view_ro();
187 CIntTabView face_voisins = le_dom_dis_->face_voisins().view_ro();
188 CIntTabView elem_faces = le_dom_dis_->elem_faces().view_ro();
189 CDoubleArrView temperature_v = static_cast<const DoubleVect&>(temperature).view_ro();
190 DoubleArrView lambda_v = static_cast<DoubleVect&>(lambda).view_wo();
191 DoubleArrView lambda_t_v = static_cast<DoubleVect&>(lambda_t).view_wo();
192 DoubleArrView tfluide_v = static_cast<DoubleVect&>(tfluide).view_rw();
193 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(ndeb, nfin),
194 KOKKOS_LAMBDA(const int num_face)
195 {
196 int ind_face = num_face - ndeb;
197 int elem = face_voisins(num_face, 0);
198 if (elem == -1)
199 elem = face_voisins(num_face, 1);
200
201 lambda_v(ind_face) = conductivite(unif ? 0 : elem);
202 lambda_t_v(ind_face) = conductivite_turbulente(elem);
203
204 // compute Tfluide of the first cell without including Tparoi
205 double surface_face = face_surfaces(num_face);
206 for (int i = 0; i < nb_faces_elem; i++)
207 {
208 int j = elem_faces(elem, i);
209 if (j != num_face)
210 {
211 double surface_pond = 0.;
212 for (int kk = 0; kk < dim; kk++)
213 surface_pond -=
214 (face_normales(j, kk) * oriente_normale(j, elem, face_voisins) *
215 face_normales(num_face, kk) * oriente_normale(num_face, elem, face_voisins))
216 / (surface_face * surface_face);
217 tfluide_v(ind_face) += temperature_v(j) * surface_pond;
218 }
219 }
220 });
221 end_gpu_timer(__KERNEL_NAME__);
222 // Ecriture
223 for (int num_face = ndeb; num_face < nfin; num_face++)
224 {
225 int ind_face = num_face - ndeb;
226 double d_equiv = equivalent_distance_[n_bord](num_face - ndeb);
227 tab_(num_face, 0) = d_equiv;
228 tab_(num_face, 1) = (lambda(ind_face) + lambda_t(ind_face)) / lambda(ind_face) * tab_d_reel_[num_face] / d_equiv;
229 tab_(num_face, 2) = (lambda(ind_face) + lambda_t(ind_face)) / d_equiv;
230 tab_(num_face, 3) = tfluide(ind_face);
231 if ((sub_type(Neumann_paroi, la_cl_th.valeur())))
232 {
233 // And we add Tface and recompute Tparoi with d_equiv
234 const Neumann_paroi& la_cl_neum = ref_cast(Neumann_paroi, la_cl_th.valeur());
235 double tparoi = temperature(num_face);
236 double flux = la_cl_neum.flux_impose(num_face - ndeb);
237 double tparoi_equiv = tfluide(ind_face) + flux / (lambda(ind_face) + lambda_t(ind_face)) * d_equiv;
238 tab_(num_face, 4) = tparoi;
239 tab_(num_face, 5) = tparoi_equiv;
240 }
241 else
242 {
243 tab_(num_face, 4) = 0.;
244 tab_(num_face, 5) = 0.;
245 }
246 }
247 }
248 }
249}
250
252{
254
255 EcrFicPartage Nusselt;
256 ouvrir_fichier_partage(Nusselt, "Nusselt");
257
258 for (int n_bord = 0; n_bord < le_dom_dis_->nb_front_Cl(); n_bord++)
259 {
260 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
261 if ((sub_type(Dirichlet_paroi_fixe, la_cl.valeur())) || (sub_type(Dirichlet_paroi_defilante, la_cl.valeur())) || (sub_type(Paroi_decalee_Robin, la_cl.valeur())))
262 {
263 const Convection_Diffusion_std& eqn = mon_modele_turb_scal->equation();
264 const Domaine_Cl_VEF& domaine_Cl_VEF_th = ref_cast(Domaine_Cl_VEF, eqn.probleme().equation(1).domaine_Cl_dis());
265 const Cond_lim& la_cl_th = domaine_Cl_VEF_th.les_conditions_limites(n_bord);
266 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
267
268 if (je_suis_maitre())
269 {
270 Nusselt << finl;
271 Nusselt << "Bord " << le_bord.le_nom() << finl;
272 if ((sub_type(Neumann_paroi, la_cl_th.valeur())))
273 {
274 if (dimension == 2)
275 {
276 Nusselt
277 << "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
278 << finl;
279 Nusselt << "\tFace a\t\t\t\t|" << finl;
280 Nusselt
281 << "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
282 << finl;
283 Nusselt << "X\t\t| Y\t\t\t| dist. carac. (m)\t| Nusselt (local)\t| h (Conv. W/m2/K)\t| Tf cote paroi (K)\t| T face de bord (K)\t| Tparoi equiv.(K) " << finl;
284 Nusselt
285 << "----------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------"
286 << finl;
287 }
288 if (dimension == 3)
289 {
290 Nusselt
291 << "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
292 << finl;
293 Nusselt << "\tFace a\t\t\t\t\t\t\t|" << finl;
294 Nusselt
295 << "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
296 << finl;
297 Nusselt << "X\t\t| Y\t\t\t| Z\t\t\t| dist. carac. (m)\t| Nusselt (local)\t| h (Conv. W/m2/K)\t| Tf cote paroi (K)\t| T face de bord (K)\t| Tparoi equiv.(K)" << finl;
298 Nusselt
299 << "----------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------"
300 << finl;
301 }
302 }
303 else
304 {
305 if (dimension == 2)
306 {
307 Nusselt << "----------------------------------------------------------------------------------------------------------------------------------------------------------------"
308 << finl;
309 Nusselt << "\tFace a\t\t\t\t|" << finl;
310 Nusselt << "----------------------------------------------------------------------------------------------------------------------------------------------------------------"
311 << finl;
312 Nusselt << "X\t\t| Y\t\t\t| dist. carac. (m)\t| Nusselt (local)\t| h (Conv. W/m2/K)\t| Tf cote paroi (K) " << finl;
313 Nusselt << "----------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------" << finl;
314 }
315 if (dimension == 3)
316 {
317 Nusselt << "----------------------------------------------------------------------------------------------------------------------------------------------------------------"
318 << finl;
319 Nusselt << "\tFace a\t\t\t\t\t\t\t|" << finl;
320 Nusselt << "----------------------------------------------------------------------------------------------------------------------------------------------------------------"
321 << finl;
322 Nusselt << "X\t\t| Y\t\t\t| Z\t\t\t| dist. carac. (m)\t| Nusselt (local)\t| h (Conv. W/m2/K)\t| Tf cote paroi (K) " << finl;
323 Nusselt << "----------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------"
324 << finl;
325 }
326 }
327 }
328 int ndeb = le_bord.num_premiere_face();
329 int nfin = ndeb + le_bord.nb_faces();
330 // Ecriture
331 for (int num_face = ndeb; num_face < nfin; num_face++)
332 {
333 double x = le_dom_dis_->xv(num_face, 0);
334 double y = le_dom_dis_->xv(num_face, 1);
335 if (dimension == 2)
336 Nusselt << x << "\t| " << y;
337 if (dimension == 3)
338 {
339 double z = le_dom_dis_->xv(num_face, 2);
340 Nusselt << x << "\t| " << y << "\t| " << z;
341 }
342 int nb_fields = nb_fields_;
343 if (!sub_type(Neumann_paroi, la_cl_th.valeur()))
344 nb_fields -= 2;
345 for (int i=0; i<nb_fields; i++)
346 Nusselt << "\t| " << tab_(num_face, i);
347 Nusselt << finl;
348 }
349 Nusselt.syncfile();
350 }
351 }
352 if (je_suis_maitre())
353 Nusselt << finl << finl;
354 Nusselt.syncfile();
355}
DoubleTab & valeurs() override
Returns the array of field values at the current time.
Champ_Uniforme Represents a field that is constant in space and time.
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
Convection_Diffusion_std This class is the base for equations modelling the transport.
Dirichlet_paroi_defilante Imposes the wall velocity in an equation of type Navier_Stokes.
Dirichlet_paroi_fixe Represents a fixed wall in a Navier-Stokes type equation.
class Domaine_Cl_dis_base Domaine_Cl_dis_base objects represent discretized boundary conditions
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
class Domaine_VF
Definition Domaine_VF.h:44
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
Sortie & syncfile() override
Triggers writing to disk of the data accumulated on the different processors since the last call to s...
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Equation_base The role of an equation is the calculation of one or more fields....
virtual const Milieu_base & milieu() const =0
virtual const Champ_Inc_base & inconnue() const =0
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Returns the discretized boundary condition domain associated with the equation.
Probleme_base & probleme()
Returns the problem associated with the equation.
Base class for an incompressible fluid and its properties:
Definition Fluide_base.h:36
class Front_VF
Definition Front_VF.h:36
int nb_faces() const
Definition Front_VF.h:53
int num_premiere_face() const
Definition Front_VF.h:63
int num_face(const int) const
Definition Front_VF.h:68
virtual void creer_tableau_faces(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
Creates an array with one "row" per face of this boundary.
const Frontiere & frontiere() const
Returns the associated geometric boundary.
const Nom & le_nom() const override
Returns the name of the geometric boundary.
virtual const Champ_Don_base & conductivite() const
Returns the conductivity of the medium (const version).
Classe Neumann_paroi This boundary condition corresponds to an imposed flux for the.
virtual double flux_impose(int i) const
Returns the value of the imposed flux on the i-th component of the field representing the flux at the...
Definition Neumann.cpp:35
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
static int dimension
Definition Objet_U.h:94
friend class Sortie
Definition Objet_U.h:70
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
virtual const Nom & le_nom() const
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Definition Objet_U.cpp:317
static int axi
Definition Objet_U.h:96
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
void imprimer_nusselt(Sortie &) const override
void compute_nusselt() const override
void associer(const Domaine_dis_base &, const Domaine_Cl_dis_base &) override
DoubleVect & equivalent_distance_name(DoubleVect &d_eq, const Nom &nom_bord) const override
virtual const Equation_base & equation(int) const =0
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
static int je_suis_maitre()
Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
Definition Process.cpp:82
Base class for output streams.
Definition Sortie.h:52
void resize(_SIZE_, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTVect.tpp:91
virtual const MD_Vector & get_md_vector() const
Definition TRUSTVect.h:123
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
Base class for the hierarchy of scalar wall-law models computing turbulent quantities near walls....
const DoubleVects & equivalent_distance() const
void ouvrir_fichier_partage(EcrFicPartage &, const Nom &) const
Opens or creates a print file for Face, d_eq, local Nu, h.