TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Loi_Paroi_Nu_Impose_VDF.cpp
1/****************************************************************************
2* Copyright (c) 2015 - 2016, 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 <Loi_Paroi_Nu_Impose_VDF.h>
17#include <Champ_Uniforme.h>
18#include <Champ_Uniforme_Morceaux.h>
19#include <Champ_Fonc_Tabule.h>
20#include <Domaine_Cl_VDF.h>
21#include <Dirichlet_paroi_fixe.h>
22#include <Dirichlet_paroi_defilante.h>
23#include <Neumann_paroi.h>
24#include <Debog.h>
25#include <Fluide_base.h>
26#include <Convection_Diffusion_std.h>
27#include <Probleme_base.h>
28#include <EcrFicPartage.h>
29#include <Modele_turbulence_scal_base.h>
30
31Implemente_instanciable(Loi_Paroi_Nu_Impose_VDF,"Loi_Paroi_Nu_Impose_VDF",Paroi_scal_hyd_base_VDF);
32
33
34// printOn()
35/////
36
38{
39 return s << que_suis_je() << " " << le_nom();
40}
41
42//// readOn
43//
44
46{
47
48 // Definition des mots-cles
49 Motcles les_mots(2);
50 les_mots[0] = "nusselt";
51 les_mots[1] = "diam_hydr";
52 int nusselt_ok=-1;
53 // Lecture et interpretation
54 Motcle motlu, accolade_fermee="}", accolade_ouverte="{";
55 s >> motlu;
56 assert(motlu==accolade_ouverte);
57 s >> motlu;
58 if(motlu == accolade_ouverte)
59 {
60 // on passe l'accolade ouvrante
61 s >> motlu;
62 }
63 while (motlu != accolade_fermee)
64 {
65 int rang=les_mots.search(motlu);
66 switch(rang)
67 {
68 case 0 : // nusselt expression
69 {
70 nusselt_ok=0;
71 Nom tmp;
72 s >> tmp;
73 Cerr << "Lecture et interpretation de la fonction " << tmp << " ... ";
74 nusselt.setNbVar(5+dimension);
75 nusselt.setString(tmp);
76 nusselt.addVar("Re");
77 nusselt.addVar("Pr");
78 nusselt.addVar("t");
79 nusselt.addVar("x");
80 if (dimension>1)
81 nusselt.addVar("y");
82 if (dimension>2)
83 nusselt.addVar("z");
84 nusselt.addVar("Dh");
85 nusselt.addVar("Lambda");
86 nusselt.parseString();
87 break;
88 }
89 case 1: // diam_hydr
90 s >> diam_hydr;
91 break;
92 default : // non compris
93 Cerr << "Mot cle \"" << motlu << "\" non compris lors de la lecture d'un "
94 << que_suis_je() << finl;
96 }
97 s >> motlu;
98 }
99
100 // Verification de la coherence
101 if (nusselt_ok==-1)
102 {
103 Cerr << "Il faut definir l'expression nusselt(Re,Pr,x,y,z,Dh)" << finl;
105 }
106
107 if (diam_hydr->nb_comp()!=1)
108 {
109 Cerr << "Il faut definir le champ diam_hydr a une composante" << finl;
111 }
112 return s;
113}
114
115
116/////////////////////////////////////////////////////////////////////////
117//
118// Implementation des fonctions de la classe Loi_Paroi_Nu_Impose_VDF
119//
120////////////////////////////////////////////////////////////////////////
121
123{
124 const Domaine_VDF& domaine_VDF = ref_cast(Domaine_VDF, le_dom_dis_.valeur());
125 const IntTab& face_voisins = domaine_VDF.face_voisins();
126 const Equation_base& eqn_hydr = mon_modele_turb_scal->equation().probleme().equation(0);
127 const DoubleTab& vitesse = eqn_hydr.inconnue().valeurs();
128 const Fluide_base& le_fluide = ref_cast(Fluide_base,eqn_hydr.milieu());
129 const Champ_Don_base& ch_visco_cin = le_fluide.viscosite_cinematique();
130 const IntVect& orientation = domaine_VDF.orientation();
131 const DoubleTab& xv=domaine_VDF.xv() ; // centres de gravite des faces
132 const IntTab& elem_faces = domaine_VDF.elem_faces();
133
134 DoubleVect pos(dimension);
135
136 const DoubleTab& tab_visco = ch_visco_cin.valeurs();
137 int l_unif;
138 double visco=-1;
139 if (sub_type(Champ_Uniforme,ch_visco_cin))
140 {
141 l_unif = 1;
142 visco = std::max(tab_visco(0,0),DMINFLOAT);
143 }
144 else
145 l_unif = 0;
146
147 if ((!l_unif) && (local_min_vect(tab_visco)<DMINFLOAT))
148 // on ne doit pas changer tab_visco ici !
149 {
150 Cerr << "In Loi_Paroi_Nu_Impose_VDF::calculer_scal : visco = " << tab_visco.local_min_vect() << " <= 0 ? " << finl;
151 throw;
152 }
153 //tab_visco+=DMINFLOAT;
154
155 bool dh_constant=sub_type(Champ_Uniforme,diam_hydr.valeur())?true:false;
156 double dh_valeur=diam_hydr->valeurs()(0,0);
157
158
159
160 int ndeb,nfin;
161 int elem;
162 double d_visco;
163
164 // const Convection_Diffusion_std& eqn = mon_modele_turb_scal->equation();
165 const Champ_Don_base& alpha = le_fluide.diffusivite();
166
167 // Boucle sur les bords:
168 for (int n_bord=0; n_bord<domaine_VDF.nb_front_Cl(); n_bord++)
169 {
170
171 // Pour chaque condition limite on regarde son type
172 // On applique les lois de paroi thermiques uniquement
173 // aux voisinages des parois ou l'on impose la temperature
174
175 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
176 if ( (sub_type(Dirichlet_paroi_fixe,la_cl.valeur()))
177 || (sub_type(Dirichlet_paroi_defilante,la_cl.valeur())) )
178 {
179
180 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
181 ndeb = le_bord.num_premiere_face();
182 nfin = ndeb + le_bord.nb_faces();
183
184 //find the associated boundary
185 int boundary_index=-1;
186 if (domaine_VDF.front_VF(n_bord).le_nom() == le_bord.le_nom())
187 boundary_index=n_bord;
188 assert(boundary_index >= 0);
189
190 for (int num_face=ndeb; num_face<nfin; num_face++)
191 {
192 elem = face_voisins(num_face,0);
193 if (elem == -1)
194 elem = face_voisins(num_face,1);
195 if (l_unif)
196 d_visco = visco;
197 else
198 d_visco = tab_visco[elem];
199
200 double d_alpha=0.;
201 if (sub_type(Champ_Uniforme,alpha))
202 d_alpha = alpha.valeurs()(0,0);
203 else
204 {
205 if (alpha.nb_comp()==1)
206 d_alpha = alpha.valeurs()(elem);
207 else
208 d_alpha = alpha.valeurs()(elem,0);
209 }
210 double Pr = d_visco/d_alpha;
211
212 // On calcule la vitesse debitante comme etant la moyenne des vitesses presentes sur les faces orthogonales a la face courante du bord.
213 int ori = orientation(num_face);
214 int face1 = elem_faces(elem,(ori+1));
215 int face2 = elem_faces(elem,(ori+1+dimension)%(2*dimension));
216 double Ud = 0.5*(vitesse(face1)+vitesse(face2));
217 Ud *= Ud;
218 if (dimension==3)
219 {
220 face1 = elem_faces(elem,(ori+2));
221 face2 = elem_faces(elem,(ori+2+dimension)%(2*dimension));
222 double tmp =0.5*(vitesse(face1)+vitesse(face2));
223 Ud += tmp*tmp;
224 }
225
226 Ud=sqrt(Ud);
227
228 // Calcul de la position
229 for (int i=0; i<dimension; i++)
230 pos[i]=xv(num_face,i);
231
232 // Calcul du diametre hydraulique
233 if (!dh_constant)
234 {
235 dh_valeur=diam_hydr->valeur_a_compo(pos,0);
236 }
237
238 double Re=Ud*dh_valeur/d_visco;
239
240 nusselt.setVar("Re",Re);
241 nusselt.setVar("Pr",Pr);
242 nusselt.setVar("Dh",dh_valeur);
243 //nusselt->setVar("Lambda",d_alpha);
244 // nusselt->setVar("t",Pr);
245 for (int i=0; i<dimension; i++)
246 {
247 nusselt.setVar(3+i,pos[i]);
248 }
249 double Nu = nusselt.eval();
250
251 // L'expression de d_equiv ne tient pas compte de alpha_t comme en VEF
252 // Cela dit, c'est normale car c'est lors du calcul du flux que la
253 // turbulence est prise en compte.
254 // Ne pas uniformiser l'ecriture avec le VEF, car on tombe sur des problemes
255 // au niveau des parois contacts entre plusieurs problemes (alpha_t pas recuperable !).
256 int global_face=num_face;
257 int local_face=domaine_VDF.front_VF(boundary_index).num_local_face(global_face);
258 equivalent_distance_[boundary_index](local_face)=dh_valeur/Nu;
259 //Cout << "pos = " << pos[0] << " " << pos[1] << finl;
260 //Cout << "Nu = " << Nu << finl;
261 //Cout << "diam = " << dh_valeur << finl;
262 //Cout << "tab_d_equiv_ = " << tab_d_equiv_[num_face] << finl;
263 }
264 }
265 }
266 return 1;
267}
268
269
270
272{
273 const Domaine_VDF& domaine_VDF = ref_cast(Domaine_VDF, le_dom_dis_.valeur());
274 const IntTab& face_voisins = domaine_VDF.face_voisins();
275 int ndeb,nfin,elem;
276 const Convection_Diffusion_std& eqn = mon_modele_turb_scal->equation();
277 const Equation_base& eqn_hydr = eqn.probleme().equation(0);
278 const Fluide_base& le_fluide = ref_cast(Fluide_base, eqn_hydr.milieu());
279 const Champ_Don_base& conductivite = le_fluide.conductivite();
280 const DoubleTab& temperature = eqn.probleme().equation(1).inconnue().valeurs();
281
282 EcrFicPartage Nusselt;
283 ouvrir_fichier_partage(Nusselt,"Nusselt");
284
285 bool dh_constant=sub_type(Champ_Uniforme,diam_hydr.valeur())?true:false;
286 double dh_valeur=diam_hydr->valeurs()(0,0);
287 DoubleVect pos(dimension);
288
289 for (int n_bord=0; n_bord<domaine_VDF.nb_front_Cl(); n_bord++)
290 {
291 const Cond_lim& la_cl = le_dom_Cl_dis_->les_conditions_limites(n_bord);
292
293 if ( (sub_type(Dirichlet_paroi_fixe,la_cl.valeur())) ||
294 (sub_type(Dirichlet_paroi_defilante,la_cl.valeur()) ))
295 {
296 const Domaine_Cl_VDF& domaine_Cl_VDF_th = ref_cast(Domaine_Cl_VDF, eqn.probleme().equation(1).domaine_Cl_dis());
297 const Cond_lim& la_cl_th = domaine_Cl_VDF_th.les_conditions_limites(n_bord);
298 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
299
300 //find the associated boundary
301 int boundary_index=-1;
302 if (domaine_VDF.front_VF(n_bord).le_nom() == le_bord.le_nom())
303 boundary_index=n_bord;
304 assert(boundary_index >= 0);
305
306 if ( (sub_type(Neumann_paroi,la_cl_th.valeur())))
307 {
308 const Neumann_paroi& la_cl_neum = ref_cast(Neumann_paroi,la_cl_th.valeur());
309
310 if(je_suis_maitre())
311 {
312 Nusselt << finl;
313 Nusselt << "Bord " << le_bord.le_nom() << finl;
314 if (dimension == 2)
315 {
316 Nusselt << "----------------------------------------------------------------------------------------------------------------------------------------------------------------" << finl;
317 Nusselt << "\tFace a\t\t\t\t|" << finl;
318 Nusselt << "----------------------------------------------------------------------------------------------------------------------------------------------------------------" << finl;
319 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| Tparoi equiv.(K)" << finl;
320 Nusselt << "----------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------" << finl;
321 }
322 if (dimension == 3)
323 {
324 Nusselt << "----------------------------------------------------------------------------------------------------------------------------------------------------------------" << finl;
325 Nusselt << "\tFace a\t\t\t\t\t\t\t|" << finl;
326 Nusselt << "----------------------------------------------------------------------------------------------------------------------------------------------------------------" << finl;
327 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| Tparoi equiv.(K)" << finl;
328 Nusselt << "----------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------" << finl;
329 }
330 }
331 ndeb = le_bord.num_premiere_face();
332 nfin = ndeb + le_bord.nb_faces();
333 for (int num_face=ndeb; num_face<nfin; num_face++)
334 {
335 // Calcul de la position
336 for (int i=0; i<dimension; i++)
337 pos[i]=domaine_VDF.xv(num_face,i);
338
339 // Calcul du diametre hydraulique
340 if (!dh_constant)
341 dh_valeur=diam_hydr->valeur_a_compo(pos,0);
342
343 double x=domaine_VDF.xv(num_face,0);
344 double y=domaine_VDF.xv(num_face,1);
345 double lambda;
346
347 elem = face_voisins(num_face,0);
348 if (elem == -1)
349 elem = face_voisins(num_face,1);
350 if (sub_type(Champ_Uniforme,conductivite))
351 lambda = conductivite.valeurs()(0,0);
352 else
353 {
354 if (conductivite.nb_comp()==1)
355 lambda = conductivite.valeurs()(elem);
356 else
357 lambda = conductivite.valeurs()(elem,0);
358 }
359
360 if (dimension == 2)
361 Nusselt << x << "\t| " << y;
362 if (dimension == 3)
363 {
364 double z=domaine_VDF.xv(num_face,2);
365 Nusselt << x << "\t| " << y << "\t| " << z;
366 }
367
368 int global_face=num_face;
369 int local_face=domaine_VDF.front_VF(boundary_index).num_local_face(global_face);
370
371 double flux = la_cl_neum.flux_impose(num_face-ndeb);
372 double tparoi = temperature(elem)+flux/lambda*equivalent_distance_[boundary_index](local_face);
373
374 Nusselt << "\t| " << equivalent_distance_[boundary_index](local_face) << "\t| " << dh_valeur/equivalent_distance_[boundary_index](local_face) << "\t| "
375 << lambda/equivalent_distance_[boundary_index](local_face) << "\t| " << temperature(elem) << "\t|" << tparoi << finl;
376 }
377 }
378 // fin de condition limite flux impose
379 else
380 {
381 if(je_suis_maitre())
382 {
383 Nusselt << finl;
384 Nusselt << "Bord " << le_bord.le_nom() << finl;
385 if (dimension == 2)
386 {
387 Nusselt << "----------------------------------------------------------------------------------------------------------------------------------------" << finl;
388 Nusselt << "\tFace a\t\t\t\t|" << finl;
389 Nusselt << "----------------------------------------------------------------------------------------------------------------------------------------" << finl;
390 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;
391 Nusselt << "----------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------" << finl;
392 }
393 if (dimension == 3)
394 {
395 Nusselt << "----------------------------------------------------------------------------------------------------------------------------------------" << finl;
396 Nusselt << "\tFace a\t\t\t\t\t\t\t|" << finl;
397 Nusselt << "----------------------------------------------------------------------------------------------------------------------------------------" << finl;
398 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;
399 Nusselt << "----------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------" << finl;
400 }
401 }
402 ndeb = le_bord.num_premiere_face();
403 nfin = ndeb + le_bord.nb_faces();
404 for (int num_face=ndeb; num_face<nfin; num_face++)
405 {
406 // Calcul de la position
407 for (int i=0; i<dimension; i++)
408 pos[i]=domaine_VDF.xv(num_face,i);
409
410 // Calcul du diametre hydraulique
411 if (!dh_constant)
412 dh_valeur=diam_hydr->valeur_a_compo(pos,0);
413
414 double x=domaine_VDF.xv(num_face,0);
415 double y=domaine_VDF.xv(num_face,1);
416 double lambda;
417 elem = face_voisins(num_face,0);
418 if (elem == -1)
419 elem = face_voisins(num_face,1);
420 if (sub_type(Champ_Uniforme,conductivite))
421 lambda = conductivite.valeurs()(0,0);
422 else
423 {
424 if (conductivite.nb_comp()==1)
425 lambda = conductivite.valeurs()(elem);
426 else
427 lambda = conductivite.valeurs()(elem,0);
428 }
429 if (dimension == 2)
430 Nusselt << x << "\t| " << y;
431 if (dimension == 3)
432 {
433 double z=domaine_VDF.xv(num_face,2);
434 Nusselt << x << "\t| " << y << "\t| " << z;
435 }
436 int global_face=num_face;
437 int local_face=domaine_VDF.front_VF(boundary_index).num_local_face(global_face);
438 Nusselt << "\t| " << equivalent_distance_[boundary_index](local_face) << "\t| "
439 << dh_valeur/equivalent_distance_[boundary_index](local_face) << "\t| "
440 << lambda/equivalent_distance_[boundary_index](local_face) << "\t| " << temperature(elem) << finl;
441 }
442 }
443 Nusselt.syncfile();
444 }
445 }
446 if(je_suis_maitre())
447 Nusselt << finl << finl;
448 Nusselt.syncfile();
449}
450
class Champ_Don_base base class of Given Fields (not calculated)
DoubleTab & valeurs() override
Overrides Champ_base::valeurs() Returns the array of values.
class Champ_Fonc_base Base class of fields that are functions of a calculated quantity
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_VDF
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
class Domaine_VDF
Definition Domaine_VDF.h:61
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
double xv(int num_face, int k) const
Definition Domaine_VF.h:76
int elem_faces(int i, int j) const
Returns the index of the i-th face of element num_elem; the face numbering convention is.
Definition Domaine_VF.h:542
int face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in direction i.
Definition Domaine_VF.h:418
const Front_VF & front_VF(int i) const
Definition Domaine_VF.h:112
int nb_front_Cl() const
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.
virtual int nb_comp() const
Definition Field_base.h:56
Base class for an incompressible fluid and its properties:
Definition Fluide_base.h:36
const Champ_Don_base & viscosite_cinematique() const
Definition Fluide_base.h:56
class Front_VF
Definition Front_VF.h:36
int num_local_face(const int) const
Definition Front_VF.h:87
int nb_faces() const
Definition Front_VF.h:53
int num_premiere_face() const
Definition Front_VF.h:63
const Nom & le_nom() const override
Returns the name of the geometric boundary.
classe Loi_Paroi_Nu_Impose_VDF
int calculer_scal(Champ_Fonc_base &) override
void imprimer_nusselt(Sortie &) const override
virtual const Champ_Don_base & conductivite() const
Returns the conductivity of the medium (const version).
virtual const Champ_Don_base & diffusivite() const
Returns the diffusivity 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
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
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
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
_TYPE_ local_min_vect(Mp_vect_options opt=VECT_REAL_ITEMS) const
Definition TRUSTVect.h:155
void ouvrir_fichier_partage(EcrFicPartage &, const Nom &) const
Opens or creates a print file for Face, d_eq, local Nu, h.