TrioCFD 1.9.8
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 << "Erreur a la lecture du terme source de type " << que_suis_je() << finl;
55 Cerr << "le champ source doit avoir " << dimension << " composantes" << 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 // On remplit les Poids et les coord_bary :
94
95 ArrOfDouble Poids(nbpts);
96 DoubleTab coord_bary(nbpts,dimension+1); // lambda_i des 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 // Pour que la somme soit 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 //On remplit la matrice de changement d'element :
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 //On remplit 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 // Calcul du terme source aux points d'integration :
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 // Calcul des Psi aux points d'integration :
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 // coordonnees des sommets locaux opposes
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 // Traitement CL de Dirichlet
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 // modif pour periodic
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)
classe Cond_lim Classe generique servant a representer n'importe quelle classe
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
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
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
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 face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
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
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
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
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 Probleme_base C'est un Probleme_U qui n'est pas un couplage.
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 Source_base Un objet Source_base est un terme apparaissant au second membre d'une
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