TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Conv_RT_VEF_Face.cpp
1/****************************************************************************
2* Copyright (c) 2022, 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_RT_VEF_Face.h>
17#include <Champ_P1NC.h>
18#include <Porosites_champ.h>
19#include <Perf_counters.h>
20#include <Domaine_VEF.h>
21#include <CL_Types_include.h>
22
23extern double calculer_coef_som(int rang_elem, int dimension, int& nb_face_diri, int *indice_diri);
24Implemente_instanciable_sans_constructeur(Op_Conv_RT_VEF_Face,"Op_Conv_RT_VEF_P1NC",Op_Conv_VEF_Face);
25// XD convection_RT convection_deriv RT NO_BRACE Keyword to use RT projection for P1NCP0RT discretization
26
27//// printOn
28//
30{
31 return s << que_suis_je() ;
32}
33
34//// readOn
35//
37{
38 ordre_=1;
39 return s ;
40}
41
42//
43// Fonctions de la classe Op_Conv_VEF_Face
44//
45////////////////////////////////////////////////////////////////////
46//
47// Implementation des fonctions
48//
49// de la classe Op_Conv_VEF_Face
50//
51////////////////////////////////////////////////////////////////////
52
53
54
55
56DoubleTab& Op_Conv_RT_VEF_Face::ajouter(const DoubleTab& transporte,
57 DoubleTab& resu) const
58{
59 const Domaine_Cl_VEF& domaine_Cl_VEF = la_zcl_vef.valeur();
60 const Domaine_VEF& domaine_VEF = ref_cast(Domaine_VEF, le_dom_vef.valeur());
61 const Champ_Inc_base& la_vitesse=vitesse();
62 const DoubleTab& vitesse_face_absolue=la_vitesse.valeurs();
63 //DoubleTab transporte_face_;
64 //DoubleTab vitesse_face_;
65
66 const IntTab& elem_faces = domaine_VEF.elem_faces();
67 const Domaine& domaine = domaine_VEF.domaine();
68 const int nb_elem_tot = domaine_VEF.nb_elem_tot();
69 const IntTab& face_voisins = domaine_VEF.face_voisins();
70 const IntTab& elem_sommets = domaine.les_elems();
71 const DoubleTab& coord_sommets=domaine.les_sommets();
72
73 // Permet d'avoir un flux_bord coherent avec les CLs (mais parfois diverge?)
74 // Active uniquement pour ordre 3
75 //
76
77 {
78 const DoubleVect& volumes = domaine_VEF.volumes();
79 const DoubleTab& face_normales = domaine_VEF.face_normales();
80 double volume;
81 // Cout<<"Op_Conv_RT_VEF_Face::ajouter RT\n";
82 // Traitement des CL de Dirichlet
83 int nb_face_diri=0;
84 int indice_diri[4];
85 int modif_traitement_diri=0;
86 if (sub_type(Domaine_VEF,domaine_VEF))
87 modif_traitement_diri=ref_cast(Domaine_VEF,domaine_VEF).get_modif_div_face_dirichlet();
88 int elem,i,j,alfa,dim;
89 i=0;
90 if (dimension==2)
91 {
92 for (elem=0; elem<nb_elem_tot; elem++)
93 {
94 DoubleTab coordSommet(dimension+1,dimension);
95 for (i=0; i<=dimension; i++)
96 {
97 int numSom=elem_sommets(elem, i);
98 for (dim=0; dim<dimension; dim++) coordSommet(i,dim)=coord_sommets(numSom,dim);
99 }
100 if (modif_traitement_diri)
101 {
102 int rang_elem = (int)domaine_VEF.rang_elem_non_std()(elem);
103 int type_elem = rang_elem < 0 ? 0 : domaine_Cl_VEF.type_elem_Cl(rang_elem);
104 calculer_coef_som(type_elem, dimension, nb_face_diri, indice_diri);
105 }
106 volume=volumes(elem);
107 double invVol = 1./(12*volume);
108 double invVol2 = invVol/volume;
109 // somme (vitesse_dir) fois (face normale_dir)
110 DoubleTab FacesNormales(dimension+1,dimension);
111 DoubleVect vitFaceNormale(dimension+1);
112 for (j=0; j<=dimension; j++)
113 {
114 int num_face=elem_faces(elem, j);
115 for (dim=0; dim<dimension; dim++) FacesNormales(j,dim)=face_normales(num_face,dim);
116 if (elem!=face_voisins(num_face,0))
117 {
118 for (dim=0; dim<dimension; dim++) FacesNormales(j,dim)=-FacesNormales(j,dim);
119 }
120 vitFaceNormale(j)=0.;
121 for (dim=0; dim<dimension; dim++)
122 vitFaceNormale(j)+=vitesse_face_absolue(num_face,dim)*FacesNormales(j,dim);
123 }
124 // Calculer le rot de la vitesse dans T
125 double rotVit=0.;
126 for (j=0; j<=dimension; j++)
127 {
128 int num_face=elem_faces(elem, j);
129 rotVit+=vitesse_face_absolue(num_face,1)*FacesNormales(j,0)-vitesse_face_absolue(num_face,0)*FacesNormales(j,1);
130 }
131 rotVit*=invVol2;
132 DoubleTab FiFj(dimension+1,dimension+1);
133 for (i=0; i<=dimension; i++)
134 {
135 for (j=i+1; j<=dimension; j++)
136 {
137 FiFj(i,j) = FacesNormales(j,0)*FacesNormales(i,1)-FacesNormales(j,1)*FacesNormales(i,0);
138 FiFj(j,i) =-FiFj(i,j);
139 }
140 FiFj(i,i)=0.;
141 }
142 DoubleVect resu_face(dimension+1);
143 for (i=0; i<=dimension; i++)
144 {
145 resu_face(i)=0;
146 for (j=0; j<=dimension; j++)
147 {
148 if (i!=j) resu_face(i) += vitFaceNormale(j)*FiFj(j,i);
149 }
150 }
151 for (i=0; i<=dimension; i++)
152 {
153 int num_face=elem_faces(elem, i);
154 // Code modifie pour prise en compte CL de Dirichlet
155 for (dim=0; dim<dimension; dim++)
156 {
157 double contrib_resu=rotVit*FacesNormales(i,dim)*resu_face(i);
158 resu(num_face, dim)+=contrib_resu;
159 // Traitement CL de Dirichlet
160 for (int fdiri=0; fdiri<nb_face_diri; fdiri++)
161 {
162 int indice=indice_diri[fdiri];
163 int facel = elem_faces(elem,indice);
164 if (num_face==facel)
165 {
166 resu(facel,dim)-=contrib_resu;
167 double contrib_resu2=contrib_resu/(dimension+1-nb_face_diri);
168 for (int f2=0; f2<dimension+1; f2++)
169 {
170 // Cerr<<num_face_i<<" "<<elem<<" la "<< f2<<" "<<fdiri<<" "<<nb_face_diri<<" dim "<< dim <<finl;
171 int face2=elem_faces(elem,f2);
172 resu(face2,dim)+=contrib_resu2;
173 }
174 }
175 }
176 }
177
178 }
179 }
180 }
181 else if (dimension==3)
182 {
183 for ( elem=0; elem<nb_elem_tot; elem++)
184 {
185 DoubleTab coordSommet(dimension+1,dimension);
186 for (i=0; i<=dimension; i++)
187 {
188 int numSom=elem_sommets(elem, i);
189 for (dim=0; dim<dimension; dim++) coordSommet(i,dim)=coord_sommets(numSom,dim);
190 }
191 // Calculer le rot de la vitesse dans elem
192 DoubleVect rotVit(dimension);
193 // Calculer rotVit.FiFj
194 DoubleTab rotVitFiFj(dimension+1,dimension+1);
195 DoubleTab FacesNormales(dimension+1,dimension);
196 DoubleVect vitFaceNormale(dimension+1);
197 if (modif_traitement_diri)
198 {
199 int rang_elem = domaine_VEF.rang_elem_non_std()(elem);
200 int type_elem = rang_elem < 0 ? 0 : domaine_Cl_VEF.type_elem_Cl(rang_elem);
201 calculer_coef_som(type_elem, dimension, nb_face_diri, indice_diri);
202 }
203 volume=volumes(elem);
204 for (dim=0; dim<dimension; dim++) rotVit(dim)=0.;
205 for (i=0; i<=dimension; i++)
206 {
207 int num_face=elem_faces(elem, i);
208 for (dim=0; dim<dimension; dim++)
209 FacesNormales(i,dim)=face_normales(num_face,dim);
210 if (elem==face_voisins(num_face,0))
211 {
212 for (dim=0; dim<dimension; dim++)
213 FacesNormales(i,dim)=-FacesNormales(i,dim);
214 }
215 //
216 rotVit(0)+=vitesse_face_absolue(num_face,2)*FacesNormales(i,1)-vitesse_face_absolue(num_face,1)*FacesNormales(i,2);
217 rotVit(1)+=vitesse_face_absolue(num_face,0)*FacesNormales(i,2)-vitesse_face_absolue(num_face,2)*FacesNormales(i,0);
218 rotVit(2)+=vitesse_face_absolue(num_face,1)*FacesNormales(i,0)-vitesse_face_absolue(num_face,0)*FacesNormales(i,1);
219 for (j=0; j<=dimension; j++) rotVitFiFj(i,j)=0.;
220 vitFaceNormale(i)=0.;
221 for (dim=0; dim<dimension; dim++) vitFaceNormale(i)+=vitesse_face_absolue(num_face,dim)*FacesNormales(i,dim);
222
223 } // end_for (i=0; i<=dimension; i++)
224 double rotVol=1./(18.*volume*volume);
225 for (dim=0; dim<dimension; dim++) rotVit(dim)*=rotVol;
226 // remplissage de rot u.SimoinsSj
227
228 for (dim=0; dim<dimension; dim++)
229 {
230 rotVitFiFj(0,1)+=rotVit(dim)*(FacesNormales(2,dim)-FacesNormales(3,dim));
231 rotVitFiFj(0,2)+=rotVit(dim)*(FacesNormales(3,dim)-FacesNormales(1,dim));
232 rotVitFiFj(0,3)+=rotVit(dim)*(FacesNormales(1,dim)-FacesNormales(2,dim));
233 rotVitFiFj(1,2)+=rotVit(dim)*(FacesNormales(0,dim)-FacesNormales(3,dim));
234 rotVitFiFj(1,3)+=rotVit(dim)*(FacesNormales(2,dim)-FacesNormales(0,dim));
235 rotVitFiFj(2,3)+=rotVit(dim)*(FacesNormales(0,dim)-FacesNormales(1,dim));
236 }
237 for (i=0; i<=dimension; i++)
238 {
239 for (j=i+1; j<=dimension; j++) rotVitFiFj(j,i)=-rotVitFiFj(i,j);
240 }
241 DoubleVect resu_face(dimension+1);
242 for (i=0; i<=dimension; i++)
243 {
244 resu_face(i)=0.;
245 for (j=0; j<=dimension; j++)
246 {
247 if (i!=j) resu_face(i)+=vitFaceNormale(j)*rotVitFiFj(i,j);
248 }
249 }
250 for (i=0; i<=dimension; i++)
251 {
252 int num_face=elem_faces(elem,i);
253 for (alfa=0; alfa<dimension; alfa++)
254 {
255 double contrib=resu_face(i)*FacesNormales(i,alfa);
256 resu(num_face,alfa)+=contrib;
257 // Traitement CL de Dirichlet
258 for (int fdiri=0; fdiri<nb_face_diri; fdiri++)
259 {
260 int indice=indice_diri[fdiri];
261 int facel = elem_faces(elem,indice);
262 if (num_face==facel)
263 {
264 resu(num_face,alfa)-=contrib;
265 double contrib2=contrib/(dimension+1-nb_face_diri);
266 for (int f2=0; f2<dimension+1; f2++)
267 {
268 // Cerr<<num_face_i<<" "<<elem<<" la "<< f2<<" "<<fdiri<<" "<<nb_face_diri<<" dim "<< dim <<finl;
269 int face2=elem_faces(elem,f2);
270 resu(face2,alfa)+=contrib2;
271 } // end_for (int f2=0; f2<dimension+1; f2++)
272 } // end_if (num_face_i==facel)
273 } // end_for (int fdiri=0; fdiri<nb_face_diri; fdiri++)
274
275 } // end_for (dim=0; dim<dimension;dim++)
276 } // end_for (i=0;i<=dimension;i++)
277 } // end_for (elem=0; elem<nb_elem_tot; elem++)
278 } // end_if (dim==3)
279 } // end_if (type_op==RT)
280 modifier_flux(*this);
281 return resu;
282}
283
284void Op_Conv_RT_VEF_Face::ajouter_contribution(const DoubleTab& transporte, Matrice_Morse& matrice ) const
285{
287 const Domaine_Cl_VEF& domaine_Cl_VEF = la_zcl_vef.valeur();
288 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
289 const Champ_Inc_base& la_vitesse=vitesse();
290 const DoubleTab& vitesse_face_absolue=la_vitesse.valeurs();
291 const IntTab& elem_faces = domaine_VEF.elem_faces();
292 const DoubleTab& face_normales = domaine_VEF.face_normales();
293 const Domaine& domaine = domaine_VEF.domaine();
294 const int nb_elem_tot = domaine_VEF.nb_elem_tot();
295 const DoubleVect& porosite_face = equation().milieu().porosite_face();
296
297 //int nfac = domaine.nb_faces_elem();
298 //int nsom = domaine.nb_som_elem();
299 const IntTab& elem_sommets = domaine.les_elems();
300 //const DoubleTab& coord_sommets=domaine.domaine().les_sommets();
301 // Pour le traitement de la convection on distingue les polyedres
302 // standard qui ne "voient" pas les conditions aux limites et les
303 // polyedres non standard qui ont au moins une face sur le bord.
304 // Un polyedre standard a n facettes sur lesquelles on applique le
305 // schema de convection.
306 // Pour un polyedre non standard qui porte des conditions aux limites
307 // de Dirichlet, une partie des facettes sont portees par les faces.
308 // En bref pour un polyedre le traitement de la convection depend
309 // du type (triangle, tetraedre ...) et du nombre de faces de Dirichlet.
310
311 double psc;
312 //DoubleTab pscl=0;
313 int i,j,n_bord;
314 int num_face;
315 int ncomp_ch_transporte;
316 if (transporte.nb_dim() == 1)
317 ncomp_ch_transporte=1;
318 else
319 ncomp_ch_transporte= transporte.dimension(1);
320
321
322 int marq=phi_u_transportant(equation());
323
324 DoubleTab vitesse_face_;
325 // soit on a transporte=phi*transporte_ et vitesse_face=vitesse_
326 // soit transporte=transporte_ et vitesse_face=phi*vitesse_
327 // cela depend si on transporte avec phi u ou avec u.
328 const DoubleTab& vitesse_face=modif_par_porosite_si_flag(vitesse_face_absolue,vitesse_face_,marq,porosite_face);
329 //ArrOfInt face(nfac);
330 //ArrOfDouble vs(dimension);
331 //ArrOfDouble vc(dimension);
332 //DoubleTab vsom(nsom,dimension);
333 //ArrOfDouble cc(dimension);
334 //const Elem_VEF_base& type_elemvef= domaine_VEF.type_elem().valeur();
335
336 //Nom nom_elem=type_elemvef.que_suis_je();
337
338
339
340 // Les polyedres non standard sont ranges en 2 groupes dans le Domaine_VEF:
341 // - polyedres bords et joints
342 // - polyedres bords et non joints
343 // On traite les polyedres en suivant l'ordre dans lequel ils figurent
344 // dans le domaine
345
346 // boucle sur les polys
347 int phi_u_transportant_yes=phi_u_transportant(equation());
348
349 {
350 Cout<<"Op_Conv_RT_VEF_Face::ajouter_contribution RT\n";
351 const DoubleVect& volumes = domaine_VEF.volumes();
352 const IntTab& face_voisins = domaine_VEF.face_voisins();
353 const DoubleTab& coord_sommets=domaine_VEF.domaine().les_sommets();
354 double volume=0.;
355 int dim,elem,alfa,beta,k;
356 if (dimension==2)
357 {
358 for (elem=0; elem<nb_elem_tot; elem++)
359 {
360 // Orientation des triangles
361 DoubleTab coordSommet(dimension+1,dimension);
362 for (i=0; i<=dimension; i++)
363 {
364 int numSom=elem_sommets(elem, i);
365 for (dim=0; dim<dimension; dim++) coordSommet(i,dim)=coord_sommets(numSom,dim);
366 }
367#ifdef DEBUG
368 double det=coordSommet(0,0)*(coordSommet(1,1)-coordSommet(2,1));
369 det-=coordSommet(1,0)*(coordSommet(0,1)-coordSommet(2,1));
370 det+=coordSommet(2,0)*(coordSommet(0,1)-coordSommet(1,1));
371 if (det<0)
372 {
373 // Changer le sens des sommets du triangle
374 Cout<<"Changer sens triangle " << elem << "\n";
375 for (dim=0; dim<dimension; dim++)
376 {
377 double temp=coordSommet(1,dim);
378 coordSommet(1,dim)=coordSommet(2,dim);
379 coordSommet(2,dim)=temp;
380 }
381 }
382#endif
383 DoubleTab FacesNormales(dimension+1,dimension);
384 DoubleVect vitFaceNormale(dimension+1);
385 for (j=0; j<=dimension; j++)
386 {
387 num_face=elem_faces(elem, j);
388 for (dim=0; dim<dimension; dim++) FacesNormales(j,dim)=face_normales(num_face,dim);
389 if (elem!=face_voisins(num_face,0))
390 {
391 for (dim=0; dim<dimension; dim++) FacesNormales(j,dim)=-FacesNormales(j,dim);
392 }
393 vitFaceNormale(j)=0.;
394 for (dim=0; dim<dimension; dim++) vitFaceNormale(j)+=vitesse_face_absolue(num_face,dim)*FacesNormales(j,dim);
395 }
396 DoubleTab FiaFib(dimension+1,dimension,dimension+1,dimension);
397
398 for (i=0; i<=dimension; i++)
399 {
400 for (alfa=0; alfa<dimension; alfa++)
401 {
402 for (j=i+1; j<=dimension; j++)
403 {
404 for (beta=0; beta<dimension; beta++)
405 {
406 FiaFib(i,alfa,j,beta)=FacesNormales(i,alfa)*FacesNormales(j,beta);
407 FiaFib(j,beta,i,beta)=FiaFib(i,alfa,j,beta);
408 }
409 }
410 }
411 }
412 DoubleTab Fij(dimension+1,dimension+1);
413 volume=volumes(elem);
414 double invVol=1./(12*volume);
415 double invVolvol=invVol/volume;
416 for (i=0; i<=dimension; i++)
417 {
418 for (j=i+1; j<=dimension; j++)
419 {
420 Fij(i,j)= FiaFib(i,0,j,1)-FiaFib(i,1,j,0);
421 Fij(j,i)=-Fij(i,j);
422 } // end_for (j=i+1; j<=dimension; j++)
423 Fij(i,i)=0.;
424 } // end_for (i=0; i<=dimension; i++)
425 // calcul qui ne depend que de i
426 DoubleVect vitFaceNormaleFij(dimension+1);
427 for (i=0; i<=dimension; i++)
428 {
429 vitFaceNormaleFij(i)=0.;
430 for (k=0; k<=dimension; k++)
431 {
432 if (k!=i) vitFaceNormaleFij(i)+=vitFaceNormale(k)*Fij(k,i);
433 }
434 vitFaceNormaleFij(i)*=invVolvol;
435 }
436
437 for (i=0; i<=dimension; i++)
438 {
439 int num_face_i=elem_faces(elem, i);
440 int num_i = num_face_i*dimension;
441 for (j=i; j<=dimension; j++)
442 {
443 int num_face_j=elem_faces(elem, j);
444 int num_j = num_face_j*dimension;
445
446 matrice(num_i,num_j) -= FiaFib(i,0,j,0)*vitFaceNormaleFij(i);
447 matrice(num_i,num_j+1) += FiaFib(i,0,j,1)*vitFaceNormaleFij(i);
448 matrice(num_i+1,num_j) += FiaFib(i,1,j,0)*vitFaceNormaleFij(i);
449 matrice(num_i+1,num_j+1) -= FiaFib(i,1,j,1)*vitFaceNormaleFij(i);
450 if (i!=j)
451 {
452 matrice(num_j,num_i) -= FiaFib(j,0,i,0)*vitFaceNormaleFij(j);
453 matrice(num_j,num_i+1) += FiaFib(j,0,i,1)*vitFaceNormaleFij(j);
454 matrice(num_j+1,num_i) += FiaFib(j,1,i,0)*vitFaceNormaleFij(j);
455 matrice(num_j+1,num_i+1) -= FiaFib(j,1,i,1)*vitFaceNormaleFij(j);
456 }
457 }
458 }
459 {
460 DoubleTab resu_j(dimension+1,dimension);
461 // NB: partie de code dupliquee ...
462 DoubleTab SiMj(dimension+1,dimension+1,dimension);
463 DoubleTab demi_coordSommet(dimension+1,dimension);
464 for (i=0; i<=dimension; i++)
465 {
466 for (dim=0; dim<dimension; dim++)
467 {
468 demi_coordSommet(i,dim)=0.5*coordSommet(i,dim);
469 SiMj(i,i,dim) = -coordSommet(i,dim);
470 }
471 }
472 for (dim=0; dim<dimension; dim++)
473 {
474 SiMj(0,1,dim) = demi_coordSommet(2,dim)-demi_coordSommet(0,dim);
475 SiMj(2,1,dim) = -SiMj(0,1,dim);
476 SiMj(0,2,dim) = demi_coordSommet(1,dim)-demi_coordSommet(0,dim);
477 SiMj(1,2,dim) = -SiMj(0,2,dim);
478 SiMj(1,0,dim) = demi_coordSommet(2,dim)-demi_coordSommet(1,dim);
479 SiMj(2,0,dim) = -SiMj(1,0,dim);
480 SiMj(0,0,dim) += demi_coordSommet(2,dim)+demi_coordSommet(1,dim);
481 SiMj(1,1,dim) += demi_coordSommet(2,dim)+demi_coordSommet(0,dim);
482 SiMj(2,2,dim) += demi_coordSommet(0,dim)+demi_coordSommet(1,dim);
483
484 }
485 //
486 for (j=0; j<=dimension; j++)
487 {
488 for (beta=0; beta<dimension; beta++)
489 resu_j(j,beta)=0.;
490 for (k=0; k<=dimension; k++)
491 {
492 for (dim=0; dim<dimension; dim++) resu_j(j,dim)+=vitFaceNormale(k)*SiMj(k,j,dim);
493 }
494 for (dim=0; dim<dimension; dim++) resu_j(j,dim)*=invVol;
495 }
496 for (i=0; i<=dimension; i++)
497 {
498 int num_face_i=elem_faces(elem, i);
499 int num_i = num_face_i*dimension;
500 for (alfa=0; alfa<dimension; alfa++)
501 {
502 for (j=i+1; j<=dimension; j++)
503 {
504 int num_face_j=elem_faces(elem, j);
505 int num_j = num_face_j*dimension;
506 for (beta=0; beta<dimension; beta++)
507 {
508 matrice(num_i,num_j)-= FacesNormales(i,alfa)*resu_j(j,beta);
509 matrice(num_j,num_i)-= FacesNormales(j,beta)*resu_j(i,alfa);
510 num_j++;
511 }
512 }
513 num_i++;
514 }
515 }
516 }
517 } // end_for (elem=0; elem<nb_elem_tot; elem++)
518 }
519 else if (dimension==3)
520 {
521 for (elem=0; elem<nb_elem_tot; elem++)
522 {
523 // Orientation des tetra
524 DoubleTab coordSommet(dimension+1,dimension);
525 for (i=0; i<=dimension; i++)
526 {
527 int numSom=elem_sommets(elem, i);
528 for (dim=0; dim<dimension; dim++) coordSommet(i,dim)=coord_sommets(numSom,dim);
529 }
530
531#ifdef DEBUG
532 DoubleVect S1S2vectS1S3(dimension);
533 DoubleTab S1Si(dimension,dimension);
534 for (i=0; i<dimension; i++)
535 {
536 for (dim=0; dim<dimension; dim++) S1Si(i,dim)=coordSommet(i+1,dim)-coordSommet(0,dim);
537 }
538 S1S2vectS1S3(0)=S1Si(0,1)*S1Si(1,2)-S1Si(0,2)*S1Si(1,1);
539 S1S2vectS1S3(1)=S1Si(0,2)*S1Si(1,0)-S1Si(0,0)*S1Si(1,2);
540 S1S2vectS1S3(2)=S1Si(0,0)*S1Si(1,1)-S1Si(0,1)*S1Si(1,0);
541 double det=0.;
542 for (dim=0; dim<dimension; dim++) det+=S1S2vectS1S3(dim)*S1Si(2,dim);
543
544 if (det<0)
545 {
546 // Changer le sens des sommets du triangle
547 Cout<<"Changer sens triangle " << elem << "\n";
548 for (dim=0; dim<dimension; dim++)
549 {
550 double temp=coordSommet(2,dim);
551 coordSommet(2,dim)=coordSommet(3,dim);
552 coordSommet(3,dim)=temp;
553 }
554 }
555#endif
556 DoubleTab FacesNormales(dimension+1,dimension);
557 DoubleVect vitFaceNormale(dimension+1);
558 DoubleTab FiFj(dimension+1,dimension+1,dimension);
559 IntTab ijkl(dimension+1,dimension+1,2);
560 for (i=0; i<=dimension; i++)
561 {
562 num_face=elem_faces(elem, i);
563 for (dim=0; dim<dimension; dim++) FacesNormales(i,dim)=face_normales(num_face,dim);
564 if (elem!=face_voisins(num_face,0))
565 {
566 for (dim=0; dim<dimension; dim++) FacesNormales(i,dim)=-FacesNormales(i,dim);
567 }
568 vitFaceNormale(i)=0.;
569 for (dim=0; dim<dimension; dim++) vitFaceNormale(i) += vitesse_face_absolue(num_face,dim)*FacesNormales(i,dim);
570
571 for (j=i+1; j<=dimension; j++)
572 {
573 FiFj(i,j,0)=FacesNormales(i,1)*FacesNormales(j,2)-FacesNormales(i,2)*FacesNormales(j,1);
574 FiFj(i,j,1)=FacesNormales(i,2)*FacesNormales(j,0)-FacesNormales(i,0)*FacesNormales(j,2);
575 FiFj(i,j,2)=FacesNormales(i,0)*FacesNormales(j,1)-FacesNormales(i,1)*FacesNormales(j,0);
576 for (dim=0; dim<dimension; dim++) FiFj(j,i,dim)=-FiFj(i,j,dim);
577 }
578 }
579 ijkl(0,1,0)=2;
580 ijkl(0,1,1)=3;
581 ijkl(0,2,0)=3;
582 ijkl(0,2,1)=1;
583 ijkl(0,3,0)=1;
584 ijkl(0,3,1)=2;
585 ijkl(1,2,0)=0;
586 ijkl(1,2,1)=3;
587 ijkl(1,3,0)=2;
588 ijkl(1,3,1)=0;
589 ijkl(2,3,0)=0;
590 ijkl(2,3,1)=1;
591 /*
592 for (i=0; i<=dimension; i++) {
593 ijkl(i,i,0)=-1; ijkl(i,i,1)=-1;
594 for(j=i+1;j<=dimension;j++) {
595 ijkl(j,i,0)=ijkl(i,j,1); ijkl(j,i,1)=ijkl(i,j,0);
596 }
597 }*/
598 DoubleTab FkiFj(dimension+1,dimension+1,dimension+1,dimension);
599 for (k=0; k<=dimension; k++)
600 {
601 for (i=k+1; i<=dimension; i++)
602 {
603 int kk=ijkl(k,i,0);
604 int ii=ijkl(k,i,1);
605 for (dim=0; dim<dimension; dim++)
606 {
607 FkiFj(k,i,k,dim)=FiFj(kk,k,dim)-FiFj(ii,k,dim);
608 FkiFj(i,k,k,dim)=-FkiFj(k,i,k,dim);
609 FkiFj(k,i,i,dim)=FiFj(kk,i,dim)-FiFj(ii,i,dim);
610 FkiFj(i,k,i,dim)=-FkiFj(k,i,i,dim);
611 }
612 }
613 }
614
615 volume=volumes(elem);
616 double invVol=1./(18.*volume*volume);
617 for (i=0; i<=dimension; i++)
618 {
619 int num_face_i=elem_faces(elem, i);
620 int num_i=num_face_i*dimension;
621 IntTab num_ia(dimension);
622 for (dim=0; dim<dimension; dim++) num_ia(dim)=num_i+dim;
623 for (j=0; j<=dimension; j++)
624 {
625 int num_face_j=elem_faces(elem, j);
626 int num_j = num_face_j*dimension;
627 for (beta=0; beta<dimension; beta++)
628 {
629 double resu_loc=0.;
630 for (k=0; k<=dimension; k++)
631 {
632 if (k!=i) resu_loc+=vitFaceNormale(k)*FkiFj(k,i,j,beta);
633 }
634 for (alfa=0; alfa<dimension; alfa++) matrice(num_ia(alfa),num_j)+=resu_loc*FacesNormales(i,alfa);
635 num_j++;
636 }
637 }
638 }
639
640
641 {
642 // Schema d'Hammer-Stroud pour integration de polynomes d'ordre 2
643 int nbpt=4;
644 double c0= 0.13819660112501051518; // (5-sqrt(5))/20
645 double c1= 0.58541019662496845446; // 1-3*c0 ou (5+3*sqrt(5))/20
646 double c2=-0.75623058987490536338; // 1-3*c1 ou (5-9*sqrt(5))/20
647 // lambda des points (coordonnees barycentriques)
648 DoubleTab lambda(nbpt,dimension+1);
649 lambda(0,0)=lambda(0,1)=lambda(0,2)=c0;
650 lambda(0,3)=c1;
651 lambda(1,0)=lambda(1,1)=lambda(1,3)=c0;
652 lambda(1,2)=c1;
653 lambda(2,0)=lambda(2,2)=lambda(2,3)=c0;
654 lambda(2,1)=c1;
655 lambda(3,2)=lambda(3,1)=lambda(3,3)=c0;
656 lambda(3,0)=c1;
657 // psi(p,k)=1-3*lambda(p,k) // valeur fonction de base CR en OXp
658 DoubleTab psi(nbpt,dimension+1);
659 psi(0,0)=psi(0,1)=psi(0,2)=c1;
660 psi(0,3)=c2;
661 psi(1,0)=psi(1,1)=psi(1,3)=c1;
662 psi(1,2)=c2;
663 psi(2,0)=psi(2,2)=psi(2,3)=c1;
664 psi(2,1)=c2;
665 psi(3,2)=psi(3,1)=psi(3,3)=c1;
666 psi(3,0)=c2;
667 int pt,gamma;
668 // les points d'integration
669 DoubleTab OXp(nbpt,dimension);
670 for (pt=0; pt<nbpt; pt++)
671 {
672 for (beta=0; beta<dimension; beta++)
673 {
674 OXp(pt,beta)=0;
675 for (j=0; j<=dimension; j++) OXp(pt,beta)+=lambda(pt,j)*coordSommet(j,beta);
676 }
677 }
678 invVol=1./(24.*volume);
679 // les vecteurs SkXp
680 DoubleTab SkXp(dimension+1,nbpt,dimension);
681 for (k=0; k<=dimension; k++)
682 {
683 for (gamma=0; gamma<dimension; gamma++)
684 {
685 for (pt=0; pt<nbpt; pt++) SkXp(k,pt,gamma)=OXp(pt,gamma)-coordSommet(k,gamma);
686 }
687 }
688 for (i=0; i<=dimension; i++)
689 {
690 int num_face_i=elem_faces(elem, i);
691 int num_i=num_face_i*dimension;
692 for (alfa=0; alfa<dimension; alfa++)
693 {
694 for (j=0; j<=dimension; j++)
695 {
696 int num_face_j=elem_faces(elem,j);
697 int num_j=num_face_j*dimension;
698 for (beta=0; beta<dimension; beta++)
699 {
700 double resu_j_beta=0.;
701 for (k=0; k<=dimension; k++)
702 {
703 double resu_k=0.;
704 // boucle sur les points d'integration
705 for (pt=0; pt<nbpt; pt++) resu_k+=SkXp(k,pt,beta)*psi(pt,j);
706 resu_k*=vitFaceNormale(k);
707 resu_j_beta+=resu_k;
708 } // end_for (k=0; k<=dimension; k++)
709 matrice(num_i,num_j)-=invVol*FacesNormales(i,alfa)*resu_j_beta ;
710 num_j++;
711 } // end_for (beta=0; beta<dimension; beta++)
712 } // end_for (j=0; j<=dimension; j++)
713 num_i++;
714 } // end_for (alfa=0; alfa<dimension;alfa++)
715 } // end_for (i=0; i<=dimension;i++)
716 } // end_if (type_op==RT)
717 } // end_for (int elem=0; elem<nb_elem_tot; elem++)
718 }
719 }
720
721 // Boucle sur les bords pour traiter les conditions aux limites
722 // il y a prise en compte d'un terme de convection pour les
723 // conditions aux limites de Neumann_sortie_libre seulement
724 int nb_bord = domaine_VEF.nb_front_Cl();
725 for (n_bord=0; n_bord<nb_bord; n_bord++)
726 {
727
728 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
729
730 if (sub_type(Neumann_sortie_libre,la_cl.valeur()))
731 {
732 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
733 int num1 = le_bord.num_premiere_face();
734 int num2 = num1 + le_bord.nb_faces();
735 for (num_face=num1; num_face<num2; num_face++)
736 {
737 psc =0;
738 for (i=0; i<dimension; i++)
739 psc += vitesse_face(num_face,i)*face_normales(num_face,i);
740 if (!phi_u_transportant_yes)
741 psc*=porosite_face(num_face);
742 if (psc>0)
743 {
744 for (j=0; j<ncomp_ch_transporte; j++)
745 {
746 int n0=num_face*ncomp_ch_transporte+j;
747 matrice(n0,n0)+=psc;
748 }
749 }
750 }
751 }
752 }
754}
755
Classe Champ_Inc_base.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
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
int type_elem_Cl(int i) const
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
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
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
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
classe Neumann_sortie_libre Cette classe represente une frontiere ouverte sans vitesse imposee
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_RT_VEF_Face
void ajouter_contribution(const DoubleTab &transporte, Matrice_Morse &matrice) const override
DoubleTab & ajouter(const DoubleTab &transporte, DoubleTab &resu) const override
class Op_Conv_VEF_Face
int phi_u_transportant(const Equation_base &eq) const
definit si l'on convecte psi avec phi*u ou avec u
const Champ_Inc_base & vitesse() const
void modifier_matrice_pour_periodique_apres_contribuer(Matrice_Morse &matrice, const Equation_base &) const
Somme les 2 lignes des faces periodiques associees permet de calculer dans le code sans se poser de q...
void modifier_matrice_pour_periodique_avant_contribuer(Matrice_Morse &matrice, const Equation_base &) const
divise les coefficients sur les ligne des faces periodiques par 2 en prevision de l'application modif...
void modifier_flux(const Operateur_base &) const
Classe de base des flux de sortie.
Definition Sortie.h:52
int nb_dim() const
Definition TRUSTTab.h:199
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133