TrioCFD 1.9.9_beta
TrioCFD documentation
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// WARNING!!!!!!! modifications regarding fluent_ and autre_num_face_loc are made only in 3D!!!!
53// C.A. 30/06/99
54
55////////////////////////////////////////////////////////////////////
56//
57// Implementation of functions
58//
59// of class 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 // For the convection treatment, standard polyhedra (not "seeing" boundary conditions)
89 // are distinguished from non-standard polyhedra (having at least one boundary face).
90 // A standard polyhedron has n facets on which the convection scheme is applied.
91 // For a non-standard polyhedron with Dirichlet boundary conditions, part of its
92 // facets are carried by the boundary faces.
93 // In short, for a polyhedron the convection treatment depends on the type
94 // (triangle, tetrahedron ...) and the number of Dirichlet faces.
95
96 double flux;
97 int poly,face_adj,fa7,i,j,comp0,n_bord;
98 int num_face, rang ,itypcl;
99 int num10, num20;
100
101 int ncomp_ch_transporte;
102 if (transporte.nb_dim() == 1)
103 ncomp_ch_transporte=1;
104 else
105 ncomp_ch_transporte= transporte.dimension(1);
106
107 IntVect face(nfac);
108 DoubleVect cc(dimension);
109
110 //////////////////////////////
111 DoubleTab psc(nfac);
112 int num_int;
113 IntTab autre_num_face(dimension-1);
114 IntTab autre_num_face_loc(dimension-1);
115 double coef1=0.,coef2=0.,coef3=0.;
116 // double psc1;
117 int nu1,nu2;
118 // int k;
119 double f_int;
120
121 //DoubleVect vs(dimension);
122 //DoubleVect vc(dimension);
123 //DoubleTab vsom(nsom,dimension);
124
125 // Reset to zero the array used for
126 // the stability time step computation
127 fluent_ = 0;
128
129 // Special treatment for periodic faces
130
131 int nb_faces_perio = 0;
132 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
133 {
134 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
135 if (sub_type(Periodique,la_cl.valeur()))
136 {
137 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
138 int num1 = le_bord.num_premiere_face();
139 int num2 = num1 + le_bord.nb_faces();
140 for (num_face=num1; num_face<num2; num_face++)
141 nb_faces_perio++;
142 }
143 }
144
145 DoubleTab tab;
146 if (ncomp_ch_transporte == 1)
147 tab.resize(nb_faces_perio);
148 else
149 tab.resize(nb_faces_perio,ncomp_ch_transporte);
150
151 nb_faces_perio=0;
152 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
153 {
154 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
155 if (sub_type(Periodique,la_cl.valeur()))
156 {
157 // const Periodique& la_cl_perio = ref_cast(Periodique, la_cl.valeur());
158 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
159 int num1 = le_bord.num_premiere_face();
160 int num2 = num1 + le_bord.nb_faces();
161 for (num_face=num1; num_face<num2; num_face++)
162 {
163 if (ncomp_ch_transporte == 1)
164 tab(nb_faces_perio) = resu(num_face);
165 else
166 for (int comp=0; comp<ncomp_ch_transporte; comp++)
167 tab(nb_faces_perio,comp) = resu(num_face,comp);
168 nb_faces_perio++;
169 }
170 }
171 }
172
173
174 // Non-standard polyhedra are arranged in 2 groups in Domaine_VEF:
175 // - boundary and joint polyhedra
176 // - boundary and non-joint polyhedra
177 // Polyhedra are processed following the order in which they appear
178 // in the domain
179
180 // loop over polyhedra
181 const IntTab& KEL=domaine_VEF.type_elem().KEL();
182 for (poly=0; poly<nb_elem_tot; poly++)
183 {
184
185 rang = rang_elem_non_std(poly);
186 if (rang==-1)
187 itypcl=0;
188 else
189 itypcl=domaine_Cl_VEF.type_elem_Cl(rang);
190
191 // compute the face indices of the polyhedron
192 for (face_adj=0; face_adj<nfac; face_adj++)
193 face[face_adj]= elem_faces(poly,face_adj);
194
195 // Find the local indices of all faces
196 for (fa7=0; fa7<nfa7; fa7++)
197 {
198 nu1=-1;
199 nu2=-1;
200 num10 = face[KEL(0,fa7)];
201 num20 = face[KEL(1,fa7)];
202 // The facet is surrounded by faces num1 and num2
203 // Cerr << "num1=" << num1 << " num2=" << num2 << finl;
204
205 // Find the indices of the other faces
206
207 i=0;
208 j=0;
209 // k=0;
210 while(i<nfac)
211 {
212 num_int = face[i];
213 if (num_int == num10)
214 {
215 nu1=i;
216 // Cerr << "nu1 (in loops)=" << nu1 << finl;
217 }
218 else if (num_int == num20)
219 {
220 nu2=i;
221 // Cerr << "nu2 (in loops)=" << nu2 << finl;
222 }
223 else
224 {
225 autre_num_face_loc(j)=i;
226 autre_num_face(j)=num_int;
227 // Cerr << "autre_num_face (in loops)=" << autre_num_face(j) << finl;
228 j++;
229 // k++;
230 }
231 i++;
232 }
233
234 if (rang==-1)
235 {
236 for (i=0; i<dimension; i++)
237 cc[i] = facette_normales(poly,fa7,i);
238 }
239 else
240 for (i=0; i<dimension; i++)
241 cc[i] = normales_facettes_Cl(rang,fa7,i);
242
243 // Compute the dot products u(xi).n.S
244 for (i=0; i<nfac; i ++)
245 {
246 psc[i] = 0.;
247 for (j=0; j<dimension; j++)
248 {
249 // Cerr << "cc[j]=" << cc[j] << finl;
250 // Cerr << "la_vitesse.valeurs()(face[i],j)=" << la_vitesse.valeurs()(face[i],j) << finl;
251
252 psc[i]+= la_vitesse.valeurs()(face[i],j)*cc[j]*porosite_face(face[i]);
253 }
254 // Cerr << "psc[" << i << "]=" << psc[i] << finl;
255 }
256
257 // assert(ncomp_ch_transporte==dimension);
258 // This scheme is valid (at least I think...) only when ch_transporte = ch_tranportant = velocity??
259
260
261 if (dimension == 2)
262 {
263 switch(itypcl)
264 {
265 case 0:
266 {
267 coef1 = 13.0*( psc[nu1]+psc[nu2] ) ;
268 coef1 -= 8.0*psc[autre_num_face_loc(0)];
269
270 coef2 = 8.0*( psc[nu1]+psc[nu2] ) ;
271 coef2 -= 7.0*psc[autre_num_face_loc(0)];
272
273 if (ncomp_ch_transporte == 1)
274 {
275 flux = (transporte(num10)+transporte(num20))*coef1;
276 flux -= transporte(autre_num_face(0))*coef2;
277 flux /= 27.;
278 resu(num10) -= flux;
279 }
280 else
281 {
282 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
283 {
284 flux = (transporte(num10,comp0)+transporte(num20,comp0))*coef1;
285 flux -= transporte(autre_num_face(0),comp0)*coef2;
286 flux /= 27.;
287 resu(num10, comp0) -= flux;
288 resu(num20, comp0) += flux;
289 }
290 }
291 // For the stability time step computation
292 fluent_[num10] += 2.*((psc[nu1]+psc[nu2])- psc[autre_num_face_loc(0)])/3.;
293 fluent_[num10] -= 2.*((psc[nu1]+psc[nu2])- psc[autre_num_face_loc(0)])/3.;
294 break;
295 }
296 default :
297 {
298 int numfa7;
299 // !!!!!! only the case where the transported field is a vector has been handled!!!
300 if ((itypcl==1)||(itypcl==2)||(itypcl==4)) // 1 Dirichlet face!!
301 {
302 switch(itypcl)
303 {
304 case 1 :
305 {
306 numfa7 = 2;
307 break;
308 }
309 case 2 :
310 {
311 numfa7 = 1;
312 break;
313 }
314 case 4 :
315 {
316 numfa7 = 0;
317 break;
318 }
319 default :
320 {
321 numfa7=-1;
322 Cerr << "This should not be possible!!!" << finl;
323 exit();
324 break;
325 }
326 }
327
328 // if (fa7 == itypcl)
329 if (fa7 == numfa7) // We are on the fa7 not coinciding with the Dirichlet face
330 {
331 coef1 = 2.*( psc[nu1]+psc[nu2] ) ;
332 coef1 -= psc[numfa7];
333
334 coef2 = psc[nu1]+psc[nu2] ;
335 coef2 -= 2.*psc[numfa7];
336
337 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
338 {
339 flux = (transporte(num10,comp0)+transporte(num20,comp0))*coef1;
340 flux -= transporte(numfa7,comp0)*coef2;
341 flux /= 6.;
342 resu(num10, comp0) -= flux;
343 resu(num20, comp0) += flux;
344 }
345 // For the stability time step computation
346 fluent_[num10] += 0.5*(psc[nu1]+psc[nu2]);
347 fluent_[num20] -= 0.5*(psc[nu1]+psc[nu2]);
348 // fluent_[num1] = ( fluent_[num1] > f_int) ? fluent_[num1] : f_int ;
349 }
350 else
351 {
352 // For coinciding fa7
353 if (fa7 == nu2)
354 {
355 coef1 = 2.*( psc[nu1]-psc[nu2] ) ;
356 coef1 += 3.*psc[numfa7];
357
358 coef2 = 3.*(psc[nu1]-psc[nu2]) ;
359 coef2 += 6.*psc[numfa7];
360
361
362 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
363 {
364 flux = (transporte(face[nu1],comp0)-transporte(face[nu2],comp0))*coef1;
365 flux += transporte(face[numfa7],comp0)*coef2;
366 flux /= 6.;
367 resu(face[nu1],comp0) -= flux; // is this the right sign??????????????????????
368 // Cerr << "num1=" << num1 << " num2=" << num2 << finl;
369 }
370 // For the stability time step computation
371 fluent_[face[nu1]] -= 0.5*(psc[nu1]-psc[nu2])+psc[numfa7]; // sign????????
372
373 //////////////////////////////////////////////
374 }
375 else
376 {
377 // fa7 == nu1
378 coef1 = 2.*( psc[nu2]-psc[nu1] ) ;
379 coef1 += 3.*psc[numfa7];
380
381 coef2 = 3.*(psc[nu2]-psc[nu1]) ;
382 coef2 += 6.*psc[numfa7]; // is this the right numbering?
383
384
385 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
386 {
387 flux = (transporte(face[nu2],comp0)-transporte(face[nu1],comp0))*coef1;
388 flux += transporte(face[numfa7],comp0)*coef2;
389 flux /= 6.;
390 resu(face[nu1],comp0) -= flux; // is this the right sign?????????????????
391 // Cerr << "num1=" << num1 << " num2=" << num2 << finl;
392 }
393 // For the stability time step computation
394 fluent_[face[nu1]] -= 0.5*(psc[nu2]-psc[nu1])+psc[numfa7]; // sign?????????????????
395
396 //////////////////////////////////////////////
397 }
398 }
399 }
400 else
401 {
402 // 2 Dirichlet faces!!!!!
403 // same expression for the 3 fa7 (coinciding with boundary faces)
404 // Assuming num fa7 = num face
405
406 // Retrieve the indices of the other faces
407 switch(fa7)
408 {
409 case 0 :
410 {
411 nu1 = 1;
412 nu2 = 2;
413 break;
414 }
415 case 1 :
416 {
417 nu1 = 0;
418 nu2 = 2;
419 break;
420 }
421 case 2 :
422 {
423 nu1 = 1;
424 nu2 = 0;
425 break;
426 }
427 default :
428 {
429 nu1=-1;
430 nu2=-1;
431 Cerr << "Stopping everything, this should not be possible!!!!" << finl;
432 Cerr << "otherwise it means I have misunderstood something!!!" << finl;
433 exit();
434 }
435 }
436 // Cerr << "fa7=" << fa7 << " nu1=" << nu1 << " nu2=" << nu2 << finl;
437 coef1 = psc[fa7];
438 coef2 = (psc[nu1]-psc[nu2])/3.;
439 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
440 {
441 flux = transporte(face[fa7],comp0)*coef1;
442 flux += (transporte(face[nu1],comp0)-transporte(face[nu2],comp0))*coef2;
443 flux /= 6.;
444 resu(face[nu1],comp0) -= flux; // is this the right sign?
445 }
446 // For the stability time step computation
447 fluent_[face[fa7]] -= psc[fa7];
448 // f_int = psc[fa7];
449 // fluent_[face[fa7]] = ( fluent_[face[fa7]] > f_int) ? fluent_[face[fa7]] : f_int ;
450 //////////////////////////////////////////////
451 }
452 break;
453 }
454 }
455 } // END of if(dimension == 2)
456 else if (dimension == 3)
457 {
458 switch(itypcl)
459 {
460 case 0:
461 {
462 coef1 = 19.0*( psc[nu1]+psc[nu2] ) ;
463 coef1 -= 7.0*(psc[autre_num_face_loc(0)]+psc[autre_num_face_loc(1)]);
464 // Cerr << "coef1=" << coef1 << finl;
465
466 coef2 = 7.0*( psc[nu1]+psc[nu2] ) ;
467 coef2 -= 15.0*psc[autre_num_face_loc(0)];
468 coef2 += 9.0*psc[autre_num_face_loc(1)];
469 // Cerr << "coef2=" << coef2 << finl;
470
471 coef3 = 7.0*( psc[nu1]+psc[nu2] ) ;
472 coef3 += 9.0*psc[autre_num_face_loc(0)];
473 coef3 -= 15.0*psc[autre_num_face_loc(1)];
474 // Cerr << "coef3=" << coef3 << finl;
475
476 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
477 {
478 flux = (transporte(num10,comp0)+transporte(num20,comp0))*coef1;
479 flux -= transporte(autre_num_face(0),comp0)*coef2;
480 flux -= transporte(autre_num_face(1),comp0)*coef3;
481 flux /= 32.;
482 resu(num10, comp0) -= flux;
483 resu(num20, comp0) += flux;
484 // Cerr << "transporte(num1,comp)=" << transporte(num1,comp) << finl;
485 // Cerr << "transporte(num2,comp)=" << transporte(num2,comp) << finl;
486 // Cerr << "transporte(autre_num_face(0),comp)=" << transporte(autre_num_face(0),comp) << finl;
487 // Cerr << "transporte(autre_num_face(1),comp)=" << transporte(autre_num_face(1),comp) << finl;
488 // Cerr << "flux=" << flux << finl;
489 //************Compute fluent for the time step
490 // f_int = 0.5*cc[comp]*(la_vitesse.valeurs()(num1,comp)+la_vitesse.valeurs()(num2,comp));
491
492 // if (f_int>=0.)
493 // fluent_[num2] += f_int ;
494 // else
495 // fluent_[num1] -= f_int ;
496 }
497 f_int = 3.*(psc[nu1]+psc[nu2]);
498 f_int -= (psc[autre_num_face_loc(0)]+psc[autre_num_face_loc(1)]);
499 f_int /= 4.;
500 if (f_int>=0.)
501 {
502 //fluent_[num2] += f_int ;
503 fluent_[num20] = ( fluent_[num20] > std::fabs(f_int))? fluent_[num20] : std::fabs(f_int);
504 }
505 else
506 {
507 //fluent_[num1] -= f_int ;
508 fluent_[num10] = ( fluent_[num10] > std::fabs(f_int))? fluent_[num10] : std::fabs(f_int);
509 }
510
511
512
513 break;
514 }
515 default:
516 {
517 Cerr << "Dans le default!!" << finl;
518 int nu3=-1;
519 if (fa7 == itypcl)
520 {
521 i=0;
522 while(i<nfac) // search for the 4th point!!
523 {
524 nu3 = i;
525 if (nu3 == fa7)
526 i++;
527 else if (nu3 == nu1)
528 i++;
529 else if (nu3 == nu2)
530 i++;
531 else
532 i=nfac;
533 }
534 coef1 = 6.*( psc[nu1]+psc[nu2] ) ;
535 coef1 -= 3.*psc[nu3]+psc[fa7];
536
537 coef2 = 3.0*( psc[nu1]+psc[nu2] ) ;
538 coef2 -= 7.0*psc[nu3];
539 coef2 += 4.0*psc[fa7];
540
541 coef3 = psc[nu1]+psc[nu2];
542 coef3 += psc[nu3];
543 coef3 -= 7.*psc[fa7];
544
545 for (comp0=0; comp0<ncomp_ch_transporte; comp0++)
546 {
547 flux = (transporte(num10,comp0)+transporte(num20,comp0))*coef1;
548 flux -= transporte(face[nu3],comp0)*coef2;
549 flux -= transporte(face[fa7],comp0)*coef3;
550 flux /= 12.;
551 resu(num10, comp0) -= flux;
552 resu(num20, comp0) += flux;
553 // For the stability time step computation
554 // SIGNE????????????
555 // f_int = std::fabs(flux/transporte(num1,comp));
556 f_int = 3.*(psc[nu1]+psc[nu2]);
557 f_int -= (psc[autre_num_face_loc(0)]+psc[autre_num_face_loc(1)]);
558 f_int /= 4.;
559 // fluent_[num1] -= f_int ;
560 // fluent_[num2] += f_int ;
561 if (f_int >=0.)
562 fluent_[num20] += f_int ;
563 else
564 fluent_[num10] -= f_int ;
565
566 // fluent_[num1] = ( fluent_[num1] > f_int) ? fluent_[num1] : f_int ;
567 //////////////////////////////////////////////
568 // Cerr << "flux=" << flux << finl;
569 }
570 }
571 else
572 {
573 // This appears to be unfinished???!!!!!!!!!!
574 }
575 break;
576 }
577 }
578 }
579 }
580 }
581 // Cerr << "vitesse=" << la_vitesse.valeurs() << finl;
582
583
584 int voisine;
585 nb_faces_perio = 0;
586 double diff1,diff2;
587 double pscav;
588
589 // Sizing the array of convective fluxes at the domain boundary
590 DoubleTab& flux_b = flux_bords_;
591 flux_b.resize(domaine_VEF.nb_faces_bord(),ncomp_ch_transporte);
592 flux_b = 0.;
593
594 // Loop over boundaries to handle boundary conditions
595 // a convection term is taken into account only for
596 // Neumann_sortie_libre boundary conditions
597
598 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
599 {
600
601 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
602
603 if (sub_type(Neumann_sortie_libre,la_cl.valeur()))
604 {
605 ////////////WARNING!!!!!!!!!!! This corresponds to the old schema and not to EF!!
606 const Neumann_sortie_libre& la_sortie_libre = ref_cast(Neumann_sortie_libre,la_cl.valeur());
607 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
608 int num1 = le_bord.num_premiere_face();
609 int num2 = num1 + le_bord.nb_faces();
610 for (num_face=num1; num_face<num2; num_face++)
611 {
612 pscav =0;
613 for (i=0; i<dimension; i++)
614 pscav += la_vitesse.valeurs()(num_face,i)*face_normales(num_face,i)*porosite_face(num_face);
615 if (pscav>0)
616 if (ncomp_ch_transporte == 1)
617 {
618 resu(num_face) -= pscav*transporte(num_face);
619 flux_b(num_face,0) -= pscav*transporte(num_face);
620 }
621 else
622 for (i=0; i<ncomp_ch_transporte; i++)
623 {
624 resu(num_face,i) -= pscav*transporte(num_face,i);
625 flux_b(num_face,i) -= pscav*transporte(num_face,i);
626 }
627 else
628 {
629 if (ncomp_ch_transporte == 1)
630 {
631 resu(num_face) -= pscav*la_sortie_libre.val_ext(num_face-num1);
632 flux_b(num_face,0) -= pscav*la_sortie_libre.val_ext(num_face-num1);
633 }
634 else
635 for (i=0; i<ncomp_ch_transporte; i++)
636 {
637 resu(num_face,i) -= pscav*la_sortie_libre.val_ext(num_face-num1,i);
638 flux_b(num_face,i) -= pscav*la_sortie_libre.val_ext(num_face-num1,i);
639 }
640 fluent_[num_face] -= pscav;
641 }
642 }
643 // Cerr << "For now Neumann_sortie_libre not supported!!!" << finl;
644 }
645 else if (sub_type(Periodique,la_cl.valeur()))
646 {
647 const Periodique& la_cl_perio = ref_cast(Periodique,la_cl.valeur());
648 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
649 int num1 = le_bord.num_premiere_face();
650 int num2 = num1 + le_bord.nb_faces();
651 IntVect fait(le_bord.nb_faces());
652 fait = 0;
653 for (num_face=num1; num_face<num2; num_face++)
654 {
655 if (fait[num_face-num1] == 0)
656 {
657 voisine = la_cl_perio.face_associee(num_face-num1) + num1;
658
659 if (ncomp_ch_transporte == 1)
660 {
661 diff1 = resu(num_face)-tab(nb_faces_perio);
662 diff2 = resu(voisine)-tab(nb_faces_perio+voisine-num_face);
663 resu(voisine) += diff1;
664 resu(num_face) += diff2;
665 flux_b(voisine,0) += diff1;
666 flux_b(num_face,0) += diff1;
667 // For the stability time step computation
668 // NOTHING in periodic ??? (faces already processed before??????)
669 //////////////////////////////////////////////
670 }
671 else
672 for (int comp=0; comp<ncomp_ch_transporte; comp++)
673 {
674 diff1 = resu(num_face,comp)-tab(nb_faces_perio,comp);
675 diff2 = resu(voisine,comp)-tab(nb_faces_perio+voisine-num_face,comp);
676 // Cerr << "num_face=" << num_face << " diff1=" << diff1 << finl;
677 // Cerr << "voisine=" << voisine << " diff2=" << diff2 << finl;
678 resu(voisine,comp) += diff1;
679 resu(num_face,comp) += diff2;
680 flux_b(voisine,comp) += diff1;
681 flux_b(num_face,comp) += diff1;
682 // For the stability time step computation
683 // NOTHING in periodic ??? (faces already processed before??????)
684 //////////////////////////////////////////////
685 }
686
687 fait[num_face-num1]= 1;
688 fait[voisine-num1] = 1;
689 }
690 nb_faces_perio++;
691 }
692 }
693 }
694 modifier_flux(*this);
695 return resu;
696
697}
Class Champ_Inc_base.
DoubleTab & valeurs() override
Returns the array of field values at the current time.
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
int type_elem_Cl(int i) const
DoubleTab & normales_facettes_Cl()
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
const Elem_VEF_base & type_elem() const
Definition Domaine_VEF.h:74
auto & facette_normales()
Definition Domaine_VEF.h:83
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 nb_faces_bord() const
Returns the number of faces on which boundary conditions are applied:
Definition Domaine_VF.h:512
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
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
Neumann_sortie_libre This class represents an open boundary without imposed velocity.
double val_ext(int i) const override
Returns the value of the i-th component of the field imposed on the exterior of the boundary.
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_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_
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
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