TRUST 1.9.8
HPC thermohydraulic platform
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 // On initialise tout de suite la loi de paroi
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 // Initialisations de equivalent_distance_, tab_d_reel, positions_Pf, elems_plus
73 // On initialise les distances equivalentes avec les distances geometriques
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 << "Attention, rien n'est fait en Axi pour le 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.: on passe ici deux fois: une fois au readOn (par Paroi_scal_hyd_base_VEF::associer())
98 // et une fois par Modele_turbulence_scal_base::preparer_calcul())
99 // donc tester si pas deja fait:
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 // Recherche d'une face autre que la face de paroi appartenant a l'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 // Les tableaux positions_Pf_, elems_plus_ ne sont calcules que sur les faces reelles
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 // on doit calculer Tfluide premiere maille sans prendre en compte 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 // Et on ajoute Tface et on Tparoi recalcule avec 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
Renvoie le tableau des valeurs du champ au temps courant.
classe Champ_Uniforme Represente un champ constant dans l'espace et dans le temps.
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
classe Convection_Diffusion_std Cette classe est la base des equations modelisant le transport
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 Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
class Domaine_VF
Definition Domaine_VF.h:44
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
Sortie & syncfile() override
Provoque l'ecriture sur disque des donnees accumulees sur les differents processeurs depuis le dernie...
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
virtual const Milieu_base & milieu() const =0
virtual const Champ_Inc_base & inconnue() const =0
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limite discretisee associee a l'equation.
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
classe Fluide_base Cette classe represente un d'un fluide incompressible ainsi que
Definition Fluide_base.h:38
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
Cree un tableau ayant une "ligne" par face de cette frontiere Voir MD_Vector_tools::creer_tableau_dis...
const Frontiere & frontiere() const
Renvoie la frontiere geometrique associee.
const Nom & le_nom() const override
Renvoie le nom de la frontiere geometrique.
virtual const Champ_Don_base & conductivite() const
Renvoie la conductivite du milieu.
Classe Neumann_paroi Cette condition limite correspond a un flux impose pour l'equation de.
virtual double flux_impose(int i) const
Renvoie la valeur du flux impose sur la i-eme composante du champ representant le flux a la frontiere...
Definition Neumann.cpp:35
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
static int dimension
Definition Objet_U.h:99
friend class Sortie
Definition Objet_U.h:75
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 const Nom & le_nom() const
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Objet_U.cpp:319
static int axi
Definition Objet_U.h:101
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
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)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
Classe de base des flux de sortie.
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")
Classe Turbulence_paroi_scal_base Classe de base pour la hierarchie des classes representant les mode...
const DoubleVects & equivalent_distance() const
void ouvrir_fichier_partage(EcrFicPartage &, const Nom &) const
Ouverture/creation d'un fichier d'impression de Face, d_eq, Nu local, h.