TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Op_VDF_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 <Dirichlet_homogene.h>
17#include <Matrice_Morse.h>
18#include <Equation_base.h>
19#include <Op_VDF_Face.h>
20#include <Domaine_Cl_VDF.h>
21#include <Periodique.h>
22#include <Dirichlet.h>
23#include <Symetrie.h>
24
25// TODO : FIXME : a la poubelle
26void Op_VDF_Face::dimensionner(const Domaine_VDF& le_dom, const Domaine_Cl_VDF& le_dom_cl, Matrice_Morse& la_matrice) const
27{
28 // Dimensionnement de la matrice qui devra recevoir les coefficients provenant de la convection, de la diffusion pour le cas des faces.
29 // Cette matrice a une structure de matrice morse.
30 // Nous commencons par calculer les tailles des tableaux tab1 et tab2.
31
32 const DoubleTab& champ_inconnue = le_dom_cl.equation().inconnue().valeurs();
33 const int ndeb = 0, nfin = le_dom.nb_faces_tot(), dimension = Objet_U::dimension, nb_comp = champ_inconnue.line_size();
34 const IntVect& orientation = le_dom.orientation();
35
36 la_matrice.dimensionner(nfin*nb_comp,nfin*nb_comp,0);
37
38 auto& tab1 = la_matrice.get_set_tab1();
39 auto& tab2 = la_matrice.get_set_tab2();
40 auto& coeff = la_matrice.get_set_coeff();
41 coeff = 0;
42 IntVect rang_voisin(nfin);
43 rang_voisin = 1;
44
45 for (int num_face = ndeb; num_face < nfin; num_face++)
46 {
47 const int ori = orientation(num_face), face1 = le_dom.face_amont_princ(num_face,0), face2 = le_dom.face_amont_princ(num_face,1),
48 face3 = le_dom.face_bord_amont(num_face,(ori+1)%dimension,0), face4 = le_dom.face_bord_amont(num_face,(ori+1)%dimension,1);
49
50 if(face1 > -1) (rang_voisin(num_face))++;
51 if(face2 > -1) (rang_voisin(num_face))++;
52 if(face3 > -1) (rang_voisin(num_face))++;
53 if(face4 > -1) (rang_voisin(num_face))++;
54
55 if (dimension==3)
56 {
57 const int face5 = le_dom.face_bord_amont(num_face,(ori+2)%dimension,0), face6 = le_dom.face_bord_amont(num_face,(ori+2)%dimension,1);
58 if(face5 > -1) (rang_voisin(num_face))++;
59 if(face6 > -1) (rang_voisin(num_face))++;
60 }
61 }
62
63 // on balaye les faces pour dimensionner tab1 et tab2
64 tab1(0) = 1;
65 for (int num_face = ndeb; num_face < nfin; num_face++)
66 for (int k = 0; k < nb_comp; k++) tab1(num_face*nb_comp+1+k) = rang_voisin(num_face) + tab1(num_face*nb_comp+k);
67
68 la_matrice.dimensionner(nfin*nb_comp,tab1(nfin*nb_comp)-1);
69
70 for (int num_face = ndeb; num_face < nfin; num_face++)
71 {
72 const int ori = orientation(num_face), face1 = le_dom.face_amont_princ(num_face,0), face2 = le_dom.face_amont_princ(num_face,1),
73 face3 = le_dom.face_bord_amont(num_face,(ori+1)%dimension,0), face4 = le_dom.face_bord_amont(num_face,(ori+1)%dimension,1);
74
75 auto cpt = tab1[num_face]-1;
76 tab2[cpt] = num_face+1;
77 cpt++;
78
79 if (face1 > -1) { tab2[cpt] = face1+1; cpt++; }
80 if (face2 > -1) { tab2[cpt] = face2+1; cpt++; }
81 if (face3 > -1) { tab2[cpt] = face3+1; cpt++; }
82 if (face4 > -1) { tab2[cpt] = face4+1; cpt++; }
83
84 if (dimension == 3)
85 {
86 const int face5 = le_dom.face_bord_amont(num_face,(ori+2)%dimension,0), face6 = le_dom.face_bord_amont(num_face,(ori+2)%dimension,1);
87 if (face5 > -1) { tab2[cpt] = face5+1; cpt++; }
88 if (face6 > -1) { tab2[cpt] = face6+1; cpt++; }
89 }
90 }
91
92 // on traite la condition de periodicite : en effet ce n'est pas sur que les faces de frontiere soient les bonnes
93 // plus precisement a droite on a la face de gauche et non celle de droite
94 const Conds_lim& les_cl = le_dom_cl.les_conditions_limites();
95 const IntTab& faces_voisins = le_dom.face_voisins(), &elem_faces = le_dom.elem_faces();
96
97 for (const auto& itr : les_cl)
98 {
99 const Cond_lim& la_cl = itr;
100 if (sub_type(Periodique,la_cl.valeur()))
101 {
102 const Front_VF& la_front_dis = ref_cast(Front_VF,la_cl->frontiere_dis());
103 const int ndeb_p = la_front_dis.num_premiere_face(), nfaces = la_front_dis.nb_faces(), nfin_p = ndeb_p + nfaces;
104
105 for (int num_face = ndeb_p; num_face < nfin_p; num_face++)
106 {
107 const int ori = orientation(num_face);
108 {
109 //int face1=le_dom.face_amont_princ(num_face,0);
110 //int face2=le_dom.face_amont_princ(num_face,1);
111 const int face3 = le_dom.face_bord_amont(num_face,(ori+1)%dimension,0), face4 = le_dom.face_bord_amont(num_face,(ori+1)%dimension,1);
112 const int face1b = elem_faces(faces_voisins(num_face,1),ori);
113
114 auto cpt = tab1[num_face]-1;
115 cpt += 3;
116 if (face1b != num_face)
117 {
118 // on recalcule fac3 fac4
119 const int face3n = face_bord_amont2(le_dom,num_face,(ori+1)%dimension,0), face4n = face_bord_amont2(le_dom,num_face,(ori+1)%dimension,1);
120 if (face3 != -1) { assert(tab2[cpt] == face3+1); tab2[cpt] = face3n+1; cpt++; }
121 if (face4 != -1) { assert(tab2[cpt] == face4+1); tab2[cpt] = face4n+1; cpt++; }
122
123 if (dimension == 3)
124 {
125 const int face5 = le_dom.face_bord_amont(num_face,(ori+2)%dimension,0), face6 = le_dom.face_bord_amont(num_face,(ori+2)%dimension,1),
126 face5n = face_bord_amont2(le_dom,num_face,(ori+2)%dimension,0), face6n = face_bord_amont2(le_dom,num_face,(ori+2)%dimension,1);
127
128 if (face5 != -1) { assert(tab2[cpt] == face5+1); tab2[cpt] = face5n+1; cpt++; }
129 if (face6 != -1) { assert(tab2[cpt] == face6+1); tab2[cpt] = face6n+1; cpt++; }
130 }
131 }
132 }
133 }
134 }
135 }
136}
137
138void Op_VDF_Face::modifier_pour_Cl_(const int face, const int comp, const int nb_comp, Matrice_Morse& la_matrice) const
139{
140 auto& tab1 = la_matrice.get_set_tab1();
141 auto& coeff = la_matrice.get_set_coeff();
142
143 const auto idiag = tab1[face * nb_comp + comp] - 1;
144 coeff[idiag] = 1.;
145
146 // pour les voisins
147 const int nbvois = (int)(tab1[face * nb_comp + 1 + comp] - tab1[face * nb_comp + comp]);
148 for (int k = 1; k < nbvois; k++) coeff[idiag + k] = 0.;
149}
150
151void Op_VDF_Face::modifier_pour_Cl(const Domaine_VDF& le_dom, const Domaine_Cl_VDF& le_dom_cl, Matrice_Morse& la_matrice, DoubleTab& secmem) const
152{
153 const Conds_lim& les_cl = le_dom_cl.les_conditions_limites();
154 const IntVect& orientation = le_dom.orientation();
155 const DoubleTab& champ_inconnue = le_dom_cl.equation().inconnue().valeurs();
156 const int nb_comp = champ_inconnue.line_size();
157
158 for (const auto& itr : les_cl)
159 {
160 const Cond_lim& la_cl = itr;
161 const Front_VF& la_front_dis = ref_cast(Front_VF, la_cl->frontiere_dis());
162 const int numdeb = la_front_dis.num_premiere_face(), nfaces = la_front_dis.nb_faces();
163
164 if (sub_type(Dirichlet, la_cl.valeur()))
165 {
166 const Dirichlet& la_cl_Dirichlet = ref_cast(Dirichlet, la_cl.valeur());
167
168 for (int face = numdeb; face < (numdeb + nfaces); face++)
169 for (int comp = 0; comp < nb_comp; comp++)
170 {
171 modifier_pour_Cl_(face, comp, nb_comp, la_matrice);
172 // pour le second membre [Correction erreur (10/99) : WEC : correction numero de face]
173 const int ori = orientation(face);
174 secmem(face, comp) = la_cl_Dirichlet.val_imp(face - numdeb, nb_comp * ori + comp);
175 }
176 }
177
178 if (sub_type(Symetrie, la_cl.valeur()))
179 {
180 for (int face = numdeb; face < numdeb + nfaces; face++)
181 for (int comp = 0; comp < nb_comp; comp++)
182 {
183 modifier_pour_Cl_(face, comp, nb_comp, la_matrice);
184 secmem(face, comp) = 0.;
185 }
186 }
187
188 if (sub_type(Dirichlet_homogene, la_cl.valeur()))
189 {
190 const Dirichlet_homogene& la_cl_Dirichlet_homogene = ref_cast(Dirichlet_homogene, la_cl.valeur());
191
192 for (int face = numdeb; face < numdeb + nfaces; face++)
193 for (int comp = 0; comp < nb_comp; comp++)
194 {
195 modifier_pour_Cl_(face, comp, nb_comp, la_matrice);
196 // pour le second membre [Correction erreur (10/99) : WEC : correction numero de face]
197 const int ori = orientation(face);
198 secmem(face, comp) = la_cl_Dirichlet_homogene.val_imp(face - numdeb, nb_comp * ori + comp);
199 }
200 }
201 }
202}
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
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
Definition Conds_lim.h:32
Classe Dirichlet_homogene Cette classe est la classe de base de la hierarchie des conditions aux limi...
double val_imp(int i) const
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
Definition Dirichlet.h:31
virtual double val_imp(int i) const
Renvoie la valeur imposee sur la i-eme composante du champ a la frontiere au temps par defaut du cham...
Definition Dirichlet.cpp:35
class Domaine_Cl_VDF
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
class Domaine_VDF
Definition Domaine_VDF.h:64
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
int face_bord_amont(int, int, int) const
Determine la face voisine de notre face en prevoyant que cette derniere puisse etre de type bord.
int face_amont_princ(int, int) const
int nb_faces_tot() const
renvoie le nombre total de faces.
Definition Domaine_VF.h:481
int elem_faces(int i, int j) const
renvoie le numero de le ieme face de la maille num_elem la facon dont ces faces sont numerotees est
Definition Domaine_VF.h:543
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
virtual const Champ_Inc_base & inconnue() const =0
class Front_VF
Definition Front_VF.h:36
int nb_faces() const
Definition Front_VF.h:53
int num_premiere_face() const
Definition Front_VF.h:63
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
auto & get_set_tab2()
void dimensionner(int n, _SIZE_ nnz)
Size the matrix with n lines and n columns and nnz zero-values coefficients.
auto & get_set_coeff()
auto & get_set_tab1()
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
static int dimension
Definition Objet_U.h:99
void modifier_pour_Cl(const Domaine_VDF &, const Domaine_Cl_VDF &, Matrice_Morse &, DoubleTab &) const
void dimensionner(const Domaine_VDF &, const Domaine_Cl_VDF &, Matrice_Morse &) const
classe Periodique Cette classe represente une condition aux limites periodique.
Definition Periodique.h:31
classe Symetrie Sur les faces de symetrie on a les proprietes suivantes:
Definition Symetrie.h:37
int line_size() const
Definition TRUSTVect.tpp:67