TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Conv_Amont_old_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_Amont_old_VEF_Face.h>
17#include <Neumann_sortie_libre.h>
18#include <Hexaedre_VEF.h>
19#include <Milieu_base.h>
20#include <Periodique.h>
21
22Implemente_instanciable(Op_Conv_Amont_old_VEF_Face,"Op_Conv_Amont_old_VEF_P1NC",Op_Conv_VEF_base);
23// XD convection_amont_old convection_deriv amont_old NO_BRACE Only for VEF discretization, obsolete keyword, see amont.
24
26{
27 return s << que_suis_je() ;
28}
29
31{
32 return s ;
33}
34
35
36//// convbis corresponds to the calculation of -1*convection_term
37//
38static void convbis(const double psc,const int num1,const int num2,
39 const DoubleTab& transporte,const int ncomp,
40 DoubleTab& resu, DoubleVect& fluent)
41{
42 int comp,amont;
43 double flux;
44
45 if (psc >= 0)
46 {
47 amont = num1;
48 fluent[num2] += psc;
49 }
50 else
51 {
52 amont = num2;
53 fluent[num1] -= psc;
54 }
55
56 for (comp=0; comp<ncomp; comp++)
57 {
58 flux = transporte(amont,comp)*psc;
59 resu(num1,comp) -= flux;
60 resu(num2,comp) += flux;
61 }
62}
63static void convbisimplicite(const double psc,const int num1,const int num2,
64 const DoubleTab& transporte,const int ncomp,
65 Matrice_Morse& matrice)
66{
67 const auto& tab1 = matrice.get_set_tab1();
68 const auto& tab2 = matrice.get_set_tab2();
69 auto& coeff = matrice.get_set_coeff();
70
71 for (int comp=0; comp<ncomp; comp++)
72 {
73 if (psc >=0)
74 {
75 for (auto k=tab1[num1*ncomp+comp]-1; k<tab1[num1*ncomp+comp+1]-1; k++)
76 {
77 if (tab2[k]-1== num1*ncomp+comp)
78 coeff(k) += psc;
79 }
80 for (auto k=tab1[num2*ncomp+comp]-1; k<tab1[num2*ncomp+comp+1]-1; k++)
81 {
82 if (tab2[k]-1== num1*ncomp+comp)
83 coeff(k) -= psc;
84 }
85 }
86 else
87 {
88 for (auto k=tab1[num1*ncomp+comp]-1; k<tab1[num1*ncomp+comp+1]-1; k++)
89 {
90 if (tab2[k]-1== num2*ncomp+comp)
91 coeff(k) += psc;
92 }
93 for (auto k=tab1[num2*ncomp+comp]-1; k<tab1[num2*ncomp+comp+1]-1; k++)
94 {
95 if (tab2[k]-1== num2*ncomp+comp)
96 coeff(k) -= psc;
97 }
98 }
99 }
100}
101
102
103DoubleTab& Op_Conv_Amont_old_VEF_Face::ajouter(const DoubleTab& transporte,
104 DoubleTab& resu) const
105{
106 // Cerr<<"Op_Conv_Amont_old_VEF_Face::ajouter"<<finl;
107 const Domaine_Cl_VEF& domaine_Cl_VEF = la_zcl_vef.valeur();
108 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
109 const Champ_Inc_base& la_vitesse=vitesse_.valeur();
110 const IntTab& elem_faces = domaine_VEF.elem_faces();
111 const DoubleTab& face_normales = domaine_VEF.face_normales();
112 const auto& facette_normales = domaine_VEF.facette_normales();
113 const DoubleVect& porosite_face = equation().milieu().porosite_face();
114 const Domaine& domaine = domaine_VEF.domaine();
115 const Elem_VEF_base& type_elem=domaine_VEF.type_elem();
116 const int nfa7 = type_elem.nb_facette();
117 const int nb_elem_tot = domaine_VEF.nb_elem_tot();
118 const IntVect& rang_elem_non_std = domaine_VEF.rang_elem_non_std();
119 const DoubleTab& normales_facettes_Cl = domaine_Cl_VEF.normales_facettes_Cl();
120 int nfac = domaine.nb_faces_elem();
121 int nsom = domaine.nb_som_elem();
122 int nb_som_facette = domaine.type_elem()->nb_som_face();
123 const Elem_geom_base& elem_geom = domaine.type_elem().valeur();
124 if ( sub_type(Hexaedre_VEF,elem_geom))
125 {
126 nb_som_facette--;
127 }
128
129 // MODIF SB su 10/09/03
130 // For the following 3 elements, there are as many vertices as faces
131 // making up the geometric element.
132 // Problem with hexahedra: 8 vertices and 6 faces, so using the array
133 // face[i] no longer works.
134 // The method retained to avoid computing velocity at vertices without
135 // the shape functions is therefore not usable for hexahedra,
136 // where the Face=>vertices array exists but not its inverse.
137 // Too costly; porosity extension to hexahedra is not done for now.
138 // ||(nom_elem=="Quadri_VEF")
139 int istetra=0;
140 Nom nom_elem=type_elem.que_suis_je();
141 if ((nom_elem=="Tetra_VEF")||(nom_elem=="Tri_VEF"))
142 istetra=1;
143
144 // For the convection treatment, standard polyhedra (not "seeing" boundary conditions)
145 // are distinguished from non-standard polyhedra (having at least one boundary face).
146 // A standard polyhedron has n facets on which the convection scheme is applied.
147 // For a non-standard polyhedron with Dirichlet boundary conditions, part of its
148 // facets are carried by the boundary faces.
149 // In short, for a polyhedron the convection treatment depends on the type
150 // (triangle, tetrahedron ...) and the number of Dirichlet faces.
151
152 double psc;
153 int poly,face_adj,fa7,i,j,n_bord,num_face, rang ,itypcl, num10,num20,num_som;
154 const int ncomp_ch_transporte = transporte.line_size();
155
156 IntVect face(nfac);
157 DoubleVect vs(dimension);
158 DoubleVect vc(dimension);
159 DoubleTab vsom(nsom,dimension);
160 DoubleVect cc(dimension);
161
162 // Reset the array used for
163 // computing the stability time step
164 fluent_ = 0;
165
166 // Special treatment for periodic faces
167
168 int nb_faces_perio = 0;
169 // Loop to count the number of periodic faces
170 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
171 {
172 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
173 if (sub_type(Periodique,la_cl.valeur()))
174 {
175 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
176 nb_faces_perio += le_bord.nb_faces();
177 }
178 }
179
180 DoubleTab tab(nb_faces_perio,ncomp_ch_transporte);
181 // Loop to fill tab
182 nb_faces_perio=0;
183 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
184 {
185 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
186 if (sub_type(Periodique,la_cl.valeur()))
187 {
188 // const Periodique& la_cl_perio = ref_cast(Periodique, la_cl.valeur());
189 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
190 int num1 = le_bord.num_premiere_face();
191 int num2 = num1 + le_bord.nb_faces();
192 for (num_face=num1; num_face<num2; num_face++)
193 {
194 for (int comp=0; comp<ncomp_ch_transporte; comp++)
195 tab(nb_faces_perio,comp) = resu(num_face,comp);
196 nb_faces_perio++;
197 }
198 }
199 }
200
201 IntVect compteur(nsom);
202 compteur = 0;
203 vsom=0.;
204
205 // Non-standard polyhedra are grouped into 2 sets in Domaine_VEF:
206 // - boundary and joint polyhedra
207 // - boundary and non-joint polyhedra
208 // Polyhedra are processed in the order in which they appear in the domain
209
210 // loop over polyhedra
211 const IntTab& KEL=type_elem.KEL();
212 for (poly=0; poly<nb_elem_tot; poly++)
213 {
214 rang = rang_elem_non_std(poly);
215 if (rang==-1)
216 itypcl=0;
217 else
218 itypcl=domaine_Cl_VEF.type_elem_Cl(rang);
219
220 // compute the face indices of the polyhedron
221 for (face_adj=0; face_adj<nfac; face_adj++)
222 face[face_adj]= elem_faces(poly,face_adj);
223 // keep this part
224 for (j=0; j<dimension; j++)
225 {
226 vs[j] = la_vitesse.valeurs()(face[0],j)*porosite_face(face[0]);
227 for (i=1; i<nfac; i++)
228 vs[j]+= la_vitesse.valeurs()(face[i],j)*porosite_face(face[i]);
229 }
230
231 // compute velocity at the vertices of the polyhedra
232 // int ncomp;
233 if (istetra==1)
234 {
235 for (j=0; j<nsom; j++)
236 for (int ncomp=0; ncomp<Objet_U::dimension; ncomp++)
237 vsom(j,ncomp) =vs[ncomp] - Objet_U::dimension*la_vitesse.valeurs()(face[j],ncomp)*porosite_face(face[j]);
238 }
239 else
240 {
241 // to be valid with hexahedra
242 // Use the shape functions implemented in class Champs_P1_impl or Champs_Q1_impl
243 // int ncomp;
244 for (j=0; j<nsom; j++)
245 {
246 num_som = domaine.sommet_elem(poly,j);
247 for (int ncomp=0; ncomp<dimension; ncomp++)
248 vsom(j,ncomp) = la_vitesse.valeur_a_sommet_compo(num_som,poly,ncomp);
249 }
250 }
251
252 type_elem.calcul_vc(face,vc,vs,vsom,vitesse(),itypcl,porosite_face);
253
254 // Loop over facets of the polyhedron
255 for (fa7=0; fa7<nfa7; fa7++)
256 {
257 if (rang==-1)
258 for (i=0; i<dimension; i++)
259 cc[i] = facette_normales(poly,fa7,i);
260 else
261 for (i=0; i<dimension; i++)
262 cc[i] = normales_facettes_Cl(rang,fa7,i);
263
264 // Apply the convection scheme to each vertex of the facet
265 // Process the vertex/vertices that are also vertices of the polyhedron
266 for (i=0; i<nb_som_facette-1; i++)
267 {
268 psc =0;
269 for (j=0; j<dimension; j++)
270 psc+= vsom(KEL(i+2,fa7),j)*cc[j];
271
272 // Loop over facets of the polyhedron
273 psc /= nb_som_facette;
274 num10 = face[KEL(0,fa7)];
275 num20 = face[KEL(1,fa7)];
276 //psc *= (porosite_face(num1)+porosite_face(num2))/2. ;
277
278 convbis(psc,num10,num20,transporte,ncomp_ch_transporte,resu,fluent_);
279 }
280 // Process the vertex coinciding with the centre of gravity of the polyhedron
281 psc=0;
282 for (j=0; j<dimension; j++)
283 psc += vc[j]*cc[j];
284 psc /= nb_som_facette;
285 num10 = face[KEL(0,fa7)];
286 num20 = face[KEL(1,fa7)];
287 //psc *= (porosite_face(num1)+porosite_face(num2))/2. ;
288
289 convbis(psc,num10,num20,transporte,ncomp_ch_transporte,resu,fluent_);
290 }
291
292 } // end of loop
293 // if(Process::is_sequential())
294 // Process::Journal()<<"OpVEFFaAmont ap interne resu[8]="<<resu(8,0)<<","<<resu(8,1)<<finl;
295 // if((Process::nproc()==2)&&(Process::me()==0))
296 // Process::Journal()<<"OpVEFFaAmont ap interne resu[4]="<<resu(4,0)<<","<<resu(4,1)<<finl;
297
298 int voisine;
299 nb_faces_perio = 0;
300 double diff1,diff2;
301
302 // Dimensioning the array of convective fluxes at the boundary
303 // of the computational domain
304 DoubleTab& flux_b = flux_bords_;
305 flux_b.resize(domaine_VEF.nb_faces_bord(),ncomp_ch_transporte);
306 flux_b = 0.;
307
308 // Loop over the boundaries to process the boundary conditions
309 // a convection term is included for Neumann_sortie_libre boundary conditions only
310
311 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
312 {
313
314 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
315
316 if (sub_type(Neumann_sortie_libre,la_cl.valeur()))
317 {
318 const Neumann_sortie_libre& la_sortie_libre = ref_cast(Neumann_sortie_libre, la_cl.valeur());
319 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
320 int num1 = le_bord.num_premiere_face();
321 int num2 = num1 + le_bord.nb_faces();
322 for (num_face=num1; num_face<num2; num_face++)
323 {
324 psc =0;
325 for (i=0; i<dimension; i++)
326 psc += la_vitesse.valeurs()(num_face,i)*face_normales(num_face,i)*porosite_face(num_face);
327 if (psc>0)
328 {
329 for (i=0; i<ncomp_ch_transporte; i++)
330 {
331 resu(num_face,i) -= psc*transporte(num_face,i);
332 flux_b(num_face,i) -= psc*transporte(num_face,i);
333 }
334 }
335 else
336 {
337 for (i=0; i<ncomp_ch_transporte; i++)
338 {
339 resu(num_face,i) -= psc*la_sortie_libre.val_ext(num_face-num1,i);
340 flux_b(num_face,i) -= psc*la_sortie_libre.val_ext(num_face-num1,i);
341 }
342 fluent_[num_face] -= psc;
343 }
344 }
345 }
346 else if (sub_type(Periodique,la_cl.valeur()))
347 {
348 const Periodique& la_cl_perio = ref_cast(Periodique, la_cl.valeur());
349 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
350 int num1 = le_bord.num_premiere_face(), num2 = num1 + le_bord.nb_faces();
351 IntVect fait(le_bord.nb_faces());
352 fait = 0;
353 for (num_face=num1; num_face<num2; num_face++)
354 {
355 if (fait[num_face-num1] == 0)
356 {
357 voisine = la_cl_perio.face_associee(num_face-num1) + num1;
358 for (int comp=0; comp<ncomp_ch_transporte; comp++)
359 {
360 diff1 = resu(num_face,comp)-tab(nb_faces_perio,comp);
361 diff2 = resu(voisine,comp)-tab(nb_faces_perio+voisine-num_face,comp);
362 resu(voisine,comp) += diff1;
363 resu(num_face,comp) += diff2;
364 flux_b(voisine,comp) += diff1;
365 flux_b(num_face,comp) += diff2;
366 }
367
368 fait[num_face-num1]= 1;
369 fait[voisine-num1] = 1;
370 }
371 nb_faces_perio++;
372 }
373 }
374 }
375 modifier_flux(*this);
376 return resu;
377
378}
379
380
381void Op_Conv_Amont_old_VEF_Face::ajouter_contribution(const DoubleTab& transporte, Matrice_Morse& matrice ) const
382{
383 const Domaine_Cl_VEF& domaine_Cl_VEF = la_zcl_vef.valeur();
384 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
385 const Champ_Inc_base& la_vitesse=vitesse_.valeur();
386 const IntTab& elem_faces = domaine_VEF.elem_faces();
387 const DoubleTab& face_normales = domaine_VEF.face_normales();
388 const auto& facette_normales = domaine_VEF.facette_normales();
389 const Domaine& domaine = domaine_VEF.domaine();
390 const Elem_VEF_base& type_elem = domaine_VEF.type_elem();
391 const int nfa7 = type_elem.nb_facette();
392 const int nb_elem_tot = domaine_VEF.nb_elem_tot();
393 const IntVect& rang_elem_non_std = domaine_VEF.rang_elem_non_std();
394 const DoubleVect& porosite_face = equation().milieu().porosite_face();
395 const DoubleTab& normales_facettes_Cl = domaine_Cl_VEF.normales_facettes_Cl();
396 int nfac = domaine.nb_faces_elem(), nsom = domaine.nb_som_elem(), nb_som_facette = domaine.type_elem()->nb_som_face();
397
398 // For the convection treatment, standard polyhedra (not "seeing" boundary conditions)
399 // are distinguished from non-standard polyhedra (having at least one boundary face).
400 // A standard polyhedron has n facets on which the convection scheme is applied.
401 // For a non-standard polyhedron with Dirichlet boundary conditions, part of its
402 // facets are carried by the boundary faces.
403 // In short, for a polyhedron the convection treatment depends on the type
404 // (triangle, tetrahedron ...) and the number of Dirichlet faces.
405
406 double psc;
407 //DoubleTab pscl=0;
408 int poly,face_adj,fa7,i,j,n_bord, num_face, rang ,itypcl, num10,num20,num_som;
409 const int ncomp_ch_transporte = transporte.line_size();
410
411 IntVect face(nfac);
412 DoubleVect vs(dimension);
413 DoubleVect vc(dimension);
414 DoubleTab vsom(nsom,dimension);
415 DoubleVect cc(dimension);
416 auto& tab1 = matrice.get_set_tab1();
417 auto& tab2 = matrice.get_set_tab2();
418 auto& coeff = matrice.get_set_coeff();
419
420 // Special treatment for periodic faces
421 int voisine, nb_faces_perio = 0;
422 double diff1,diff2;
423
424 // Loop to count the number of periodic faces
425 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
426 {
427 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
428 if (sub_type(Periodique,la_cl.valeur()))
429 {
430 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
431 nb_faces_perio += le_bord.nb_faces();
432 }
433 }
434
435 DoubleTab tab(nb_faces_perio,ncomp_ch_transporte);
436
437 // Loop to fill tab
438 nb_faces_perio=0;
439 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
440 {
441 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
442 if (sub_type(Periodique,la_cl.valeur()))
443 {
444 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
445 int num1 = le_bord.num_premiere_face();
446 int num2 = num1 + le_bord.nb_faces();
447 for (num_face=num1; num_face<num2; num_face++)
448 {
449 for (int comp=0; comp<ncomp_ch_transporte; comp++)
450 tab(nb_faces_perio,comp) = coeff(num_face*ncomp_ch_transporte+comp);
451 nb_faces_perio++;
452 }
453 }
454 }
455
456 // Non-standard polyhedra are grouped into 2 sets in Domaine_VEF:
457 // - boundary and joint polyhedra
458 // - boundary and non-joint polyhedra
459 // Polyhedra are processed in the order in which they appear in the domain
460
461 // loop over polyhedra
462 const IntTab& KEL=type_elem.KEL();
463 for (poly=0; poly<nb_elem_tot; poly++)
464 {
465
466 rang = rang_elem_non_std(poly);
467 if (rang==-1)
468 itypcl=0;
469 else
470 itypcl=domaine_Cl_VEF.type_elem_Cl(rang);
471
472 // compute the face indices of the polyhedron
473 for (face_adj=0; face_adj<nfac; face_adj++)
474 face[face_adj]= elem_faces(poly,face_adj);
475
476 // compute velocity at the vertices of the polyhedra
477 for (j=0; j<dimension; j++)
478 {
479 vs[j] = la_vitesse.valeurs()(face[0],j);
480 for (i=1; i<nfac; i++)
481 vs[j]+= la_vitesse.valeurs()(face[i],j);
482 }
483
484 // compute velocity at the vertices of the polyhedra
485 // Use the shape functions implemented in class Champs_P1_impl or Champs_Q1_impl
486
487 int ncomp;
488 for (j=0; j<nsom; j++)
489 {
490 num_som = domaine.sommet_elem(poly,j);
491 for(int kk=0; kk<Objet_U::dimension; kk++)
492 for (ncomp=0; ncomp<dimension; ncomp++)
493 vsom(j,ncomp) = la_vitesse.valeur_a_sommet_compo(num_som,poly,ncomp);
494 }
495
496 // compute vc
497 type_elem.calcul_vc(face,vc,vs,vsom,vitesse(),itypcl,porosite_face);
498
499 // Loop over facets of the polyhedron
500
501 for (fa7=0; fa7<nfa7; fa7++)
502 {
503 if (rang==-1)
504 for (i=0; i<dimension; i++)
505 cc[i] = facette_normales(poly,fa7,i);
506 else
507 for (i=0; i<dimension; i++)
508 cc[i] = normales_facettes_Cl(rang,fa7,i);
509
510 // Apply the convection scheme to each vertex of the facet
511 // Process the vertex/vertices that are also vertices of the polyhedron
512
513 for (i=0; i<nb_som_facette-1; i++)
514 {
515 psc =0;
516
517 /////////////////////////////////////////////////////////////////////
518 // Fill the coefficient array corresponding to convbis
519 /////////////////////////////////////////////////////////////////////
520
521 for (j=0; j<dimension; j++)
522 psc += vsom(KEL(i+2,fa7),j)*cc[j];
523 psc/= nb_som_facette;
524 num10 = face[KEL(0,fa7)];
525 num20 = face[KEL(1,fa7)];
526 convbisimplicite(psc,num10,num20,transporte,ncomp_ch_transporte,matrice);
527
528 } // end of loop over facet vertices.
529
530 // process the vertex coinciding with the centre of gravity of the polyhedron
531 psc=0;
532 for (j=0; j<dimension; j++)
533 psc += vc[j]*cc[j];
534 psc /= nb_som_facette;
535 num10 = face[KEL(0,fa7)];
536 num20 = face[KEL(1,fa7)];
537 convbisimplicite(psc,num10,num20,transporte,ncomp_ch_transporte,matrice);
538
539 } // end of loop over facets.
540
541 } // end of loop over polyhedra.
542
543 // Loop over the boundaries to process the boundary conditions
544 // a convection term is included for Neumann_sortie_libre boundary conditions only
545
546 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
547 {
548 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
549 if (sub_type(Neumann_sortie_libre,la_cl.valeur()))
550 {
551 // const Neumann_sortie_libre& la_sortie_libre = ref_cast(Neumann_sortie_libre, la_cl.valeur());
552 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
553 int num1 = le_bord.num_premiere_face();
554 int num2 = num1 + le_bord.nb_faces();
555 for (num_face=num1; num_face<num2; num_face++)
556 {
557 psc =0;
558 for (i=0; i<dimension; i++)
559 psc += la_vitesse.valeurs()(num_face,i)*face_normales(num_face,i);
560 if (psc>0)
561 {
562 for (j=0; j<ncomp_ch_transporte; j++)
563 {
564 for (auto k=tab1[num_face*ncomp_ch_transporte+j]-1; k<tab1[num_face*ncomp_ch_transporte+j+1]-1; k++)
565 {
566 if (tab2[k]-1==num_face*ncomp_ch_transporte+j)
567 coeff(k) += psc;
568 }
569 }
570 }
571 else /*psc < 0 */
572 {
573 for (j=0; j<ncomp_ch_transporte; j++)
574 {
575 for (auto k=tab1[num_face*ncomp_ch_transporte+j]-1; k<tab1[num_face*ncomp_ch_transporte+j+1]-1; k++)
576 {
577 if (tab2[k]-1==num_face*ncomp_ch_transporte+j)
578 coeff(k) += 0;
579 }
580 }
581 }
582 }
583 }
584 else if (sub_type(Periodique,la_cl.valeur()))
585 {
586 const Periodique& la_cl_perio = ref_cast(Periodique, la_cl.valeur());
587 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
588 int num1 = le_bord.num_premiere_face();
589 int num2 = num1 + le_bord.nb_faces();
590 IntVect fait(le_bord.nb_faces());
591 fait = 0;
592 for (num_face=num1; num_face<num2; num_face++)
593 {
594 if (fait[num_face-num1] == 0)
595 {
596 voisine = la_cl_perio.face_associee(num_face-num1) + num1;
597 for (int comp=0; comp<ncomp_ch_transporte; comp++)
598 {
599 diff1 = -1*tab(nb_faces_perio,comp);
600 diff2 = -1*tab(nb_faces_perio+voisine-num_face,comp);
601
602 for (auto k=tab1[num_face*ncomp_ch_transporte+comp]-1; k<tab1[num_face*ncomp_ch_transporte+1+comp]-1; k++)
603 if (tab2[k]-1==num_face*ncomp_ch_transporte+comp)
604 coeff(k) += diff2;
605
606 for (auto k=tab1[voisine*ncomp_ch_transporte+comp]-1; k<tab1[voisine*ncomp_ch_transporte+1+comp]-1; k++)
607 if (tab2[k]-1==voisine*ncomp_ch_transporte+comp)
608 coeff(k) += diff1;
609 }
610
611 fait[num_face-num1]= 1;
612 fait[voisine-num1] = 1;
613 }
614 nb_faces_perio++;
615 }
616 }
617 }
618}
619
621{
622 const Domaine_Cl_VEF& domaine_Cl_VEF = la_zcl_vef.valeur();
623 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
624 const Champ_Inc_base& la_vitesse=vitesse_.valeur();
625 const DoubleTab& face_normales = domaine_VEF.face_normales();
626 //const Domaine& domaine = domaine_VEF.domaine();
627 //int nfac = domaine.nb_faces_elem();
628 double psc;
629 int i,n_bord, num_face;
630 const int ncomp = resu.line_size();
631
632 //IntVect face(nfac);
633
634 // Special treatment for periodic faces
635 int voisine, nb_faces_perio = 0;
636 double diff1,diff2;
637
638 // Loop to count the number of periodic faces
639 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
640 {
641 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
642 if (sub_type(Periodique,la_cl.valeur()))
643 {
644 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
645 nb_faces_perio += le_bord.nb_faces();
646 }
647 }
648
649 DoubleTab tab(nb_faces_perio,ncomp);
650 // Loop to fill tab
651 nb_faces_perio=0;
652 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
653 {
654 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
655 if (sub_type(Periodique,la_cl.valeur()))
656 {
657 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
658 int num1 = le_bord.num_premiere_face();
659 int num2 = num1 + le_bord.nb_faces();
660 for (num_face=num1; num_face<num2; num_face++)
661 {
662 for (int comp=0; comp<ncomp; comp++)
663 tab(nb_faces_perio,comp) = resu(num_face,comp);
664
665 nb_faces_perio++;
666 }
667 }
668 }
669 // Loop over the boundaries to process the boundary conditions
670 // a convection term is included for Neumann_sortie_libre boundary conditions only
671
672 for (n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
673 {
674 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
675 if (sub_type(Neumann_sortie_libre,la_cl.valeur()))
676 {
677 const Neumann_sortie_libre& la_sortie_libre = ref_cast(Neumann_sortie_libre, la_cl.valeur());
678 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
679 int num1 = le_bord.num_premiere_face();
680 int num2 = num1 + le_bord.nb_faces();
681 for (num_face=num1; num_face<num2; num_face++)
682 {
683 psc =0;
684 for (i=0; i<dimension; i++)
685 psc += la_vitesse.valeurs()(num_face,i)*face_normales(num_face,i);
686 if (psc>0)
687 for (i=0; i<ncomp; i++)
688 resu(num_face,i) += 0;
689 else
690 for (i=0; i<ncomp; i++)
691 resu(num_face,i) -= psc*la_sortie_libre.val_ext(num_face-num1,i);
692 }
693 }
694 else if (sub_type(Periodique,la_cl.valeur()))
695 {
696 const Periodique& la_cl_perio = ref_cast(Periodique, la_cl.valeur());
697 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
698 int num1 = le_bord.num_premiere_face();
699 int num2 = num1 + le_bord.nb_faces();
700 IntVect fait(le_bord.nb_faces());
701 fait = 0;
702 for (num_face=num1; num_face<num2; num_face++)
703 {
704 if (fait[num_face-num1] == 0)
705 {
706 voisine = la_cl_perio.face_associee(num_face-num1) + num1;
707 for (int comp=0; comp<ncomp; comp++)
708 {
709 diff1 = resu(num_face,comp)-tab(nb_faces_perio,comp);
710 diff2 = resu(voisine,comp)-tab(nb_faces_perio+voisine-num_face,comp);
711 resu(voisine,comp) += diff1;
712 resu(num_face,comp) += diff2;
713 }
714
715 fait[num_face-num1]= 1;
716 fait[voisine-num1] = 1;
717 }
718 nb_faces_perio++;
719 }
720 }
721 }
722}
Class Champ_Inc_base.
DoubleTab & valeurs() override
Returns the array of field values at the current time.
virtual double valeur_a_sommet_compo(int, int, int) const
Returns the compo-th coordinate of the values at the element le_poly at the vertex sommet.
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
virtual void calcul_vc(const ArrOfInt &, ArrOfDouble &, const ArrOfDouble &, const DoubleTab &, const Champ_Inc_base &, int, const DoubleVect &) const =0
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
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
auto & get_set_tab2()
auto & get_set_coeff()
auto & get_set_tab1()
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.
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
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_Amont_old_VEF_Face
void contribue_au_second_membre(DoubleTab &) const
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
void ajouter_contribution(const DoubleTab &, Matrice_Morse &) const
class Op_Conv_VEF_base
const Champ_Inc_base & vitesse() const
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
Base class for output streams.
Definition Sortie.h:52
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
int line_size() const
Definition TRUSTVect.tpp:67