TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Conv_Centre_old_VEF_Face.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 <Op_Conv_Centre_old_VEF_Face.h>
17#include <Periodique.h>
18#include <Neumann_sortie_libre.h>
19
20Implemente_instanciable(Op_Conv_Centre_old_VEF_Face,"Op_Conv_Centre_old_VEF_P1NC",Op_Conv_VEF_base);
21// XD convection_centre_old convection_deriv centre_old NO_BRACE Only for VEF discretization.
22
23//// printOn
24//
25
27{
28 return s << que_suis_je() ;
29}
30
31//// readOn
32//
33
35{
36 return s ;
37}
38
39//
40// Fonctions de la classe Op_Conv_Centre_old_VEF_Face
41//
43 const Domaine_Cl_dis_base& domaine_cl_dis,
44 const Champ_Inc_base& ch_transporte)
45{
46 const Domaine_VEF& zvef = ref_cast(Domaine_VEF,domaine_dis);
47 const Domaine_Cl_VEF& zclvef = ref_cast(Domaine_Cl_VEF,domaine_cl_dis);
48 const Champ_Inc_base& le_ch_transporte = ref_cast(Champ_Inc_base,ch_transporte);
49
50 le_dom_vef = zvef;
51 la_zcl_vef = zclvef;
52 champ_transporte = le_ch_transporte;
53
54 fluent_.reset();
55 le_dom_vef->creer_tableau_faces(fluent_);
56}
57
58DoubleTab& Op_Conv_Centre_old_VEF_Face::ajouter(const DoubleTab& transporte,
59 DoubleTab& resu) const
60{
61 const Domaine_Cl_VEF& domaine_Cl_VEF = la_zcl_vef.valeur();
62 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
63 // const Champ_Inc_base& le_transporte = champ_transporte.valeur();
64 const Champ_Inc_base& la_vitesse =vitesse_.valeur();
65
66 const IntTab& elem_faces = domaine_VEF.elem_faces();
67 const DoubleTab& face_normales = domaine_VEF.face_normales();
68 const auto& facette_normales = domaine_VEF.facette_normales();
69 // const DoubleVect& volumes_entrelaces = domaine_VEF.volumes_entrelaces();
70 const Domaine& domaine = domaine_VEF.domaine();
71 // const int nb_faces = domaine_VEF.nb_faces();
72 const int nfa7 = domaine_VEF.type_elem().nb_facette();
73 // const int nb_elem = domaine_VEF.nb_elem();
74 const int nb_elem_tot = domaine_VEF.nb_elem_tot();
75 const IntVect& rang_elem_non_std = domaine_VEF.rang_elem_non_std();
76
77
78 const DoubleTab& normales_facettes_Cl = domaine_Cl_VEF.normales_facettes_Cl();
79 // const DoubleVect& volumes_entrelaces_Cl = domaine_Cl_VEF.volumes_entrelaces_Cl();
80
81 const DoubleVect& porosite_face = equation().milieu().porosite_face();
82
83 int nfac = domaine.nb_faces_elem();
84 int nsom = domaine.nb_som_elem();
85 int nb_som_facette = domaine.type_elem()->nb_som_face();
86
87
88 // Pour le traitement de la convection on distingue les polyedres
89 // standard qui ne "voient" pas les conditions aux limites et les
90 // polyedres non standard qui ont au moins une face sur le bord.
91 // Un polyedre standard a n facettes sur lesquelles on applique le
92 // schema de convection.
93 // Pour un polyedre non standard qui porte des conditions aux limites
94 // de Dirichlet, une partie des facettes sont portees par les faces.
95 // En bref pour un polyedre le traitement de la convection depend
96 // du type (triangle, tetraedre ...) et du nombre de faces de Dirichlet.
97
98 double psc;
99 double flux;
100 int poly,face_adj,fa7,i,j,comp0,n_bord;
101 int num_face, rang ,itypcl;
102 int num10, num20, num_som;
103
104 int ncomp_ch_transporte;
105 if (transporte.nb_dim() == 1)
106 ncomp_ch_transporte=1;
107 else
108 ncomp_ch_transporte= transporte.dimension(1);
109
110 // MODIF SB su 10/09/03
111 // Pour les 3 elements suivants, il y a autant de sommets que de face
112 // constituant l'element geometrique
113 // PB avec les hexa, 8 sommets et 6 faces, donc l'utilisation du tableau
114 // face[i] ne fonctionne plus
115 // la methode retenue pour eviter de calculer la vitesse aux sommets sans
116 // les fonctions de forme n'est donc pas utilisable,
117 // pour l'hexa on n'a pas acces a la face.
118 // il existe le tableau Face=>sommets mais pas l'inverse.
119 // trop couteux et pour le moment on n'etend pas les porosites aux hexa
120
121 int istetra=0;
122 const Elem_VEF_base& type_elemvef= domaine_VEF.type_elem();
123 Nom nom_elem=type_elemvef.que_suis_je();
124 if ((nom_elem=="Tetra_VEF")||(nom_elem=="Tri_VEF"))
125 istetra=1;
126
127 IntVect face(nfac);
128 DoubleVect vs(dimension);
129 DoubleVect vc(dimension);
130 DoubleTab vsom(nsom,dimension);
131 DoubleVect cc(dimension);
132
133 // declaration pour le champ transporte
134
135 DoubleVect ts(ncomp_ch_transporte);
136 DoubleVect tc(ncomp_ch_transporte);
137 DoubleTab tsom(nsom,ncomp_ch_transporte);
138
139
140 // On remet a zero le tableau qui sert pour
141 // le calcul du pas de temps de stabilite
142 fluent_ = 0;
143
144 // Traitement particulier pour les faces de periodicite
145
146 int nb_faces_perio = 0;
147 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
148 {
149 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
150 if (sub_type(Periodique,la_cl.valeur()))
151 {
152 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
153 int num1 = le_bord.num_premiere_face();
154 int num2 = num1 + le_bord.nb_faces();
155 for (num_face=num1; num_face<num2; num_face++)
156 nb_faces_perio++;
157 }
158 }
159
160 DoubleTab tab;
161 if (ncomp_ch_transporte == 1)
162 tab.resize(nb_faces_perio);
163 else
164 tab.resize(nb_faces_perio,ncomp_ch_transporte);
165
166 nb_faces_perio=0;
167 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
168 {
169 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
170 if (sub_type(Periodique,la_cl.valeur()))
171 {
172 // const Periodique& la_cl_perio = ref_cast(Periodique, la_cl.valeur());
173 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
174 int num1 = le_bord.num_premiere_face();
175 int num2 = num1 + le_bord.nb_faces();
176 for (num_face=num1; num_face<num2; num_face++)
177 {
178 if (ncomp_ch_transporte == 1)
179 tab(nb_faces_perio) = resu(num_face);
180 else
181 for (int comp=0; comp<ncomp_ch_transporte; comp++)
182 tab(nb_faces_perio,comp) = resu(num_face,comp);
183 nb_faces_perio++;
184 }
185 }
186 }
187
188
189 // Les polyedres non standard sont ranges en 2 groupes dans le Domaine_VEF:
190 // - polyedres bords et joints
191 // - polyedres bords et non joints
192 // On traite les polyedres en suivant l'ordre dans lequel ils figurent
193 // dans le domaine
194
195 // boucle sur les polys
196 const IntTab& KEL=domaine_VEF.type_elem().KEL();
197 for (poly=0; poly<nb_elem_tot; poly++)
198 {
199
200 rang = rang_elem_non_std(poly);
201 if (rang==-1)
202 itypcl=0;
203 else
204 itypcl=domaine_Cl_VEF.type_elem_Cl(rang);
205
206 // calcul des numeros des faces du polyedre
207 for (face_adj=0; face_adj<nfac; face_adj++)
208 face[face_adj]= elem_faces(poly,face_adj);
209
210 for (j=0; j<dimension; j++)
211 {
212 vs[j] = la_vitesse.valeurs()(face[0],j)*porosite_face(face[0]);
213 for (i=1; i<nfac; i++)
214 vs[j]+= la_vitesse.valeurs()(face[i],j)*porosite_face(face[i]);
215 }
216 // int ncomp;
217 if (istetra==1)
218 {
219 for (j=0; j<nsom; j++)
220 {
221 for (int ncomp=0; ncomp<Objet_U::dimension; ncomp++)
222 vsom(j,ncomp) =vs[ncomp] - Objet_U::dimension*la_vitesse.valeurs()(face[j],ncomp)*porosite_face(face[j]);
223 }
224 }
225 else
226 {
227 // pour que cela soit valide avec les hexa
228 // On va utliser les fonctions de forme implementees dans la classe Champs_P1_impl ou Champs_Q1_impl
229 //int ncomp;
230 for (j=0; j<nsom; j++)
231 {
232 num_som = domaine.sommet_elem(poly,j);
233 for (int ncomp=0; ncomp<dimension; ncomp++)
234 {
235 vsom(j,ncomp) = la_vitesse.valeur_a_sommet_compo(num_som,poly,ncomp);
236 }
237 }
238 }
239
240 // calcul de vc
241 domaine_VEF.type_elem().calcul_vc(face,vc,vs,vsom,vitesse(),
242 itypcl,porosite_face);
243
244 // calcul du champ transporte aux sommets des polyedres ,tsom
245 if(ncomp_ch_transporte == 1)
246 {
247 ts[0]=transporte(face[0]);
248 for (i=1; i<nfac; i++)
249 ts[0]+= transporte(face[i]);
250
251 for (i=0; i<nsom; i++)
252 tsom(i,0) = ts[0] - dimension*transporte(face[i],0);
253 }
254 else
255 {
256 for (j=0; j<ncomp_ch_transporte; j++)
257 {
258 ts[j] = transporte(face[0],j);
259 for (i=1; i<nfac; i++)
260 ts[j]+= transporte(face[i],j);
261 }
262 for (i=0; i<nsom; i++)
263 for (j=0; j<ncomp_ch_transporte; j++)
264 tsom(i,j) = ts[j] - dimension*transporte(face[i],j);
265 }
266
267 // calcul du champ transporte au centre de gravite ,tc
268
269 for (j=0; j<ncomp_ch_transporte; j++)
270 tc[j] = ts[j]/nfac;
271
272
273 // Boucle sur les facettes du polyedre non standard:
274
275 for (fa7=0; fa7<nfa7; fa7++)
276 {
277 num10 = face[KEL(0,fa7)];
278 num20 = face[KEL(1,fa7)];
279 if (rang==-1)
280 for (i=0; i<dimension; i++)
281 cc[i] = facette_normales(poly,fa7,i);
282 else
283 for (i=0; i<dimension; i++)
284 cc[i] = normales_facettes_Cl(rang,fa7,i);
285
286 // On applique le schema de convection a chaque sommet de la facette
287
288 // On traite le ou les sommets qui sont aussi des sommets du polyedre
289
290 int isom;
291 for (i=0; i<nb_som_facette-1; i++)
292 {
293 isom = KEL(i+2,fa7);
294 psc =0;
295 for (j=0; j<dimension; j++)
296 psc+= vsom(isom,j)*cc[j];
297 psc /= nb_som_facette;
298
299 if(psc >= 0)
300 fluent_[num20] += psc;
301 else
302 fluent_[num10] -= psc;
303
304 // ecriture du flux
305 if (ncomp_ch_transporte == 1)
306 {
307 flux = tsom(isom,0)*psc;
308 resu(num10) -= flux;
309 resu(num20) += flux;
310 }
311 else
312 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
313 {
314 flux = tsom(isom,comp0)*psc;
315 resu(num10, comp0) -= flux;
316 resu(num20, comp0) += flux;
317 }
318 }
319
320
321 // On traite le sommet confondu avec le centre de gravite du polyedre
322
323 psc=0;
324 for (j=0; j<dimension; j++)
325 psc += vc[j]*cc[j];
326 psc /= nb_som_facette;
327
328 if(psc >= 0)
329 fluent_[num20] += psc;
330 else
331 fluent_[num10] -= psc;
332
333 // ecriture du flux
334
335 if (ncomp_ch_transporte == 1)
336 {
337 flux = tc[0]*psc;
338 resu(num10) -= flux;
339 resu(num20) += flux;
340 }
341 else
342 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
343 {
344 flux = tc[comp0]*psc;
345 resu(num10, comp0) -= flux;
346 resu(num20, comp0) += flux;
347 }
348 }
349
350 } // fin de la boucle
351
352 int voisine;
353 nb_faces_perio = 0;
354 double diff1,diff2;
355
356 // Dimensionnement du tableau des flux convectifs au bord du domaine
357 // de calcul
358 DoubleTab& flux_b = flux_bords_;
359 flux_b.resize(domaine_VEF.nb_faces_bord(),ncomp_ch_transporte);
360 flux_b = 0.;
361
362 // Boucle sur les bords pour traiter les conditions aux limites
363 // il y a prise en compte d'un terme de convection pour les
364 // conditions aux limites de Neumann_sortie_libre seulement
365
366 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
367 {
368
369 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
370
371 if (sub_type(Neumann_sortie_libre,la_cl.valeur()))
372 {
373 const Neumann_sortie_libre& la_sortie_libre = ref_cast(Neumann_sortie_libre,la_cl.valeur());
374 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
375 int num1 = le_bord.num_premiere_face();
376 int num2 = num1 + le_bord.nb_faces();
377 for (num_face=num1; num_face<num2; num_face++)
378 {
379 psc =0;
380 for (i=0; i<dimension; i++)
381 psc += la_vitesse.valeurs()(num_face,i)*face_normales(num_face,i)*porosite_face(num_face);
382 if (psc>0)
383 if (ncomp_ch_transporte == 1)
384 {
385 resu(num_face) -= psc*transporte(num_face);
386 flux_b(num_face,0) -= psc*transporte(num_face);
387 }
388 else
389 for (i=0; i<ncomp_ch_transporte; i++)
390 {
391 resu(num_face,i) -= psc*transporte(num_face,i);
392 flux_b(num_face,i) -= psc*transporte(num_face,i);
393 }
394 else
395 {
396 if (ncomp_ch_transporte == 1)
397 {
398 resu(num_face) -= psc*la_sortie_libre.val_ext(num_face-num1);
399 flux_b(num_face,0) -= psc*la_sortie_libre.val_ext(num_face-num1);
400 }
401 else
402 for (i=0; i<ncomp_ch_transporte; i++)
403 {
404 resu(num_face,i) -= psc*la_sortie_libre.val_ext(num_face-num1,i);
405 flux_b(num_face,i) -= psc*la_sortie_libre.val_ext(num_face-num1,i);
406 }
407 fluent_[num_face] -= psc;
408 }
409 }
410 }
411 else if (sub_type(Periodique,la_cl.valeur()))
412 {
413 const Periodique& la_cl_perio = ref_cast(Periodique,la_cl.valeur());
414 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
415 int num1 = le_bord.num_premiere_face();
416 int num2 = num1 + le_bord.nb_faces();
417 IntVect fait(le_bord.nb_faces());
418 fait = 0;
419 for (num_face=num1; num_face<num2; num_face++)
420 {
421 if (fait[num_face-num1] == 0)
422 {
423 voisine = la_cl_perio.face_associee(num_face-num1) + num1;
424
425 if (ncomp_ch_transporte == 1)
426 {
427 diff1 = resu(num_face)-tab(nb_faces_perio);
428 diff2 = resu(voisine)-tab(nb_faces_perio+voisine-num_face);
429 resu(voisine) += diff1;
430 resu(num_face) += diff2;
431 flux_b(voisine,0) += diff1;
432 flux_b(num_face,0) += diff2;
433 }
434 else
435 for (int comp=0; comp<ncomp_ch_transporte; comp++)
436 {
437 diff1 = resu(num_face,comp)-tab(nb_faces_perio,comp);
438 diff2 = resu(voisine,comp)-tab(nb_faces_perio+voisine-num_face,comp);
439 resu(voisine,comp) += diff1;
440 resu(num_face,comp) += diff2;
441 flux_b(voisine,comp) += diff1;
442 flux_b(num_face,comp) += diff2;
443 }
444
445 fait[num_face-num1]= 1;
446 fait[voisine-num1] = 1;
447 }
448 nb_faces_perio++;
449 }
450 }
451 }
452 modifier_flux(*this);
453 return resu;
454
455}
Classe Champ_Inc_base.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual double valeur_a_sommet_compo(int, int, int) const
renvoi la compo eme corrdonne des valeurs a l'element le_poly au sommet sommet
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
int type_elem_Cl(int i) const
DoubleTab & normales_facettes_Cl()
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_VEF
Definition Domaine_VEF.h:54
IntVect & rang_elem_non_std()
Definition Domaine_VEF.h:86
const Elem_VEF_base & type_elem() const
Definition Domaine_VEF.h:75
auto & facette_normales()
Definition Domaine_VEF.h:84
virtual double face_normales(int face, int comp) const
Definition Domaine_VF.h:47
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
int nb_faces_bord() const
renvoie le nombre de faces sur lesquelles sont appliquees les conditions limites :
Definition Domaine_VF.h:513
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
int nb_elem_tot() const
int nb_front_Cl() const
const Domaine & domaine() const
virtual void calcul_vc(const ArrOfInt &, ArrOfDouble &, const ArrOfDouble &, const DoubleTab &, const Champ_Inc_base &, int, const DoubleVect &) const =0
const IntTab & KEL() const
virtual int nb_facette() const =0
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual const Milieu_base & milieu() const =0
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
DoubleVect & porosite_face()
Definition Milieu_base.h:62
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
classe Neumann_sortie_libre Cette classe represente une frontiere ouverte sans vitesse imposee
double val_ext(int i) const override
Renvoie la valeur de la i-eme composante du champ impose a l'exterieur de la frontiere.
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
class Op_Conv_Centre_old_VEF_Face
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
void associer(const Domaine_dis_base &, const Domaine_Cl_dis_base &, const Champ_Inc_base &) override
class Op_Conv_VEF_base
const Champ_Inc_base & vitesse() const
void modifier_flux(const Operateur_base &) const
DoubleTab flux_bords_
classe Periodique Cette classe represente une condition aux limites periodique.
Definition Periodique.h:31
int face_associee(int i) const
Definition Periodique.h:35
Classe de base des flux de sortie.
Definition Sortie.h:52
int nb_dim() const
Definition TRUSTTab.h:199
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133