TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Terme_Source_Qdm_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 <Terme_Source_Qdm_VEF_Face.h>
17#include <Champ_Uniforme.h>
18#include <Domaine.h>
19
20#include <Domaine_VEF.h>
21#include <Domaine_Cl_VEF.h>
22#include <Periodique.h>
23#include <BilanQdmVEF.h>
24#include <Equation_base.h>
25#include <Schema_Temps_base.h>
26#include <Domaine_VEF.h>
27#include <Operateur.h>
28#include <Operateur_base.h>
29#include <VEF_discretisation.h>
30#include <Discretisation_base.h>
31
32extern double calculer_coef_som(int rang_elem, int dimension, int& nb_face_diri, int *indice_diri);
33Implemente_instanciable(Terme_Source_Qdm_VEF_Face,"Source_Qdm_VEF_P1NC",Source_base);
34
35
36
37//// printOn
38//
39
41{
42 return s << que_suis_je() ;
43}
44
45
46//// readOn
47//
48
50{
51 s >> la_source;
52 if (la_source->nb_comp() != dimension)
53 {
54 Cerr << "Error reading the source term of type " << que_suis_je() << finl;
55 Cerr << "the source field must have " << dimension << " components" << finl;
56 exit();
57 }
58 return s ;
59}
60
65
67 const Domaine_Cl_dis_base& domaine_Cl_dis)
68{
69 le_dom_VEF = ref_cast(Domaine_VEF, domaine_dis);
70 le_dom_Cl_VEF = ref_cast(Domaine_Cl_VEF, domaine_Cl_dis);
71}
72
73
74DoubleTab& Terme_Source_Qdm_VEF_Face::ajouter(DoubleTab& resu) const
75{
76 int nb_comp=resu.line_size();
77 const Domaine_VEF& domaine_VEF = le_dom_VEF.valeur();
78 const Domaine_Cl_VEF& domaine_Cl_VEF=le_dom_Cl_VEF.valeur();
79 const IntTab& elem_faces = domaine_VEF.elem_faces();
80 const IntTab& elem_sommets = domaine_VEF.domaine().les_elems();
81 const DoubleVect& volumes = domaine_VEF.volumes();
82 const DoubleTab& coord_sommets=domaine_VEF.domaine().les_sommets();
83 ArrOfDouble a0(dimension),a0a1(dimension),a0a2(dimension), a0a3(dimension);
84 int nb_elem_tot=domaine_VEF.nb_elem_tot();
85 double volume;
86 DoubleTab resu_sauv(resu);
87 resu = 0.;
88 const int nbpts = (dimension==2) ? 7 : 15;
89
90 const DoubleTab& face_normales = domaine_VEF.face_normales();
91 const IntTab& face_voisins = domaine_VEF.face_voisins();
92
93 // Fill Poids and coord_bary:
94
95 ArrOfDouble Poids(nbpts);
96 DoubleTab coord_bary(nbpts,dimension+1); // lambda_i of the points
97
98 double tiers=0.333333333333333;
99 if(dimension==2)
100 {
101 Poids[0]=0.225;
102 Poids[1]=Poids[2]=Poids[3]=0.125939180544827;
103 Poids[4]=Poids[5]=Poids[6]=0.132394152788506;
104
105 coord_bary(0,0)=coord_bary(0,1)=coord_bary(0,2)=tiers;
106
107 coord_bary(1,0)=0.797426985353087;
108 coord_bary(1,1)=coord_bary(1,2)=0.101286507323456;
109 coord_bary(2,1)=0.797426985353087;
110 coord_bary(2,0)=coord_bary(2,2)=0.101286507323456;
111 coord_bary(3,2)=0.797426985353087;
112 coord_bary(3,0)=coord_bary(3,1)=0.101286507323456;
113
114 coord_bary(4,0)=0.059715871789770;
115 coord_bary(4,1)=coord_bary(4,2)=0.470142064105115;
116 coord_bary(5,1)=0.059715871789770;
117 coord_bary(5,0)=coord_bary(5,2)=0.470142064105115;
118 coord_bary(6,2)=0.059715871789770;
119 coord_bary(6,0)=coord_bary(6,1)=0.470142064105115;
120 }
121 else if(dimension==3)
122 {
123 Poids[0]=0.030283678097089;
124 Poids[1]=Poids[2]=Poids[3]=Poids[4]=0.006026785714286;
125 Poids[5]=Poids[6]=Poids[7]=Poids[8]=0.011645249086029;
126 Poids[9]=Poids[10]=Poids[11]=
127 Poids[12]=Poids[13]=Poids[14]=0.010949141561386;
128 // So that the sum equals 1.
129 Poids*=6;
130
131 coord_bary(0,0)=coord_bary(0,1)=coord_bary(0,2)
132 =coord_bary(0,3)=0.250000000000000;
133
134 coord_bary(1,0)=0.;
135 coord_bary(1,1)=coord_bary(1,2)=coord_bary(1,3)=tiers;
136 coord_bary(2,1)=0.;
137 coord_bary(2,0)=coord_bary(2,2)=coord_bary(2,3)=tiers;
138 coord_bary(3,2)=0.;
139 coord_bary(3,0)=coord_bary(3,1)=coord_bary(3,3)=tiers;
140 coord_bary(4,3)=0.;
141 coord_bary(4,0)=coord_bary(4,1)=coord_bary(4,2)=tiers;
142
143
144 coord_bary(5,0)=0.727272727272727;
145 coord_bary(5,1)=coord_bary(5,2)=coord_bary(5,3)=0.090909090909091;
146 coord_bary(6,1)=0.727272727272727;
147 coord_bary(6,0)=coord_bary(6,2)=coord_bary(6,3)=0.090909090909091;
148 coord_bary(7,2)=0.727272727272727;
149 coord_bary(7,0)=coord_bary(7,1)=coord_bary(7,3)=0.090909090909091;
150 coord_bary(8,3)=0.727272727272727;
151 coord_bary(8,0)=coord_bary(8,1)=coord_bary(8,2)=0.090909090909091;
152
153 coord_bary(9,0)=coord_bary(9,1)=0.066550153573664;
154 coord_bary(9,2)=coord_bary(9,3)=0.433449846426336;
155
156 coord_bary(10,0)=coord_bary(10,2)=0.066550153573664;
157 coord_bary(10,1)=coord_bary(10,3)=0.433449846426336;
158
159 coord_bary(11,0)=coord_bary(11,3)=0.066550153573664;
160 coord_bary(11,1)=coord_bary(11,2)=0.433449846426336;
161
162 coord_bary(12,1)=coord_bary(12,2)=0.066550153573664;
163 coord_bary(12,0)=coord_bary(12,3)=0.433449846426336;
164
165 coord_bary(13,1)=coord_bary(13,3)=0.066550153573664;
166 coord_bary(13,0)=coord_bary(13,2)=0.433449846426336;
167
168 coord_bary(14,2)=coord_bary(14,3)=0.066550153573664;
169 coord_bary(14,0)=coord_bary(14,1)=0.433449846426336;
170 }
171 else
172 assert(0);
173 IntVect les_polygones(nbpts);
174 DoubleTab les_positions(nbpts, dimension);
175 DoubleTab valeurs_source(nbpts,dimension);
176 DoubleTab valeurs_Psi(nbpts,dimension);
177 ArrOfDouble somme(dimension);
178 int nb_face_diri=0;
179 int indice_diri[4];
180 int modif_traitement_diri=0;
181 if (sub_type(Domaine_VEF,domaine_VEF))
182 modif_traitement_diri=ref_cast(Domaine_VEF, domaine_VEF).get_modif_div_face_dirichlet();
183 for (int elem=0; elem<nb_elem_tot; elem++)
184 {
185 int rang_elem = (int)domaine_VEF.rang_elem_non_std()(elem);
186 int type_elem = rang_elem < 0 ? 0 : (int)domaine_Cl_VEF.type_elem_Cl(rang_elem);
187 if (modif_traitement_diri)
188 calculer_coef_som(type_elem,dimension, nb_face_diri, indice_diri);
189 volume=volumes(elem);
190 for (int i=0; i<nbpts; i++)
191 les_polygones(i)=elem;
192
193 //Fill the element change matrix:
194 const int som_glob = elem_sommets(elem,0);
195 for (int dim=0; dim<dimension; dim++)
196 a0[dim]=coord_sommets(som_glob,dim);
197
198 const int som_glob1 = elem_sommets(elem,1);
199 for (int dim=0; dim<dimension; dim++)
200 a0a1[dim]=coord_sommets(som_glob1,dim)-a0[dim];
201
202 const int som_glob2 = elem_sommets(elem,2);
203 for (int dim=0; dim<dimension; dim++)
204 a0a2[dim]=coord_sommets(som_glob2,dim)-a0[dim];
205
206 if(dimension == 3)
207 {
208 const int som_glob3 = elem_sommets(elem,3);
209 for (int dim=0; dim<dimension; dim++)
210 a0a3[dim]=coord_sommets(som_glob3,dim)-a0[dim];
211 }
212
213 //Fill les_positions:
214 if(dimension == 2)
215 {
216 for (int pt=0; pt<nbpts; pt++)
217 {
218 for (int dim=0; dim<dimension; dim++)
219 les_positions(pt,dim)=a0[dim]
220 +coord_bary(pt,1)* a0a1[dim]
221 +coord_bary(pt,2)* a0a2[dim];
222 }
223 }
224 else if(dimension == 3)
225 {
226 for (int pt=0; pt<nbpts; pt++)
227 {
228 for (int dim=0; dim<dimension; dim++)
229 les_positions(pt,dim)=a0[dim]
230 +coord_bary(pt,1)* a0a1[dim]
231 +coord_bary(pt,2)* a0a2[dim]
232 +coord_bary(pt,3)* a0a3[dim];
233 }
234 }
235 else
236 assert(0);
237
238 // Compute the source term at integration points:
239 la_source->valeur_aux_elems(les_positions,les_polygones,
240 valeurs_source);
241 bool RT = sub_type(VEF_discretisation, equation().discretisation()) && (ref_cast(VEF_discretisation, equation().discretisation()).get_alphaRT() );
242 if (!RT)
243 {
244 for(int face=0; face<=dimension; face++)
245 {
246 int num_face=elem_faces(elem, face);
247
248 // Compute Psi at integration points:
249
250 for (int pt=0; pt<nbpts; pt++)
251 {
252 for (int dim=0; dim<dimension; dim++)
253 valeurs_Psi(pt, dim)=1-dimension*coord_bary(pt,face);
254 }
255 // Integration!!
256
257 for (int pt=0; pt<nbpts; pt++)
258 {
259 for (int dim=0; dim<dimension; dim++)
260 {
261 double contrib=Poids[pt]*volume
262 *valeurs_source(pt,dim)*valeurs_Psi(pt,dim);
263 resu(num_face, dim)+=contrib;
264 somme[dim]+=contrib;
265
266 for (int fdiri=0; fdiri<nb_face_diri; fdiri++)
267 {
268 int indice=indice_diri[fdiri];
269 int facel = elem_faces(elem,indice);
270
271 if (num_face==facel)
272 {
273 resu(facel,dim)-=contrib;
274 double contrib2=contrib/(dimension+1-nb_face_diri);
275 for (int f2=0; f2<dimension+1; f2++)
276 {
277 // Cerr<<num_face<<" "<<elem<<" la "<< f2<<" "<<fdiri<<" "<<nb_face_diri<<" dim "<< dim<<finl;
278 int face2=elem_faces(elem,f2);
279 resu(face2,dim)+=contrib2;
280 }
281 }
282 }
283 }
284 }
285 }
286 }
287 else
288 {
289 // coordinates of the opposite local vertices
290 DoubleTab coord_sommets_loc(dimension+1,dimension);
291 for (int sommet=0; sommet<=dimension; sommet++)
292 {
293 for (int dim=0; dim<dimension; dim++) coord_sommets_loc(sommet,dim)=coord_sommets(elem_sommets(elem,sommet),dim);
294 }
295 for(int face=0; face<=dimension; face++)
296 {
297 int num_face=elem_faces(elem, face);
298 double contrib=0;
299 for (int pt=0; pt<nbpts; pt++)
300 {
301 double contrib_pt=0;
302 for (int dim=0; dim<dimension; dim++) contrib_pt+=(les_positions(pt,dim)-coord_sommets_loc(face,dim))*valeurs_source(pt,dim);
303 contrib+=contrib_pt*Poids[pt];
304 }
305 contrib/=dimension;
306 double signe=1.;
307 if(elem!=face_voisins(num_face,0))
308 signe=-1.;
309 for (int dim=0; dim<dimension; dim++)
310 {
311 double contrib_resu=signe*face_normales(num_face,dim)*contrib;
312 resu(num_face, dim)+=contrib_resu;
313 // Dirichlet boundary condition treatment
314 for (int fdiri=0; fdiri<nb_face_diri; fdiri++)
315 {
316 int indice=indice_diri[fdiri];
317 int facel = elem_faces(elem,indice);
318
319 if (num_face==facel)
320 {
321 resu(facel,dim)-=contrib_resu;
322 double contrib_resu2=contrib_resu/(dimension+1-nb_face_diri);
323 for (int f2=0; f2<dimension+1; f2++)
324 {
325 int face2=elem_faces(elem,f2);
326 resu(face2,dim)+=contrib_resu2;
327 }
328 }
329
330 }
331 }
332 }
333 }
334 }
335 {
336 // periodic correction
337 for (int n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
338 {
339 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
340 if (sub_type(Periodique,la_cl.valeur()))
341 {
342 const Periodique& la_cl_perio = ref_cast(Periodique,la_cl.valeur());
343 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
344 int nb_faces_bord=le_bord.nb_faces();
345 IntVect fait(nb_faces_bord);
346 fait = 0;
347 for (int ind_face=0; ind_face<nb_faces_bord; ind_face++)
348 {
349 if (fait(ind_face) == 0)
350 {
351 int ind_face_associee = la_cl_perio.face_associee(ind_face);
352 fait(ind_face) = 1;
353 fait(ind_face_associee) = 1;
354 int face = le_bord.num_face(ind_face);
355 int face_associee = le_bord.num_face(ind_face_associee);
356 for (int comp=0; comp<nb_comp; comp++)
357 {
358 resu(face, comp)=(resu(face_associee, comp)+=resu(face, comp));
359 }
360 }// if fait
361 }// for face
362 }// sub_type Perio
363 }
364 }
365 ArrOfDouble tab_bilan(nb_comp);
366 BilanQdmVEF::bilan_qdm(resu, domaine_Cl_VEF, tab_bilan);
367 /*
368 if (equation().schema_temps().limpr())
369 {
370 for (int comp=0; comp<nb_comp; comp++)
371 {
372 Cout << "Apres Source bilan["<<comp<<"]="<< bilan[comp]<<finl;
373 }
374 }*/
375
376 BilanQdmVEF::bilan_energie(resu, equation().inconnue().valeurs(), domaine_Cl_VEF, tab_bilan);
377 /*
378 if (equation().schema_temps().limpr())
379 {
380 for (int comp=0; comp<nb_comp; comp++)
381 {
382 Cout << "Apres Source bilan energie ["<<comp<<"]="<< bilan[comp]<<finl;
383 }
384 }*/
385 resu += resu_sauv;
386 return resu;
387}
388
389DoubleTab& Terme_Source_Qdm_VEF_Face::calculer(DoubleTab& resu) const
390{
391 resu = 0;
392 return ajouter(resu);
393}
394
396{
397 la_source->mettre_a_jour(temps);
398}
399
static void bilan_energie(const DoubleTab &dudt, const DoubleTab &u, const Domaine_Cl_VEF &domaine_Cl_VEF, ArrOfDouble &bilan)
static void bilan_qdm(const DoubleTab &dudt, const Domaine_Cl_VEF &domaine_Cl_VEF, ArrOfDouble &bilan)
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
DoubleTab_t & les_sommets()
Definition Domaine.h:113
IntTab_t & les_elems()
Definition Domaine.h:129
int type_elem_Cl(int i) const
class Domaine_Cl_dis_base Domaine_Cl_dis_base objects represent discretized boundary conditions
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
class Domaine_VEF
Definition Domaine_VEF.h:53
IntVect & rang_elem_non_std()
Definition Domaine_VEF.h:85
virtual double face_normales(int face, int comp) const
Definition Domaine_VF.h:47
double volumes(int i) const
Definition Domaine_VF.h:113
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
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
int nb_elem_tot() const
int nb_front_Cl() const
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Front_VF
Definition Front_VF.h:36
int nb_faces() const
Definition Front_VF.h:53
int num_face(const int) const
Definition Front_VF.h:68
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 Periodique This class represents a periodic boundary condition.
Definition Periodique.h:31
int face_associee(int i) const
Definition Periodique.h:35
class Probleme_base It is a Probleme_U that is not a coupling.
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
Source_base A Source_base object is a term appearing on the right-hand side of an.
Definition Source_base.h:42
int line_size() const
Definition TRUSTVect.tpp:67
class Terme_Source_Qdm_VEF_Face
DoubleTab & calculer(DoubleTab &) const override
void mettre_a_jour(double) override
DOES NOTHING - to override in derived classes.
void associer_domaines(const Domaine_dis_base &, const Domaine_Cl_dis_base &) override
void associer_pb(const Probleme_base &) override
DoubleTab & ajouter(DoubleTab &) const override