TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Op_Conv_Centre_EF_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 <Op_Conv_Centre_EF_VEF_Face.h>
17#include <Neumann_sortie_libre.h>
18#include <Periodique.h>
19
20Implemente_instanciable(Op_Conv_Centre_EF_VEF_Face,"Op_Conv_Centre_EF_VEF_P1NC",Op_Conv_VEF_base);
21// XD bloc_ef objet_lecture nul NO_BRACE not_set
22// XD attr mot1 chaine(into=["transportant_bar","transporte_bar","filtrer_resu","antisym"]) mot1 REQ not_set
23// XD attr val1 entier(into=[0,1]) val1 REQ not_set
24// XD attr mot2 chaine(into=["transportant_bar","transporte_bar","filtrer_resu","antisym"]) mot2 REQ not_set
25// XD attr val2 entier(into=[0,1]) val2 REQ not_set
26// XD attr mot3 chaine(into=["transportant_bar","transporte_bar","filtrer_resu","antisym"]) mot3 REQ not_set
27// XD attr val3 entier(into=[0,1]) val3 REQ not_set
28// XD attr mot4 chaine(into=["transportant_bar","transporte_bar","filtrer_resu","antisym"]) mot4 REQ not_set
29// XD attr val4 entier(into=[0,1]) val4 REQ not_set
30// XD convection_ef convection_deriv ef NO_BRACE For VEF calculations, a centred convective scheme based on Finite
31// XD_CONT Elements formulation can be called through the following data:NL2 NL2 Convection { EF transportant_bar val
32// XD_CONT transporte_bar val antisym val filtrer_resu val }NL2 NL2 This scheme is 2nd order accuracy (and get better
33// XD_CONT the property of kinetic energy conservation). Due to possible problems of instabilities phenomena, this
34// XD_CONT scheme has to be coupled with stabilisation process (see Source_Qdm_lambdaup).These two last data are
35// XD_CONT equivalent from a theoretical point of view in variationnal writing to : div(( u. grad ub , vb) - (u. grad
36// XD_CONT vb, ub)), where vb corresponds to the filtered reference test functions.NL2 NL2 Remark:NL2 This class
37// XD_CONT requires to define a filtering operator : see solveur_bar
38// XD attr mot1 chaine(into=["defaut_bar"]) mot1 OPT equivalent to transportant_bar 0 transporte_bar 1 filtrer_resu 1
39// XD_CONT antisym 1
40// XD attr bloc_ef bloc_ef bloc_ef OPT not_set
41
43{
44 return s << que_suis_je() ;
45}
46
48{
49 return s ;
50}
51
52// ATTENTION!!!!!! les modifs concernant fluent_ et autre_num_face_loc sont faites qu en 3D!!!!
53// C.A. 30/06/99
54
55////////////////////////////////////////////////////////////////////
56//
57// Implementation des fonctions
58//
59// de la classe Op_Conv_Centre_EF_VEF_Face
60//
61////////////////////////////////////////////////////////////////////
62
63
64DoubleTab& Op_Conv_Centre_EF_VEF_Face::ajouter(const DoubleTab& transporte,
65 DoubleTab& resu) const
66{
67 const Domaine_Cl_VEF& domaine_Cl_VEF = la_zcl_vef.valeur();
68 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
69 const Champ_Inc_base& la_vitesse=vitesse_.valeur();
70
71 const DoubleVect& porosite_face = equation().milieu().porosite_face();
72
73 const IntTab& elem_faces = domaine_VEF.elem_faces();
74 const DoubleTab& face_normales = domaine_VEF.face_normales();
75 const auto& facette_normales = domaine_VEF.facette_normales();
76 const Domaine& domaine = domaine_VEF.domaine();
77 const int nfa7 = domaine_VEF.type_elem().nb_facette();
78 const int nb_elem_tot = domaine_VEF.nb_elem_tot();
79 const IntVect& rang_elem_non_std = domaine_VEF.rang_elem_non_std();
80
81
82 const DoubleTab& normales_facettes_Cl = domaine_Cl_VEF.normales_facettes_Cl();
83
84 int nfac = domaine.nb_faces_elem();
85 //int nsom = domaine.nb_som_elem();
86
87
88 // Pour le traitement de la convection on distingue les polyedres
89 // standard qui ne "voient" pas les conditions aux limites et les
90 // polyedres non standard qui ont au moins une face sur le bord.
91 // Un polyedre standard a n facettes sur lesquelles on applique le
92 // schema de convection.
93 // Pour un polyedre non standard qui porte des conditions aux limites
94 // de Dirichlet, une partie des facettes sont portees par les faces.
95 // En bref pour un polyedre le traitement de la convection depend
96 // du type (triangle, tetraedre ...) et du nombre de faces de Dirichlet.
97
98 double flux;
99 int poly,face_adj,fa7,i,j,comp0,n_bord;
100 int num_face, rang ,itypcl;
101 int num10, num20;
102
103 int ncomp_ch_transporte;
104 if (transporte.nb_dim() == 1)
105 ncomp_ch_transporte=1;
106 else
107 ncomp_ch_transporte= transporte.dimension(1);
108
109 IntVect face(nfac);
110 DoubleVect cc(dimension);
111
112 //////////////////////////////
113 DoubleTab psc(nfac);
114 int num_int;
115 IntTab autre_num_face(dimension-1);
116 IntTab autre_num_face_loc(dimension-1);
117 double coef1=0.,coef2=0.,coef3=0.;
118 // double psc1;
119 int nu1,nu2;
120 // int k;
121 double f_int;
122
123 //DoubleVect vs(dimension);
124 //DoubleVect vc(dimension);
125 //DoubleTab vsom(nsom,dimension);
126
127 // On remet a zero le tableau qui sert pour
128 // le calcul du pas de temps de stabilite
129 fluent_ = 0;
130
131 // Traitement particulier pour les faces de periodicite
132
133 int nb_faces_perio = 0;
134 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
135 {
136 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
137 if (sub_type(Periodique,la_cl.valeur()))
138 {
139 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
140 int num1 = le_bord.num_premiere_face();
141 int num2 = num1 + le_bord.nb_faces();
142 for (num_face=num1; num_face<num2; num_face++)
143 nb_faces_perio++;
144 }
145 }
146
147 DoubleTab tab;
148 if (ncomp_ch_transporte == 1)
149 tab.resize(nb_faces_perio);
150 else
151 tab.resize(nb_faces_perio,ncomp_ch_transporte);
152
153 nb_faces_perio=0;
154 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
155 {
156 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
157 if (sub_type(Periodique,la_cl.valeur()))
158 {
159 // const Periodique& la_cl_perio = ref_cast(Periodique, la_cl.valeur());
160 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
161 int num1 = le_bord.num_premiere_face();
162 int num2 = num1 + le_bord.nb_faces();
163 for (num_face=num1; num_face<num2; num_face++)
164 {
165 if (ncomp_ch_transporte == 1)
166 tab(nb_faces_perio) = resu(num_face);
167 else
168 for (int comp=0; comp<ncomp_ch_transporte; comp++)
169 tab(nb_faces_perio,comp) = resu(num_face,comp);
170 nb_faces_perio++;
171 }
172 }
173 }
174
175
176 // Les polyedres non standard sont ranges en 2 groupes dans le Domaine_VEF:
177 // - polyedres bords et joints
178 // - polyedres bords et non joints
179 // On traite les polyedres en suivant l'ordre dans lequel ils figurent
180 // dans le domaine
181
182 // boucle sur les polys
183 const IntTab& KEL=domaine_VEF.type_elem().KEL();
184 for (poly=0; poly<nb_elem_tot; poly++)
185 {
186
187 rang = rang_elem_non_std(poly);
188 if (rang==-1)
189 itypcl=0;
190 else
191 itypcl=domaine_Cl_VEF.type_elem_Cl(rang);
192
193 // calcul des numeros des faces du polyedre
194 for (face_adj=0; face_adj<nfac; face_adj++)
195 face[face_adj]= elem_faces(poly,face_adj);
196
197 // On cherche les numeros locaux de tpoutes les faces
198 for (fa7=0; fa7<nfa7; fa7++)
199 {
200 nu1=-1;
201 nu2=-1;
202 num10 = face[KEL(0,fa7)];
203 num20 = face[KEL(1,fa7)];
204 // La facette est entouree des faces num1 et num2
205 // Cerr << "num1=" << num1 << " num2=" << num2 << finl;
206
207 // On cherche le numero des autres faces
208
209 i=0;
210 j=0;
211 // k=0;
212 while(i<nfac)
213 {
214 num_int = face[i];
215 if (num_int == num10)
216 {
217 nu1=i;
218 // Cerr << "nu1 (dans les boucles)=" << nu1 << finl;
219 }
220 else if (num_int == num20)
221 {
222 nu2=i;
223 // Cerr << "nu2 (dans les boucles)=" << nu2 << finl;
224 }
225 else
226 {
227 autre_num_face_loc(j)=i;
228 autre_num_face(j)=num_int;
229 // Cerr << "autre_num_face (dans les boucles)=" << autre_num_face(j) << finl;
230 j++;
231 // k++;
232 }
233 i++;
234 }
235
236 if (rang==-1)
237 {
238 for (i=0; i<dimension; i++)
239 cc[i] = facette_normales(poly,fa7,i);
240 }
241 else
242 for (i=0; i<dimension; i++)
243 cc[i] = normales_facettes_Cl(rang,fa7,i);
244
245 // On calcule les produits scalaires u(xi).n.S
246 for (i=0; i<nfac; i ++)
247 {
248 psc[i] = 0.;
249 for (j=0; j<dimension; j++)
250 {
251 // Cerr << "cc[j]=" << cc[j] << finl;
252 // Cerr << "la_vitesse.valeurs()(face[i],j)=" << la_vitesse.valeurs()(face[i],j) << finl;
253
254 psc[i]+= la_vitesse.valeurs()(face[i],j)*cc[j]*porosite_face(face[i]);
255 }
256 // Cerr << "psc[" << i << "]=" << psc[i] << finl;
257 }
258
259 // assert(ncomp_ch_transporte==dimension);
260 // Ce schema est valable (enfin je crois...) uniquement quand ch_transporte = ch_tranportant = vitesse??
261
262
263 if (dimension == 2)
264 {
265 switch(itypcl)
266 {
267 case 0:
268 {
269 coef1 = 13.0*( psc[nu1]+psc[nu2] ) ;
270 coef1 -= 8.0*psc[autre_num_face_loc(0)];
271
272 coef2 = 8.0*( psc[nu1]+psc[nu2] ) ;
273 coef2 -= 7.0*psc[autre_num_face_loc(0)];
274
275 if (ncomp_ch_transporte == 1)
276 {
277 flux = (transporte(num10)+transporte(num20))*coef1;
278 flux -= transporte(autre_num_face(0))*coef2;
279 flux /= 27.;
280 resu(num10) -= flux;
281 }
282 else
283 {
284 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
285 {
286 flux = (transporte(num10,comp0)+transporte(num20,comp0))*coef1;
287 flux -= transporte(autre_num_face(0),comp0)*coef2;
288 flux /= 27.;
289 resu(num10, comp0) -= flux;
290 resu(num20, comp0) += flux;
291 }
292 }
293 // Pour la calcul du pas de temps de stabilite
294 fluent_[num10] += 2.*((psc[nu1]+psc[nu2])- psc[autre_num_face_loc(0)])/3.;
295 fluent_[num10] -= 2.*((psc[nu1]+psc[nu2])- psc[autre_num_face_loc(0)])/3.;
296 break;
297 }
298 default :
299 {
300 int numfa7;
301 // !!!!!! on a traite que le cas ou le champ transporte est vecteur!!!
302 if ((itypcl==1)||(itypcl==2)||(itypcl==4)) // 1 face de Dirichlet!!
303 {
304 switch(itypcl)
305 {
306 case 1 :
307 {
308 numfa7 = 2;
309 break;
310 }
311 case 2 :
312 {
313 numfa7 = 1;
314 break;
315 }
316 case 4 :
317 {
318 numfa7 = 0;
319 break;
320 }
321 default :
322 {
323 numfa7=-1;
324 Cerr << "C est pas possible!!!" << finl;
325 exit();
326 break;
327 }
328 }
329
330 // if (fa7 == itypcl)
331 if (fa7 == numfa7) // On est sur la fa7 non confondu avec la face de Dirichlet
332 {
333 coef1 = 2.*( psc[nu1]+psc[nu2] ) ;
334 coef1 -= psc[numfa7];
335
336 coef2 = psc[nu1]+psc[nu2] ;
337 coef2 -= 2.*psc[numfa7];
338
339 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
340 {
341 flux = (transporte(num10,comp0)+transporte(num20,comp0))*coef1;
342 flux -= transporte(numfa7,comp0)*coef2;
343 flux /= 6.;
344 resu(num10, comp0) -= flux;
345 resu(num20, comp0) += flux;
346 }
347 // Pour la calcul du pas de temps de stabilite
348 fluent_[num10] += 0.5*(psc[nu1]+psc[nu2]);
349 fluent_[num20] -= 0.5*(psc[nu1]+psc[nu2]);
350 // fluent_[num1] = ( fluent_[num1] > f_int) ? fluent_[num1] : f_int ;
351 }
352 else
353 {
354 // Pour les fa7 confondus
355 if (fa7 == nu2)
356 {
357 coef1 = 2.*( psc[nu1]-psc[nu2] ) ;
358 coef1 += 3.*psc[numfa7];
359
360 coef2 = 3.*(psc[nu1]-psc[nu2]) ;
361 coef2 += 6.*psc[numfa7];
362
363
364 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
365 {
366 flux = (transporte(face[nu1],comp0)-transporte(face[nu2],comp0))*coef1;
367 flux += transporte(face[numfa7],comp0)*coef2;
368 flux /= 6.;
369 resu(face[nu1],comp0) -= flux; // est ce le bon signe??????????????????????
370 // Cerr << "num1=" << num1 << " num2=" << num2 << finl;
371 }
372 // Pour la calcul du pas de temps de stabilite
373 fluent_[face[nu1]] -= 0.5*(psc[nu1]-psc[nu2])+psc[numfa7]; // signe????????
374
375 //////////////////////////////////////////////
376 }
377 else
378 {
379 // fa7 == nu1
380 coef1 = 2.*( psc[nu2]-psc[nu1] ) ;
381 coef1 += 3.*psc[numfa7];
382
383 coef2 = 3.*(psc[nu2]-psc[nu1]) ;
384 coef2 += 6.*psc[numfa7]; // est ce la bonne numerotation?
385
386
387 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
388 {
389 flux = (transporte(face[nu2],comp0)-transporte(face[nu1],comp0))*coef1;
390 flux += transporte(face[numfa7],comp0)*coef2;
391 flux /= 6.;
392 resu(face[nu1],comp0) -= flux; // est ce le bon signe?????????????????
393 // Cerr << "num1=" << num1 << " num2=" << num2 << finl;
394 }
395 // Pour la calcul du pas de temps de stabilite
396 fluent_[face[nu1]] -= 0.5*(psc[nu2]-psc[nu1])+psc[numfa7]; // signe?????????????????
397
398 //////////////////////////////////////////////
399 }
400 }
401 }
402 else
403 {
404 // 2 faces de Dirichlet!!!!!
405 // meme expression pour les 3 fa7 (confondues avec les faces de bord)
406 // On suppose que la num fa7 = num face
407
408 // Recuperation des numeros des autres faces
409 switch(fa7)
410 {
411 case 0 :
412 {
413 nu1 = 1;
414 nu2 = 2;
415 break;
416 }
417 case 1 :
418 {
419 nu1 = 0;
420 nu2 = 2;
421 break;
422 }
423 case 2 :
424 {
425 nu1 = 1;
426 nu2 = 0;
427 break;
428 }
429 default :
430 {
431 nu1=-1;
432 nu2=-1;
433 Cerr << "On arrete tout, c est pas possible!!!!" << finl;
434 Cerr << "sinon c est que je n ai rien compris!!!" << finl;
435 exit();
436 }
437 }
438 // Cerr << "fa7=" << fa7 << " nu1=" << nu1 << " nu2=" << nu2 << finl;
439 coef1 = psc[fa7];
440 coef2 = (psc[nu1]-psc[nu2])/3.;
441 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
442 {
443 flux = transporte(face[fa7],comp0)*coef1;
444 flux += (transporte(face[nu1],comp0)-transporte(face[nu2],comp0))*coef2;
445 flux /= 6.;
446 resu(face[nu1],comp0) -= flux; // est ce le bon signe?
447 }
448 // Pour la calcul du pas de temps de stabilite
449 fluent_[face[fa7]] -= psc[fa7];
450 // f_int = psc[fa7];
451 // fluent_[face[fa7]] = ( fluent_[face[fa7]] > f_int) ? fluent_[face[fa7]] : f_int ;
452 //////////////////////////////////////////////
453 }
454 break;
455 }
456 }
457 } // FIN de if(dimension == 2)
458 else if (dimension == 3)
459 {
460 switch(itypcl)
461 {
462 case 0:
463 {
464 coef1 = 19.0*( psc[nu1]+psc[nu2] ) ;
465 coef1 -= 7.0*(psc[autre_num_face_loc(0)]+psc[autre_num_face_loc(1)]);
466 // Cerr << "coef1=" << coef1 << finl;
467
468 coef2 = 7.0*( psc[nu1]+psc[nu2] ) ;
469 coef2 -= 15.0*psc[autre_num_face_loc(0)];
470 coef2 += 9.0*psc[autre_num_face_loc(1)];
471 // Cerr << "coef2=" << coef2 << finl;
472
473 coef3 = 7.0*( psc[nu1]+psc[nu2] ) ;
474 coef3 += 9.0*psc[autre_num_face_loc(0)];
475 coef3 -= 15.0*psc[autre_num_face_loc(1)];
476 // Cerr << "coef3=" << coef3 << finl;
477
478 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
479 {
480 flux = (transporte(num10,comp0)+transporte(num20,comp0))*coef1;
481 flux -= transporte(autre_num_face(0),comp0)*coef2;
482 flux -= transporte(autre_num_face(1),comp0)*coef3;
483 flux /= 32.;
484 resu(num10, comp0) -= flux;
485 resu(num20, comp0) += flux;
486 // Cerr << "transporte(num1,comp)=" << transporte(num1,comp) << finl;
487 // Cerr << "transporte(num2,comp)=" << transporte(num2,comp) << finl;
488 // Cerr << "transporte(autre_num_face(0),comp)=" << transporte(autre_num_face(0),comp) << finl;
489 // Cerr << "transporte(autre_num_face(1),comp)=" << transporte(autre_num_face(1),comp) << finl;
490 // Cerr << "flux=" << flux << finl;
491 //************Calcul de fluent pour le pas de temps
492 // f_int = 0.5*cc[comp]*(la_vitesse.valeurs()(num1,comp)+la_vitesse.valeurs()(num2,comp));
493
494 // if (f_int>=0.)
495 // fluent_[num2] += f_int ;
496 // else
497 // fluent_[num1] -= f_int ;
498 }
499 f_int = 3.*(psc[nu1]+psc[nu2]);
500 f_int -= (psc[autre_num_face_loc(0)]+psc[autre_num_face_loc(1)]);
501 f_int /= 4.;
502 if (f_int>=0.)
503 {
504 //fluent_[num2] += f_int ;
505 fluent_[num20] = ( fluent_[num20] > std::fabs(f_int))? fluent_[num20] : std::fabs(f_int);
506 }
507 else
508 {
509 //fluent_[num1] -= f_int ;
510 fluent_[num10] = ( fluent_[num10] > std::fabs(f_int))? fluent_[num10] : std::fabs(f_int);
511 }
512
513
514
515 break;
516 }
517 default:
518 {
519 Cerr << "Dans le default!!" << finl;
520 int nu3=-1;
521 if (fa7 == itypcl)
522 {
523 i=0;
524 while(i<nfac) // on cherche le 4ieme point!!
525 {
526 nu3 = i;
527 if (nu3 == fa7)
528 i++;
529 else if (nu3 == nu1)
530 i++;
531 else if (nu3 == nu2)
532 i++;
533 else
534 i=nfac;
535 }
536 coef1 = 6.*( psc[nu1]+psc[nu2] ) ;
537 coef1 -= 3.*psc[nu3]+psc[fa7];
538
539 coef2 = 3.0*( psc[nu1]+psc[nu2] ) ;
540 coef2 -= 7.0*psc[nu3];
541 coef2 += 4.0*psc[fa7];
542
543 coef3 = psc[nu1]+psc[nu2];
544 coef3 += psc[nu3];
545 coef3 -= 7.*psc[fa7];
546
547 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
548 {
549 flux = (transporte(num10,comp0)+transporte(num20,comp0))*coef1;
550 flux -= transporte(face[nu3],comp0)*coef2;
551 flux -= transporte(face[fa7],comp0)*coef3;
552 flux /= 12.;
553 resu(num10, comp0) -= flux;
554 resu(num20, comp0) += flux;
555 // Pour la calcul du pas de temps de stabilite
556 // SIGNE????????????
557 // f_int = std::fabs(flux/transporte(num1,comp));
558 f_int = 3.*(psc[nu1]+psc[nu2]);
559 f_int -= (psc[autre_num_face_loc(0)]+psc[autre_num_face_loc(1)]);
560 f_int /= 4.;
561 // fluent_[num1] -= f_int ;
562 // fluent_[num2] += f_int ;
563 if (f_int >=0.)
564 fluent_[num20] += f_int ;
565 else
566 fluent_[num10] -= f_int ;
567
568 // fluent_[num1] = ( fluent_[num1] > f_int) ? fluent_[num1] : f_int ;
569 //////////////////////////////////////////////
570 // Cerr << "flux=" << flux << finl;
571 }
572 }
573 else
574 {
575 // J ai l impression que ce n est pas fini???!!!!!!!!!!
576 }
577 break;
578 }
579 }
580 }
581 }
582 }
583 // Cerr << "vitesse=" << la_vitesse.valeurs() << finl;
584
585
586 int voisine;
587 nb_faces_perio = 0;
588 double diff1,diff2;
589 double pscav;
590
591 // Dimensionnement du tableau des flux convectifs au bord du domaine
592 // de calcul
593 DoubleTab& flux_b = flux_bords_;
594 flux_b.resize(domaine_VEF.nb_faces_bord(),ncomp_ch_transporte);
595 flux_b = 0.;
596
597 // Boucle sur les bords pour traiter les conditions aux limites
598 // il y a prise en compte d'un terme de convection pour les
599 // conditions aux limites de Neumann_sortie_libre seulement
600
601 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
602 {
603
604 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
605
606 if (sub_type(Neumann_sortie_libre,la_cl.valeur()))
607 {
608 ////////////ATTENTION!!!!!!!!!!! Cela correspond a l ancien schema et pas au EF!!
609 const Neumann_sortie_libre& la_sortie_libre = ref_cast(Neumann_sortie_libre,la_cl.valeur());
610 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
611 int num1 = le_bord.num_premiere_face();
612 int num2 = num1 + le_bord.nb_faces();
613 for (num_face=num1; num_face<num2; num_face++)
614 {
615 pscav =0;
616 for (i=0; i<dimension; i++)
617 pscav += la_vitesse.valeurs()(num_face,i)*face_normales(num_face,i)*porosite_face(num_face);
618 if (pscav>0)
619 if (ncomp_ch_transporte == 1)
620 {
621 resu(num_face) -= pscav*transporte(num_face);
622 flux_b(num_face,0) -= pscav*transporte(num_face);
623 }
624 else
625 for (i=0; i<ncomp_ch_transporte; i++)
626 {
627 resu(num_face,i) -= pscav*transporte(num_face,i);
628 flux_b(num_face,i) -= pscav*transporte(num_face,i);
629 }
630 else
631 {
632 if (ncomp_ch_transporte == 1)
633 {
634 resu(num_face) -= pscav*la_sortie_libre.val_ext(num_face-num1);
635 flux_b(num_face,0) -= pscav*la_sortie_libre.val_ext(num_face-num1);
636 }
637 else
638 for (i=0; i<ncomp_ch_transporte; i++)
639 {
640 resu(num_face,i) -= pscav*la_sortie_libre.val_ext(num_face-num1,i);
641 flux_b(num_face,i) -= pscav*la_sortie_libre.val_ext(num_face-num1,i);
642 }
643 fluent_[num_face] -= pscav;
644 }
645 }
646 // Cerr << "Pour l instant Neumann_sortie_libre pas possible!!!" << finl;
647 }
648 else if (sub_type(Periodique,la_cl.valeur()))
649 {
650 const Periodique& la_cl_perio = ref_cast(Periodique,la_cl.valeur());
651 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
652 int num1 = le_bord.num_premiere_face();
653 int num2 = num1 + le_bord.nb_faces();
654 IntVect fait(le_bord.nb_faces());
655 fait = 0;
656 for (num_face=num1; num_face<num2; num_face++)
657 {
658 if (fait[num_face-num1] == 0)
659 {
660 voisine = la_cl_perio.face_associee(num_face-num1) + num1;
661
662 if (ncomp_ch_transporte == 1)
663 {
664 diff1 = resu(num_face)-tab(nb_faces_perio);
665 diff2 = resu(voisine)-tab(nb_faces_perio+voisine-num_face);
666 resu(voisine) += diff1;
667 resu(num_face) += diff2;
668 flux_b(voisine,0) += diff1;
669 flux_b(num_face,0) += diff1;
670 // Pour la calcul du pas de temps de stabilite
671 // RIEN en periodique ??? (faces deja traites avant??????)
672 //////////////////////////////////////////////
673 }
674 else
675 for (int comp=0; comp<ncomp_ch_transporte; comp++)
676 {
677 diff1 = resu(num_face,comp)-tab(nb_faces_perio,comp);
678 diff2 = resu(voisine,comp)-tab(nb_faces_perio+voisine-num_face,comp);
679 // Cerr << "num_face=" << num_face << " diff1=" << diff1 << finl;
680 // Cerr << "voisine=" << voisine << " diff2=" << diff2 << finl;
681 resu(voisine,comp) += diff1;
682 resu(num_face,comp) += diff2;
683 flux_b(voisine,comp) += diff1;
684 flux_b(num_face,comp) += diff1;
685 // Pour la calcul du pas de temps de stabilite
686 // RIEN en periodique ??? (faces deja traites avant??????)
687 //////////////////////////////////////////////
688 }
689
690 fait[num_face-num1]= 1;
691 fait[voisine-num1] = 1;
692 }
693 nb_faces_perio++;
694 }
695 }
696 }
697 modifier_flux(*this);
698 return resu;
699
700}
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
int type_elem_Cl(int i) const
DoubleTab & normales_facettes_Cl()
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
const Elem_VEF_base & type_elem() const
Definition Domaine_VEF.h:75
auto & facette_normales()
Definition Domaine_VEF.h:84
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 nb_faces_bord() const
renvoie le nombre de faces sur lesquelles sont appliquees les conditions limites :
Definition Domaine_VF.h:513
int nb_elem_tot() const
int nb_front_Cl() const
const Domaine & domaine() const
const IntTab & KEL() const
virtual int nb_facette() const =0
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
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
double val_ext(int i) const override
Renvoie la valeur de la i-eme composante du champ impose a l'exterieur de la frontiere.
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_Centre_EF_VEF_Face
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
class Op_Conv_VEF_base
void modifier_flux(const Operateur_base &) const
DoubleTab flux_bords_
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
int nb_dim() const
Definition TRUSTTab.h:199
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133