TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Conv_EF_VEF_P1NC.cpp
1/****************************************************************************
2* Copyright (c) 2025, 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_EF_VEF_P1NC.h>
17#include <Champ_P1NC.h>
18
19#include <Porosites_champ.h>
20#include <Periodique.h>
21#include <Symetrie.h>
22
23Implemente_instanciable(Op_Conv_EF_VEF_P1NC,"Op_Conv_EF_VEF_P1NC",Op_Conv_VEF_base);
24
26{
27 return s << que_suis_je() ;
28}
29
31{
32 Motcle motlu;
33 for (int i=0; i<4; i++)
34 {
35 s >> motlu;
36 if (motlu=="defaut_bar")
37 break;
38 else if (motlu=="transportant_bar")
40 else if (motlu=="transporte_bar")
41 s >> transporte_bar;
42 else if (motlu=="filtrer_resu")
43 s >> filtrer_resu;
44 else if (motlu=="antisym")
45 s >> antisym;
46 else
47 {
48 Cerr << motlu << "n'est pas compris par "
49 << que_suis_je() << finl;
50 exit();
51 }
52 }
53
54 if (transportant_bar <0)
55 {
56 Cerr << "il manque le mot cle transportant_bar" << finl;
57 exit();
58 }
59 if (transporte_bar <0)
60 {
61 Cerr << "il manque le mot cle transporte_bar" << finl;
62 exit();
63 }
64 if (filtrer_resu <0)
65 {
66 Cerr << "il manque le mot cle filtrer_resu" << finl;
67 exit();
68 }
69 if (antisym <0)
70 {
71 Cerr << "il manque le mot cle antisym" << finl;
72 exit();
73 }
74 return s ;
75}
76
77//
78// Fonctions de la classe Op_Conv_EF_VEF_P1NC
79//
80
81// convbis correspond au calcul de -1*terme_convection
82
83
84////////////////////////////////////////////////////////////////////
85//
86// Implementation des fonctions
87//
88// de la classe Op_Conv_EF_VEF_P1NC
89//
90////////////////////////////////////////////////////////////////////
91
92
93DoubleTab& Op_Conv_EF_VEF_P1NC::ajouter(const DoubleTab& transporte_2,
94 DoubleTab& resu) const
95{
96 //Cerr << "Op_Conv_EF_VEF_P1NC::ajouter" << finl;
97 DoubleTab sauv(resu);
98 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
99 const Domaine_Cl_VEF& domaine_Cl_VEF = la_zcl_vef.valeur();
100 const Champ_P1NC& la_vitesse=ref_cast( Champ_P1NC, vitesse_.valeur());
101 const DoubleTab& velocity_tab=la_vitesse.valeurs();
102 const Champ_P1NC& ch=ref_cast(Champ_P1NC,mon_equation->inconnue());
103
104 const IntTab& elem_faces = domaine_VEF.elem_faces();
105 const IntTab& face_voisins = domaine_VEF.face_voisins();
106 const DoubleTab& face_normales=domaine_VEF.face_normales();
107 const DoubleVect& porosite_face = equation().milieu().porosite_face();
108 const int nb_elem_tot = domaine_VEF.nb_elem_tot();
109 const int nb_faces_elem=elem_faces.dimension(1);
110
111 assert(nb_faces_elem==(dimension+1));
112 {
113 // calcul de la CFL.
114 double psc;
115 // On remet a zero le tableau qui sert pour
116 // le calcul du pas de temps de stabilite
117 fluent_ = 0;
118
119 const int nb_faces = domaine_VEF.nb_faces();
120 for(int num_face=0; num_face<nb_faces; num_face++)
121 {
122 psc=0.;
123 for (int i=0; i<dimension; i++)
124 psc+=velocity_tab(num_face,i)*face_normales(num_face,i);
125 fluent_(num_face)=std::fabs(psc);
126 }
127 }
128 int marq=phi_u_transportant(equation());
129
130 DoubleTab transporte_;
131 DoubleTab vitesse_face_;
132 // soit on a transporte=phi*transporte_ et vitesse_face=vitesse_
133 // soit transporte=transporte_ et vitesse_face=phi*vitesse_
134 // cela d~pend si on transporte avec phi u ou avec u.
135 const DoubleTab& transporte=modif_par_porosite_si_flag(transporte_2,transporte_,!marq,porosite_face);
136 const DoubleTab& tab_vitesse=modif_par_porosite_si_flag(velocity_tab,vitesse_face_,marq,porosite_face);
137 // DoubleTab ubar(transporte);
138 // la_vitesse.filtrer_L2(ubar);
139 // DoubleTab uprime(transporte);
140 // uprime-=ubar;
141
142 DoubleTab uT(transporte);
143 DoubleTab u(tab_vitesse);
144
145 if (transporte_bar) ch.filtrer_L2(uT);
146 if (transportant_bar) la_vitesse.filtrer_L2(u);
147
148 const int nb_comp =resu.line_size();
149 DoubleTab grad_uT(nb_comp, dimension);
150 DoubleTab grad_phi(nb_faces_elem,dimension);
151 int elem, num_face, j, i, face;
152 double d_inv=(1./nb_faces_elem);
153
154 resu=0;
155 DoubleTab sigma(dimension, dimension);
156 DoubleTab contrib_elem(nb_faces_elem, nb_comp);
157 for (elem=0; elem<nb_elem_tot; elem++)
158 {
159 //for elem
160 sigma=0, contrib_elem=0, grad_uT=0., grad_phi=0.;
161 for(num_face=0; num_face<nb_faces_elem; num_face++)
162 {
163 //for num_face
164 face=elem_faces(elem, num_face);
165 double cc=1.;
166 if(face_voisins(face,0)!=elem)
167 cc*=-1;
168 for (i=0; i<dimension; i++)
169 {
170 grad_phi(num_face,i)=face_normales(face,i)*cc;
171 for (j=0; j<nb_comp; j++)
172 {
173 sigma(i,j)+=u(face,i)*uT(face,j);
174 grad_uT(j,i)+=uT(face,j)*grad_phi(num_face,i);
175 }
176 }
177 }
178
179 if(antisym==1)
180 {
181 for(num_face=0; num_face<nb_faces_elem; num_face++)
182 {
183 //for num_face
184 face=elem_faces(elem, num_face);
185 for (i=0; i<dimension; i++)
186 for (j=0; j<nb_comp; j++)
187 contrib_elem(num_face,j)-=0.5*d_inv*(u(face,i)*grad_uT(j,i)-sigma(i,j)*grad_phi(num_face,i));// Ui Uj,i Vj - Ui Vj,i Uj
188 }
189 }
190 else
191 {
192 for(num_face=0; num_face<nb_faces_elem; num_face++)
193 {
194 //for num_face
195 face=elem_faces(elem, num_face);
196 for (i=0; i<dimension; i++)
197 for (j=0; j<nb_comp; j++)
198 contrib_elem(num_face,j)-=d_inv*(u(face,i)*grad_uT(j, i));// Ui Uj,i Vj
199 }
200 }
201
202 for(num_face=0; num_face<nb_faces_elem; num_face++)
203 {
204 face=elem_faces(elem, num_face);
205 for (i=0; i<nb_comp; i++)
206 resu(face,i)+=contrib_elem(num_face,i);
207 }
208 }
209
210 for (int n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
211 {
212 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
213 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
214 int nb_faces_bord_tot=le_bord.nb_faces_tot();
215 int num10 = 0, num20 = le_bord.nb_faces_tot();
216
217 if (sub_type(Periodique,la_cl.valeur()))
218 {
219 const Periodique& la_cl_perio = ref_cast(Periodique,la_cl.valeur());
220 int face_associee;
221 IntVect fait(nb_faces_bord_tot);
222 fait = 0;
223
224 for (int ind_face=num10; ind_face<num20; ind_face++)
225 {
226 face = le_bord.num_face(ind_face);
227 if (fait(ind_face) == 0)
228 {
229 fait(ind_face) = 1;
230 face_associee=la_cl_perio.face_associee(ind_face);
231 fait(face_associee) = 1;
232 face_associee = le_bord.num_face(face_associee);
233
234 for (int comp=0; comp<nb_comp; comp++)
235 {
236 double som;
237 som=resu(face_associee,comp)+resu(face,comp);
238 resu(face,comp)=resu(face_associee,comp)=som;
239 }
240 }// if fait
241 }// for face
242
243 }// sub_type Perio
244
245 else if ((antisym==1) && (!sub_type(Symetrie,la_cl.valeur())) )
246 {
247 // Cerr << "Ajout des termes de bords :" << finl;
248 int num1 = le_bord.num_premiere_face();
249 int nb_faces=le_bord.nb_faces();
250 int num2 = num1 + nb_faces;
251
252 for (face=num1; face<num2; face++)
253 {
254 int comp;
255 double psc = 0;
256 for (comp=0; comp<nb_comp; comp++)
257 psc += face_normales(face,comp)*u(face, comp);
258 psc *=0.5;
259 for (comp=0; comp<nb_comp; comp++)
260 resu(face, comp)-=psc*uT(face, comp);
261
262 }
263 }
264 }// for nbord
265
266 if(filtrer_resu)
267 ch.filtrer_resu(resu);
268
269 // On desactive le calcul et l'impression des energies u'......
270 // on garde le codage au cas ou..
271 if (0)
272 {
273 Cerr << "filtrage petites echelles : " << finl;
274
275 DoubleTab ubar(transporte);
276 ch.filtrer_L2(ubar);
277 DoubleTab uprime(transporte);
278 uprime-=ubar;
279
280 const int nb_faces = domaine_VEF.nb_faces();
281 const DoubleVect& volumes_entrelaces=domaine_VEF.volumes_entrelaces();
282 int face2, k;
283 double psc=0., pscprim=0., ec=0., ecprime=0.;
284 int deb=domaine_VEF.premiere_face_int();
285 for(face2=deb; face2<nb_faces; face2++)
286 for(k=0; k< dimension; k++)
287 {
288 double v=volumes_entrelaces(face2);
289 double up, u2, r;
290 if(nb_comp>1)
291 {
292 up=uprime(face2,k);
293 uprime(face2,k)*=v;
294 u2=ubar(face2,k);
295 r=resu(face2,k);
296 }
297 else
298 {
299 up=uprime(face2);
300 uprime(face2)*=v;
301 u2=ubar(face2);
302 r=resu(face2);
303 }
304 pscprim+=r*up;
305 psc+=r*u2;
306 ec+=u2*u2*v;
307 ecprime+=up*up*v;
308 }
309
310
311
312 for (int n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
313 {
314 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
315 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
316 int num1 = le_bord.num_premiere_face();
317 int nb_faces_b=le_bord.nb_faces();
318 int num2 = num1 + nb_faces_b;
319 if (sub_type(Periodique,la_cl.valeur()))
320 {
321 const Periodique& la_cl_perio = ref_cast(Periodique,la_cl.valeur());
322 int face_associee;
323 IntVect fait(nb_faces_b);
324 fait = 0;
325
326 for (face2=num1; face2<num2; face2++)
327 {
328 if (fait(face2-num1) == 0)
329 {
330 fait(face2-num1) = 1;
331 face_associee=la_cl_perio.face_associee(face2-num1);
332 fait(face_associee) = 1;
333 face_associee+=num1;
334 double v=volumes_entrelaces(face2);
335 double up, u2, r;
336 for(k=0; k< dimension; k++)
337 {
338 if(nb_comp>1)
339 {
340 up=(uprime(face2,k));
341 uprime(face2,k)*=v;
342 uprime(face_associee,k)=uprime(face2,k);
343 u2=ubar(face2,k);
344 r=resu(face2,k);
345 }
346 else
347 {
348 up=uprime(face2);
349 uprime(face2)*=v;
350 uprime(face_associee)=uprime(face2);
351 u2=ubar(face2);
352 r=resu(face2);
353 }
354 pscprim+=r*up;
355 psc+=r*u2;
356 ec+=u2*u2*v;
357 ecprime+=up*up*v;
358 }
359 }
360 }
361 }
362 else
363 {
364 for (face2=num1; face2<num2; face2++)
365 {
366 double v=volumes_entrelaces(face2);
367 double up, u2, r;
368 for(k=0; k< dimension; k++)
369 {
370 if(nb_comp>1)
371 {
372 up=(uprime(face2,k));
373 uprime(face2,k)*=v;
374 u2=ubar(face2,k);
375 r=resu(face2,k);
376 }
377 else
378 {
379 up=uprime(face2);
380 uprime(face2)*=v;
381 u2=ubar(face2);
382 r=resu(face2);
383 }
384 pscprim+=r*up;
385 psc+=r*u2;
386 ec+=u2*u2*v;
387 ecprime+=up*up*v;
388 }
389 }
390 }
391 }
392 Cerr << "(u,u) "<< ec <<finl;
393 Cerr << "(u',u') "<< ecprime <<finl;
394 Cerr << "(u grad u ,u) "<< psc <<finl;
395 Cerr << "(u grad u ,u') "<< pscprim <<finl;
396 double pourcent=0;
397 if (!est_egal(ec,0))
398 pourcent=100*sqrt(ecprime/ec);
399 Cerr << "||u'||/||u|| : " << pourcent << " %" << finl;
400 }
401 resu+=sauv;
402 modifier_flux(*this);
403 return resu;
404}
405
406
407void Op_Conv_EF_VEF_P1NC::ajouter_contribution(const DoubleTab& transporte, Matrice_Morse& matrice ) const
408{
409 Cerr << "Op_Conv_EF_VEF_P1NC::ajouter_contribution non code." << finl;
410 exit();
411}
412
414{
415 Cerr << "Op_Conv_EF_VEF_P1NC::contribue_au_second_membre non code." << finl;
416 exit();
417}
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
void filtrer_L2(DoubleTab &x) const
Definition Champ_P1NC.h:127
void filtrer_resu(DoubleTab &x) const
Definition Champ_P1NC.h:137
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
class Domaine_VEF
Definition Domaine_VEF.h:54
int nb_faces() const
renvoie le nombre global de faces.
Definition Domaine_VF.h:471
DoubleVect & volumes_entrelaces()
Definition Domaine_VF.h:99
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 premiere_face_int() const
une face est interne ssi elle separe deux elements.
Definition Domaine_VF.h:463
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
int nb_elem_tot() const
int nb_front_Cl() const
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
int nb_faces_tot() const
Definition Front_VF.h:58
int num_face(const int) const
Definition Front_VF.h:68
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
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
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_EF_VEF_P1NC
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
void ajouter_contribution(const DoubleTab &, Matrice_Morse &) const
void contribue_au_second_membre(DoubleTab &) const
class Op_Conv_VEF_base
int phi_u_transportant(const Equation_base &eq) const
definit si l'on convecte psi avec phi*u ou avec u
void modifier_flux(const Operateur_base &) const
classe Periodique Cette classe represente une condition aux limites periodique.
Definition Periodique.h:31
int face_associee(int i) const
Definition Periodique.h:35
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
classe Symetrie Sur les faces de symetrie on a les proprietes suivantes:
Definition Symetrie.h:37
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
int line_size() const
Definition TRUSTVect.tpp:67