TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Diff_VEF_Face_Penalise.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#include <Op_Diff_VEF_Face_Penalise.h>
16#include <Dirichlet_paroi_fixe.h>
17
18
19Implemente_instanciable(Op_Diff_VEF_Face_Penalise,"Op_Diff_VEFpenalise_P1NC",Op_Diff_VEF_Face);
20
21/* Mandatory implementation of the printOn() function */
23printOn(Sortie& s ) const
24{
25 return s << que_suis_je() ;
26}
27
28/* Mandatory implementation of the readOn() function */
30{
31 /* IMPORTANT NOTE: this class was created by derivation but
32 * it should only be applied to non-turbulent Navier-Stokes equations,
33 * hence the following checks.
34 */
35
36 Cerr<<"In Op_Diff_VEF_Face_Penalise::readOn()"<<finl;
37
38 /* Check problem dimension since the theory has only been validated
39 * in 2D.
40 */
41 if (dimension != 2)
42 {
43 Cerr << "Error in Op_Diff_VEF_Face_Penalise::readOn()" << finl;
44 Cerr << "Problem dimension must be 2" << finl;
46 }
47
48 return is ;
49}
50
51/*
52 *
53 *
54 *
55 *
56 *
57 */
58
59/*! @brief Method that computes the contribution of the operator.
60 *
61 */
63calculer(const DoubleTab& inconnue, DoubleTab& resu) const
64{
65 resu = 0.;
66 return ajouter(inconnue,resu);
67}
68
69/*
70 *
71 *
72 *
73 *
74 *
75 */
76
77/*! @brief Method that computes the velocity at time n+1 when the explicit scheme is used.
78 *
79 */
81ajouter(const DoubleTab& inconnue, DoubleTab& resu) const
82{
83 // Cerr << "Entering ajouter() of penalisation" << finl;
84 int nb_composante,numero_global_face,local;
85 int face_penalisation,face;
86 double coeff;
87 IntList voisinage_ordre1,voisinage_ordre1_strict;
88 IntList voisinage_ordre2,voisinage_ordre2_strict;
89 IntList ensemble_faces;
90
91 /* Compute the result due to the penalisation matrix
92 * i.e. sum_j U_j P_i,j where P_i,j is the term of the
93 * penalisation matrix.
94 */
95 for (nb_composante = 0; nb_composante < dimension; nb_composante++)
96 {
97 for (numero_global_face = 0; numero_global_face < domaine_vef().nb_faces();
98 numero_global_face++)
99 {
100 /* Compute the neighbourhoods of numero_global_face */
101 voisinage(numero_global_face,voisinage_ordre1);
102 voisinage(voisinage_ordre1,voisinage_ordre2);
103 reduction(voisinage_ordre1,voisinage_ordre2,voisinage_ordre2_strict);
104 // Cerr << "Nombre iterations " << numero_global_face << finl;
105 // Cerr << "Nombre de faces " << domaine_vef().nb_faces() << finl;
106
107 /* Compute resu(numero_face_global,nb_comp)
108 * for voisinage_ordre2_strict
109 */
110 for (local = 0 ; local < voisinage_ordre2_strict.size(); local++)
111 {
112 face = voisinage_ordre2_strict[local];
113 faces_communes(numero_global_face,face,ensemble_faces);
114 // Cerr << "Taille voisinage_ordre_1 " << voisinage_ordre1.size()
115 // << finl;
116 // Cerr << "Taille voisinage_ordre2 " << voisinage_ordre2.size()
117 // << finl;
118 // Cerr << "Taille voisinage_ordre2_strict " << voisinage_ordre2_strict.size() << finl;
119 // Cerr << "Taille ensemble_faces " << ensemble_faces.size() << finl;
120
121 // if (ensemble_faces.size() != 1)
122 // {
123 // Cerr << "Erreur dans ajouter() de la penalisation." << finl;
124 // Process::exit();
125 // }
126
127 for (int mm = 0; mm < ensemble_faces.size(); mm++)
128 {
129 face_penalisation = ensemble_faces[mm];
130
131 resu(numero_global_face,nb_composante) +=
132 inconnue(face,nb_composante)*
133 signe(numero_global_face,face)*
134 coefficient_penalisation(face_penalisation)*
135 longueur(face_penalisation)*
136 1./3.;
137 }
138
139 }
140
141 /* Compute resu(numero_global_face,nb_comp)
142 * for voisinage_ordre1_strict
143 */
144 for (local = 0 ; local < voisinage_ordre1_strict.size(); local++)
145 {
146 assert(voisinage_ordre1_strict.size() == 2
147 || voisinage_ordre1_strict.size() == 4);
148
149 face = voisinage_ordre1_strict[local];
150 face_penalisation = autre_face(numero_global_face,face);
151
152 resu(numero_global_face,nb_composante) +=
153 inconnue(face,nb_composante)*
154 coefficient_penalisation(face_penalisation)*
155 longueur(face_penalisation)*
156 (-1./3.);
157 }
158
159 /* Case 1: the face under consideration is on the domain boundary
160 * and numero_global_face = face.
161 */
162 if (numero_global_face < domaine_vef().nb_faces_bord())
163 for (local = 0; local < voisinage_ordre1.size(); local++)
164 {
165 assert(voisinage_ordre1.size() == 3);
166
167 face_penalisation = voisinage_ordre1[local];
168
169 if (numero_global_face == face_penalisation)
170 coeff = 1.;
171 else
172 coeff = 1./3.;
173
174 resu(numero_global_face,nb_composante) +=
175 inconnue(numero_global_face,nb_composante) *
176 coeff *
177 coefficient_penalisation(face_penalisation)*
178 longueur(face_penalisation);
179 }
180
181 /* Case 2: the face is internal and numero_global_face = face */
182 else
183 for (local = 0; local < voisinage_ordre1_strict.size(); local++)
184 {
185 assert( voisinage_ordre1_strict.size() == 4);
186
187 face_penalisation = voisinage_ordre1_strict[local];
188
189 resu(numero_global_face,nb_composante) +=
190 inconnue(numero_global_face,nb_composante) *
191 coefficient_penalisation(face_penalisation)*
192 longueur(face_penalisation)*
193 1./3.;
194 }
195 }
196 }
197
198
199 /* Add the classical diffusion matrix */
200 Op_Diff_VEF_Face::ajouter(inconnue,resu);
201
202 // Cerr << "Exiting calcul_matrice_de_penalisation_" << finl;
203 return resu;
204}
205
206/*
207 *
208 *
209 *
210 *
211 *
212 */
213
214/*! @brief Method computing the neighbourhood of a face.
215 *
216 */
218voisinage(const int Numero_face, IntList& Voisinage) const
219{
220 // Cerr << "Entering voisinage for a face index" << finl;
221
222 /* Clear the list Voisinage to avoid surprises */
223 if (! Voisinage.est_vide() ) Voisinage.vide();
224
225 /* Declaration of the main local parameters. */
226 int numero_local;
227
228 /* The number of faces per element in the discretisation domain.
229 * NOTE: prisms are excluded.
230 */
231 const int nb_faces_element = domaine().nb_faces_elem();
232
233 /* The neighbouring elements of Numero_face */
234 const int voisin1 = domaine_vef().face_voisins(Numero_face,1);
235 const int voisin2 = domaine_vef().face_voisins(Numero_face,0);
236
237 /* Retrieve the faces of voisin* and inject them into the list Voisinage.
238 * The element must exist, hence the first test.
239 */
240 if (voisin1 != -1)
241 {
242 for (numero_local = 0; numero_local < nb_faces_element; numero_local++)
243 {
244 /* Retrieve the global index of each face of voisin* */
245 const int numero_global_face =
246 domaine_vef().elem_faces(voisin1,numero_local);
247
248 /* Then store this index in the list Voisinage. */
249 Voisinage.add_if_not(numero_global_face);
250
251 }// end for
252
253 }// end if
254
255 if (voisin2 != -1)
256 {
257 for (numero_local = 0; numero_local < nb_faces_element; numero_local++)
258 {
259 /* Retrieve the global index of each
260 * face of numero_element_*
261 */
262 const int numero_global_face =
263 domaine_vef().elem_faces(voisin2,numero_local);
264
265 /* Then store this index in the list Voisinage. */
266 Voisinage.add_if_not(numero_global_face);
267
268 }// end for
269
270 }//end if
271
272 // Cerr << "Exiting voisinage for a face index" << finl;
273}
274
275/*
276 *
277 *
278 *
279 *
280 *
281 */
282
283/*! @brief Method computing the neighbourhood of a list of faces.
284 *
285 */
287voisinage(const IntList& Ensemble_faces, IntList& Voisinage) const
288{
289 // Cerr << "Entering voisinage for a set of faces" << finl;
290
291 /* Clear the list Voisinage to avoid surprises */
292 if (! Voisinage.est_vide() ) Voisinage.vide();
293
294 /* Declaration of the main local parameters. */
295 int nb_elements_Ensemble_faces,nb_elements_liste_temporaire;
296 IntList liste_temporaire;
297
298 for (nb_elements_Ensemble_faces = 0;
299 nb_elements_Ensemble_faces < Ensemble_faces.size();
300 nb_elements_Ensemble_faces++)
301 {
302 /* Loop-internal parameter */
303 const int numero_face_dans_Ensemble_faces =
304 Ensemble_faces[nb_elements_Ensemble_faces];
305
306 /* Clear the temporary list each time we change face */
307 if (! liste_temporaire.est_vide() ) liste_temporaire.vide();
308
309 /* Place the neighbourhood of numero_face_dans_Ensemble_faces
310 * into the temporary list.
311 */
312 voisinage(numero_face_dans_Ensemble_faces,liste_temporaire);
313 // Cerr << "Taille liste temporaire " << liste_temporaire.size() << finl;
314
315
316 for (nb_elements_liste_temporaire = 0;
317 nb_elements_liste_temporaire < liste_temporaire.size();
318 nb_elements_liste_temporaire++)
319 {
320 // Cerr << "les elements " << liste_temporaire[nb_elements_liste_temporaire] << finl;
321 /* Second-loop-internal parameter */
322 const int numero_face_dans_liste_temporaire =
323 liste_temporaire[nb_elements_liste_temporaire];
324
325 /* Finally, store in Voisinage */
326 Voisinage.add_if_not(numero_face_dans_liste_temporaire);
327
328 }// end second for
329
330 }// end first for
331
332 // Cerr << "Exiting voisinage for a set of faces" << finl;
333}
334
335/*
336 *
337 *
338 *
339 *
340 *
341 */
342
343
345signe(const int Face1, const int Face2) const
346{
347 // Cerr << "Entering signe" << finl;
348
349 /* Local parameters of the procedure */
350 int numero_local;
351
352 /* Retrieve the number of vertices per face in the discretised domain.
353 * NOTE: prismes are excluded by convention.
354 */
355 const int nb_sommets_par_face = domaine_vef().nb_som_face();
356
357 /* Create a list containing the vertices of Face2 */
358 IntList sommets_Face2;
359
360 for (numero_local = 0 ; numero_local < nb_sommets_par_face ; numero_local++)
361 sommets_Face2.add(domaine_vef().face_sommets(Face2,numero_local));
362
363 /* Check whether any vertices of Face2 belong to Face1.
364 * If yes, return 1; otherwise return -1.
365 */
366 for (numero_local = 0; numero_local < nb_sommets_par_face ; numero_local++)
367 if ( sommets_Face2.contient(domaine_vef().face_sommets(Face1,numero_local)))
368 return 1.;
369
370 return -1.;
371
372 // Cerr << "Exiting signe" << finl;
373}
374
375/*
376 *
377 *
378 *
379 *
380 *
381 */
382
383/*! @brief Member function returning the penalisation coefficient associated with each face of the primary mesh.
384 *
385 */
387coefficient_penalisation(const int Numero_face) const
388{
389 // Cerr << "Entering coefficient_penalisation" << finl;
390 /* Initialisation of local parameters */
391 double eta=0.;
392 double coefficientpenalisation = 0.;
393
394 const int voisin1 =
395 domaine_vef().face_voisins(Numero_face,1);
396
397 const int voisin2 =
398 domaine_vef().face_voisins(Numero_face,0);
399
400 if (voisin1 == -1 && voisin2 == -1)
401 {
402 Cerr << "Error in Op_Dift_standard_Face_VEF_penalise::"
403 << "coefficient_penalisation()" << finl;
405 }
406
407 if (voisin1 != -1 && voisin2 != -1)
408 {
409 /* Compute the penalisation coefficients */
410 coefficientpenalisation = 1./diametre(voisin1);
411 eta = 1./diametre(voisin2);
412
413 coefficientpenalisation = std::min(coefficientpenalisation,eta);
414 }
415
416 if (voisin1 == -1)
417 coefficientpenalisation = 1./diametre(voisin2);
418
419 if (voisin2 == -1)
420 coefficientpenalisation = 1./diametre(voisin1);
421
422 return coefficientpenalisation;
423 // Cerr << "Exiting coefficient_penalisation" << finl;
424}
425
426/*
427 *
428 *
429 *
430 *
431 *
432 */
433
434/*! @brief Member function returning the list of faces belonging to the neighbourhood of both Face1 AND Face2.
435 *
436 */
438faces_communes(const int Face1,const int Face2,
439 IntList& Faces_communes) const
440{
441
442 // Cerr <<"Entering faces_communes" << finl;
443 /* First clear Faces_communes to avoid errors. */
444 if (! Faces_communes.est_vide() ) Faces_communes.vide();
445
446 /* Declaration of local parameters of the procedure */
447 IntList voisinage_Face1,voisinage_Face2;
448 int nb_element_voisinage_Face2;
449
450 /* Compute the neighbourhoods of both Face1 and Face2 */
451 voisinage(Face1,voisinage_Face1);
452 voisinage(Face2,voisinage_Face2);
453
454 /* Then find the faces common to these 2 neighbourhoods. */
455 for (nb_element_voisinage_Face2 = 0;
456 nb_element_voisinage_Face2 < voisinage_Face2.size();
457 nb_element_voisinage_Face2++)
458 {
459 const int numero_face_voisinage_Face2 =
460 voisinage_Face2[nb_element_voisinage_Face2];
461
462 if (voisinage_Face1.contient(numero_face_voisinage_Face2))
463 Faces_communes.add_if_not(numero_face_voisinage_Face2);
464
465 }// end for
466
467 // Cerr << "Exiting faces_communes" << finl;
468}
469
470/*
471 *
472 *
473 *
474 *
475 *
476 */
477
479reduction(const IntList& Liste1,const IntList& Liste2,
480 IntList& Liste_reduite) const
481{
482 // Cerr << "Entering reduction" << finl;
483 /* Clear Liste_reduite to avoid errors */
484 if (! Liste_reduite.est_vide() ) Liste_reduite.vide();
485
486 /* Declaration of local parameters of the procedure */
487 const IntList *liste_de_plus_petite_taille,*liste_de_plus_grande_taille;
488 int nb_element_dans_liste;
489
490 /* Check the sizes of the lists passed as parameters, then
491 * allocate accordingly.
492 */
493 if (Liste1.size() >= Liste2.size())
494 {
495 liste_de_plus_petite_taille = &Liste2;
496 liste_de_plus_grande_taille = &Liste1;
497 }
498 else
499 {
500 liste_de_plus_petite_taille = &Liste1;
501 liste_de_plus_grande_taille = &Liste2;
502 }
503
504 /* Remove from liste_de_plus_grande_taille the elements
505 * of liste_de_plus_petite_taille that are present in it.
506 */
507 for (int ll = 0 ; ll < (*liste_de_plus_grande_taille).size() ; ll++)
508 Liste_reduite.add( (*liste_de_plus_grande_taille)[ll] );
509
510 for (nb_element_dans_liste = 0;
511 nb_element_dans_liste < (*liste_de_plus_petite_taille).size();
512 nb_element_dans_liste++)
513 if
514 (Liste_reduite.contient( (*liste_de_plus_petite_taille)
515 [nb_element_dans_liste] ) )
516 Liste_reduite.suppr( (*liste_de_plus_petite_taille)
517 [nb_element_dans_liste] );
518
519 // Cerr << "Exiting reduction" << finl;
520}
521
522
523/*
524 *
525 *
526 *
527 *
528 *
529 */
530
531/*! @brief Member function returning the index of the element containing both Face1 and Face2 if it exists, or -1 otherwise.
532 *
533 */
535element_commun(const int Face1,const int Face2) const
536{
537 // Cerr << "Entering element_commun" << finl;
538
539 /* Neighbouring elements of Face1 */
540 const int voisin1_Face1 = domaine_vef().face_voisins(Face1,1);
541 const int voisin2_Face1 = domaine_vef().face_voisins(Face1,0);
542
543 /* Neighbouring elements of Face2 */
544 const int voisin1_Face2 = domaine_vef().face_voisins(Face2,1);
545 const int voisin2_Face2 = domaine_vef().face_voisins(Face2,0);
546
547 /* Search for the common element */
548 if (voisin1_Face1 != -1)
549 if (voisin1_Face1 == voisin1_Face2 || voisin1_Face1 == voisin2_Face2)
550 return voisin1_Face1;
551
552 if (voisin2_Face1 != -1)
553 if (voisin2_Face1 == voisin1_Face2 || voisin2_Face1 == voisin2_Face2)
554 return voisin2_Face1;
555
556 Cerr << " Op_Diff_VEF_Face_Penalise::element_commun()" << finl;
557 Cerr << "Warning: face " << Face1 << " and face " << Face2
558 << " have no common element" << finl;
559 Cerr << "Exiting element_commun" << finl;
560 return -1;
561
562}
563
564/*
565 *
566 *
567 *
568 *
569 *
570 */
571
572/*! @brief Member function returning the 3rd face of element Element if Face1 and Face2 belong to the same element.
573 *
574 * Returns -1 otherwise.
575 *
576 */
578autre_face(const int Face1, const int Face2)
579const
580{
581 // Cerr << "Entering autre_face" << finl;
582 /* Declaration of local variables */
583 int numero_local,lautre_face=-1;
584 int elem_commun = element_commun(Face1,Face2);
585
586 /* Number of faces per element in the discretisation domain.
587 * NOTE: prismes are excluded.
588 */
589 if (elem_commun == -1)
590 {
591 Cerr << "Function element_commun" << finl;
592 Cerr << "The 2 faces do not belong to the same element." << finl;
594 return lautre_face;
595 }
596
597 const int nb_faces_element = domaine().nb_faces_elem();
598
599 for (numero_local = 0; numero_local < nb_faces_element; numero_local++)
600
601 {
602 /* Retrieve the global index of each face of Element */
603 const int numero_global_face =
604 domaine_vef().elem_faces(elem_commun,numero_local);
605
606 if ( numero_global_face != Face1 && numero_global_face != Face2)
607 {
608 lautre_face = numero_global_face;
609 break;
610 }
611
612 }// end for
613
614 return lautre_face;
615
616}
617/*
618 *
619 *
620 *
621 *
622 *
623 */
624
625
int nb_faces() const
Returns the total number of faces.
Definition Domaine_VF.h:471
int nb_som_face() const
Returns the number of vertices per face.
Definition Domaine_VF.h:493
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 face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in direction i.
Definition Domaine_VF.h:418
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
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
void reduction(const IntList &Liste1, const IntList &Liste2, IntList &Liste_reduite) const
void faces_communes(const int Face1, const int Face2, IntList &Face_commune) const
Member function returning the list of faces belonging to the neighbourhood of both Face1 AND Face2.
double signe(const int Face1, const int Face2) const
double diametre(const int Element) const
DoubleTab & ajouter(const DoubleTab &inconnue, DoubleTab &resu) const override
Method that computes the velocity at time n+1 when the explicit scheme is used.
void voisinage(const int Numero_face, IntList &Voisinage) const
Method computing the neighbourhood of a face.
DoubleTab & calculer(const DoubleTab &inconnue, DoubleTab &resu) const override
Method that computes the contribution of the operator.
double coefficient_penalisation(const int Numero_face) const
Member function returning the penalisation coefficient associated with each face of the primary mesh.
double longueur(const int Face) const
int autre_face(const int Face1, const int Face2) const
Member function returning the 3rd face of element Element if Face1 and Face2 belong to the same eleme...
int element_commun(const int Face1, const int Face2) const
Member function returning the index of the element containing both Face1 and Face2 if it exists,...
class Op_Diff_VEF_Face
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
const Domaine_VEF & domaine_vef() const
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 est_vide() const
TRUSTList & add(_TYPE_)
insertion en queue
Definition TRUSTList.tpp:85
TRUSTList & add_if_not(_TYPE_)
Ajout d'un element a la liste ssi il n'existe pas deja.
void suppr(_TYPE_)
Supprime un element contenu dans la liste.
int contient(_TYPE_) const
Verifie si un element appartient ou non a la liste.
void vide()
Vide la liste.
int size() const
Definition TRUSTList.h:68