TrioCFD 1.9.9_beta
TrioCFD documentation
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 // Sizing of the matrix that will receive the coefficients from convection and diffusion for face unknowns.
29 // This matrix has a Morse matrix structure.
30 // We start by computing the sizes of arrays tab1 and 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 // sweep over faces to size tab1 and 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 // handle the periodicity condition: the boundary faces may not be the correct ones;
93 // more precisely, on the right side we have the left face rather than the right face
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 // recompute 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 // for the neighbors
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 // for the right-hand side [Bug fix (10/99) : WEC : face index correction]
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 // for the right-hand side [Bug fix (10/99) : WEC : face index correction]
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
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
class Conds_lim This class represents a vector of boundary conditions.
Definition Conds_lim.h:32
Classe Dirichlet_homogene This class is the base class of the hierarchy of homogeneous Dirichlet-type...
double val_imp(int i) const
Dirichlet This class is the base class of the hierarchy of Dirichlet-type boundary conditions.
Definition Dirichlet.h:31
virtual double val_imp(int i) const
Returns the imposed value on the i-th component of the field at the boundary at the default time of c...
Definition Dirichlet.cpp:35
class Domaine_Cl_VDF
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
class Domaine_VDF
Definition Domaine_VDF.h:61
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
int face_bord_amont(int, int, int) const
Returns the neighboring face, accounting for the possibility that it may be a boundary face.
int face_amont_princ(int, int) const
int nb_faces_tot() const
Returns the total number of faces.
Definition Domaine_VF.h:481
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
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
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
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
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
static int dimension
Definition Objet_U.h:94
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
class Periodique This class represents a periodic boundary condition.
Definition Periodique.h:31
Symetrie On symmetry faces, the following properties hold:
Definition Symetrie.h:37
int line_size() const
Definition TRUSTVect.tpp:67