TrioCFD 1.9.9_beta
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 << "is not understood by "
49 << que_suis_je() << finl;
50 exit();
51 }
52 }
53
54 if (transportant_bar <0)
55 {
56 Cerr << "missing keyword transportant_bar" << finl;
57 exit();
58 }
59 if (transporte_bar <0)
60 {
61 Cerr << "missing keyword transporte_bar" << finl;
62 exit();
63 }
64 if (filtrer_resu <0)
65 {
66 Cerr << "missing keyword filtrer_resu" << finl;
67 exit();
68 }
69 if (antisym <0)
70 {
71 Cerr << "missing keyword antisym" << finl;
72 exit();
73 }
74 return s ;
75}
76
77//
78// Member functions of class Op_Conv_EF_VEF_P1NC
79//
80
81// convbis corresponds to the computation of -1*convection_term
82
83
84////////////////////////////////////////////////////////////////////
85//
86// Implementation of member functions
87//
88// of class 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 // CFL computation.
114 double psc;
115 // Reset to zero the array used for
116 // the computation of the stability time step
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 // either transporte=phi*transporte_ and vitesse_face=vitesse_
133 // or transporte=transporte_ and vitesse_face=phi*vitesse_
134 // depending on whether transport uses phi*u or 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 << "Adding boundary terms:" << 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 // Disable the computation and printing of u' energies......
270 // keeping the code in case it is needed later..
271 if (0)
272 {
273 Cerr << "small-scale filtering: " << 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 not implemented." << finl;
410 exit();
411}
412
414{
415 Cerr << "Op_Conv_EF_VEF_P1NC::contribue_au_second_membre not implemented." << finl;
416 exit();
417}
DoubleTab & valeurs() override
Returns the array of field values at the current time.
void filtrer_L2(DoubleTab &x) const
Definition Champ_P1NC.h:127
void filtrer_resu(DoubleTab &x) const
Definition Champ_P1NC.h:137
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
class Domaine_VEF
Definition Domaine_VEF.h:53
int nb_faces() const
Returns the total number of 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
Returns the index of the i-th face of element num_elem; the face numbering convention is.
Definition Domaine_VF.h:542
int premiere_face_int() const
A face is internal if and only if it separates two elements.
Definition Domaine_VF.h:463
int face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in 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
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
DoubleVect & porosite_face()
Definition Milieu_base.h:62
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
static int dimension
Definition Objet_U.h:94
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 Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
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
Defines whether psi is convected with phi*u or with u.
void modifier_flux(const Operateur_base &) const
class Periodique This class represents a periodic boundary condition.
Definition Periodique.h:31
int face_associee(int i) const
Definition Periodique.h:35
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
Base class for output streams.
Definition Sortie.h:52
Symetrie On symmetry faces, the following properties hold:
Definition Symetrie.h:37
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
int line_size() const
Definition TRUSTVect.tpp:67