TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Dift_standard_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_Dift_standard_VEF_Face.h>
17#include <Dirichlet_paroi_defilante.h>
18#include <Dirichlet_paroi_fixe.h>
19#include <Dirichlet_homogene.h>
20#include <Champ_P1NC.h>
21#include <Periodique.h>
22#include <Dirichlet.h>
23#include <TRUSTTrav.h>
24#include <Debog.h>
25
26Implemente_instanciable(Op_Dift_standard_VEF_Face, "Op_Dift_VEF_P1NC_standard", Op_Dift_VEF_base);
27
28// XD bloc_diffusion_standard objet_lecture nul NO_BRACE grad_Ubar 1 makes the gradient calculated through the filtered
29// XD_CONT values of velocity (P1-conform).NL2 nu 1 (respectively nut 1) takes the molecular viscosity (eddy viscosity)
30// XD_CONT into account in the velocity gradient part of the diffusion expression. NL2 nu_transp 1 (respectively
31// XD_CONT nut_transp 1) takes the molecular viscosity (eddy viscosity) into account according in the TRANSPOSED
32// XD_CONT velocity gradient part of the diffusion expression.NL2 filtrer_resu 1 allows to filter the resulting
33// XD_CONT diffusive fluxes contribution.
34// XD attr mot1 chaine(into=["grad_Ubar","nu","nut","nu_transp","nut_transp","filtrer_resu"]) mot1 REQ not_set
35// XD attr val1 entier(into=[0,1]) val1 REQ not_set
36// XD attr mot2 chaine(into=["grad_Ubar","nu","nut","nu_transp","nut_transp","filtrer_resu"]) mot2 REQ not_set
37// XD attr val2 entier(into=[0,1]) val2 REQ not_set
38// XD attr mot3 chaine(into=["grad_Ubar","nu","nut","nu_transp","nut_transp","filtrer_resu"]) mot3 REQ not_set
39// XD attr val3 entier(into=[0,1]) val3 REQ not_set
40// XD attr mot4 chaine(into=["grad_Ubar","nu","nut","nu_transp","nut_transp","filtrer_resu"]) mot4 REQ not_set
41// XD attr val4 entier(into=[0,1]) val4 REQ not_set
42// XD attr mot5 chaine(into=["grad_Ubar","nu","nut","nu_transp","nut_transp","filtrer_resu"]) mot5 REQ not_set
43// XD attr val5 entier(into=[0,1]) val5 REQ not_set
44// XD attr mot6 chaine(into=["grad_Ubar","nu","nut","nu_transp","nut_transp","filtrer_resu"]) mot6 REQ not_set
45// XD attr val6 entier(into=[0,1]) val6 REQ not_set
46
47// XD diffusion_standard diffusion_deriv standard NO_BRACE A new keyword, intended for LES calculations, has been
48// XD_CONT developed to optimise and parameterise each term of the diffusion operator. Remark:NL2 NL2 1. This class
49// XD_CONT requires to define a filtering operator : see solveur_barNL2 2. The former (original) version: diffusion { }
50// XD_CONT -which omitted some of the term of the diffusion operator- can be recovered by using the following parameters
51// XD_CONT in the new class :NL2 diffusion { standard grad_Ubar 0 nu 1 nut 1 nu_transp 0 nut_transp 1 filtrer_resu 0}.
52// XD attr mot1 chaine(into=["defaut_bar"]) mot1 OPT equivalent to grad_Ubar 1 nu 1 nut 1 nu_transp 1 nut_transp 1
53// XD_CONT filtrer_resu 1
54// XD attr bloc_diffusion_standard bloc_diffusion_standard bloc_diffusion_standard OPT not_set
55
56
58
60{
61 Motcle accfermee = "}", motlu;
62 is >> motlu;
63 while (motlu != accfermee)
64 {
65 if (motlu == "defaut_bar")
66 {
67 is >> motlu;
68 break;
69 }
70 else if (motlu == "grad_Ubar") is >> grad_Ubar;
71 else if (motlu == "nu") is >> nu_lu;
72 else if (motlu == "nut") is >> nut_lu;
73 else if (motlu == "nu_transp") is >> nu_transp_lu;
74 else if (motlu == "nut_transp") is >> nut_transp_lu;
75 else if (motlu == "filtrer_resu") is >> filtrer_resu;
76 else
77 {
78 Cerr << motlu << " is not understood by " << que_suis_je() << finl;
80 }
81 is >> motlu;
82 }
83 return is;
84}
85
86void Op_Dift_standard_VEF_Face::ajouter_cas_vectoriel(const DoubleTab& vitesse, DoubleTab& resu, const DoubleTab& nu, const DoubleTab& nu_turb) const
87{
88 const Domaine_Cl_VEF& domaine_Cl_VEF = domaine_cl_vef();
89 const Domaine_VEF& domaine_VEF = domaine_vef();
90 const int nbr_comp = resu.line_size();
91
92 // cast grad and grad_transp to be able to modify them: no longer using statics due to issues with multiple problems
93 DoubleTab& grad = ref_cast_non_const(DoubleTab, grad_);
94 Debog::verifier("Op_Dift_standard_VEF_Face::ajouter_cas_vectoriel : resu 0 ", resu);
95
96 //DoubleVect n(Objet_U::dimension), t(Objet_U::dimension);
97 //DoubleTrav Tgrad(Objet_U::dimension, Objet_U::dimension);
98
99 assert(nbr_comp > 1);
100
101 // Size and initialize the flux balance array:
102 flux_bords_.resize(domaine_VEF.nb_faces_bord(), nbr_comp);
103 flux_bords_ = 0.;
104
105 // Build the grad_ array
106 if (!grad.get_md_vector())
107 {
109 domaine_VEF.domaine().creer_tableau_elements(grad);
110 }
111
112 // *** GRADIENT COMPUTATION ***
113 DoubleTab ubar(vitesse);
114
115 if (grad_Ubar) ref_cast(Champ_P1NC,inconnue_.valeur()).filtrer_L2(ubar);
116
117 Champ_P1NC::calcul_gradient(ubar, grad, domaine_Cl_VEF);
118
119 if (le_modele_turbulence->utiliser_loi_paroi())
120 Champ_P1NC::calcul_duidxj_paroi(grad, nu, nu_turb, tau_tan_, domaine_Cl_VEF);
121
123
124 // *** DIFFUSION COMPUTATION ***
125 Debog::verifier("Op_Dift_standard_VEF_Face::ajouter_cas_vectoriel : grad 1 ", grad);
126 calcul_divergence(resu, grad, grad, nu, nu_turb);
127
128 Debog::verifier("Op_Dift_standard_VEF_Face::ajouter_cas_vectoriel : resu 1 ", resu);
129
130 if (filtrer_resu) ref_cast(Champ_P1NC,inconnue_.valeur()).filtrer_resu(resu);
131}
132
133void Op_Dift_standard_VEF_Face::calcul_divergence(DoubleTab& dif, const DoubleTab& grad, const DoubleTab& gradt, const DoubleTab& nu, const DoubleTab& nu_turb) const
134{
135 const Domaine_Cl_VEF& domaine_Cl_VEF = domaine_cl_vef();
136 const Domaine_VEF& domaine_VEF = domaine_vef();
137 const IntTab& face_voisins = domaine_VEF.face_voisins();
138 const DoubleTab& face_normale = domaine_VEF.face_normales();
139 const int nb_faces = domaine_VEF.nb_faces(), nbr_comp = dif.line_size();
140 double nu1 = -123., nu2 = -123., nu1t = -123., nu2t = -123., flux = -123.;
141 double c1 = 0., c2 = 0., c3 = 0., c4 = 0.;
142
143 if (nu_lu) c1 = 1.;
144 if (nut_lu) c2 = 1.;
145 if (nu_transp_lu) c3 = 1.;
146 if (nut_transp_lu) c4 = 1.;
147
148 // Boundary treatment
149 Debog::verifier("Op_Dift_standard_VEF_Face::calcul_divergence dif 0 ", dif);
150
151 const Conds_lim& les_cl = domaine_Cl_VEF.les_conditions_limites();
152 int nb_cl = les_cl.size();
153 for (int num_cl = 0; num_cl < nb_cl; num_cl++)
154 {
155 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(num_cl);
156 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
157 const int nb_faces_b = le_bord.nb_faces();
158 const int num1 = le_bord.num_premiere_face(), num2 = num1 + nb_faces_b;
159
160 if (sub_type(Periodique, la_cl.valeur()))
161 {
162 const Periodique& la_cl_perio = ref_cast(Periodique, la_cl.valeur());
163 IntVect fait(nb_faces_b);
164 fait = 0;
165 for (int num_face0 = num1; num_face0 < num2; num_face0++)
166 {
167 int face_associee = la_cl_perio.face_associee(num_face0 - num1);
168 if (fait(num_face0 - num1) == 0)
169 {
170 fait(num_face0 - num1) = 1;
171 fait(face_associee) = 1;
172 const int elem10 = face_voisins(num_face0, 0), elem2 = face_voisins(num_face0, 1);
173 nu1 = c1 * nu[elem10] + c2 * nu_turb[elem10];
174 nu2 = c1 * nu[elem2] + c2 * nu_turb[elem2];
175 nu1t = c3 * nu[elem10] + c4 * nu_turb[elem10];
176 nu2t = c3 * nu[elem2] + c4 * nu_turb[elem2];
177
178 for (int i = 0; i < nbr_comp; i++)
179 for (int j = 0; j < nbr_comp; j++)
180 dif(num_face0, i) -= face_normale(num_face0, j) * (nu1 * grad(elem10, i, j) + nu1t * gradt(elem10, j, i) - (nu2 * grad(elem2, i, j) + nu2t * gradt(elem2, j, i)));
181
182 for (int i = 0; i < nbr_comp; i++)
183 dif(face_associee + num1, i) = dif(num_face0, i);
184 }
185 }
186 }
187 else if ((sub_type(Dirichlet, la_cl.valeur())) || (sub_type(Dirichlet_homogene, la_cl.valeur())))
188 {
189 if (sub_type(Dirichlet_paroi_fixe,la_cl.valeur()) || sub_type(Dirichlet_paroi_defilante, la_cl.valeur()))
190 {
191 for (int num_face0 = num1; num_face0 < num2; num_face0++)
192 {
193 int elem1 = face_voisins(num_face0, 0);
194 nu1 = c1 * nu[elem1] + c2 * nu_turb[elem1];
195 nu1t = c3 * nu[elem1] + c4 * nu_turb[elem1];
196
197 for (int i = 0; i < nbr_comp; i++)
198 {
199 flux = 0.;
200 for (int j = 0; j < nbr_comp; j++)
201 flux += face_normale(num_face0, j) * (nu1 * grad(elem1, i, j) + nu1t * gradt(elem1, j, i));
202
203 dif(num_face0, i) = 0.; // PQ: valid in turbulent regime based on linear velocity profile in the viscous sublayer
204 flux_bords_(num_face0, i) -= flux;
205 }
206 }
207 }
208 }
209 else // For other boundary conditions
210 {
211 for (int num_face = num1; num_face < num2; num_face++)
212 {
213 int elem1 = face_voisins(num_face, 0);
214 nu1 = c1 * nu[elem1] + c2 * nu_turb[elem1];
215 nu1t = c3 * nu[elem1] + c4 * nu_turb[elem1];
216
217 for (int i = 0; i < nbr_comp; i++)
218 {
219 flux = 0.;
220 for (int j = 0; j < nbr_comp; j++)
221 flux += face_normale(num_face, j) * (nu1 * grad(elem1, i, j) + nu1t * gradt(elem1, j, i));
222
223 dif(num_face, i) = 0.; // PQ: pending a better implementation
224 flux_bords_(num_face, i) -= flux;
225 }
226
227 }
228 }
229 }
230
231 Debog::verifier("Op_Dift_standard_VEF_Face::calcul_divergence dif 1 ", dif);
232 Debog::verifier("Op_Dift_standard_VEF_Face::calcul_divergence nu 1 ", nu);
233 Debog::verifier("Op_Dift_standard_VEF_Face::calcul_divergence nu_turb 1 ", nu_turb);
234 Debog::verifier("Op_Dift_standard_VEF_Face::calcul_divergence grad 1 ", grad);
235 Debog::verifier("Op_Dift_standard_VEF_Face::calcul_divergence gradt 1 ", gradt);
236
237 for (int num_face0 = domaine_VEF.premiere_face_int(); num_face0 < nb_faces; num_face0++)
238 {
239 const int elem10 = face_voisins(num_face0, 0), elem2 = face_voisins(num_face0, 1);
240 nu1 = c1 * nu[elem10] + c2 * nu_turb[elem10];
241 nu2 = c1 * nu[elem2] + c2 * nu_turb[elem2];
242 nu1t = c3 * nu[elem10] + c4 * nu_turb[elem10];
243 nu2t = c3 * nu[elem2] + c4 * nu_turb[elem2];
244
245 for (int i = 0; i < nbr_comp; i++)
246 for (int j = 0; j < nbr_comp; j++)
247 dif(num_face0, i) -= face_normale(num_face0, j) * (nu1 * grad(elem10, i, j) + nu1t * gradt(elem10, j, i) - (nu2 * grad(elem2, i, j) + nu2t * gradt(elem2, j, i)));
248 }
249
250 Debog::verifier("Op_Dift_standard_VEF_Face::calcul_divergence dif 2 ", dif);
251
253
254 Debog::verifier("Op_Dift_standard_VEF_Face::calcul_divergence dif 3 ", dif);
255}
256
257DoubleTab& Op_Dift_standard_VEF_Face::ajouter(const DoubleTab& inconnue, DoubleTab& resu) const
258{
259 const DoubleTab& nu_turb = diffusivite_turbulente().valeurs();
260 DoubleTab nu(nu_turb);
261 remplir_nu(nu);
262 ajouter_cas_vectoriel(inconnue, resu, nu, nu_turb);
263 modifier_flux(*this);
264 return resu;
265}
DoubleTab & valeurs() override
Overrides Champ_base::valeurs() Returns the array of values.
static DoubleTab & calcul_gradient(const DoubleTab &, DoubleTab &, const Domaine_Cl_VEF &)
static DoubleTab & calcul_duidxj_paroi(DoubleTab &, const DoubleTab &, const DoubleTab &, const DoubleTab &, const Domaine_Cl_VEF &)
static void verifier(const char *const msg, double)
Definition Debog.cpp:21
virtual void creer_tableau_elements(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
Creates a parallel array of values at elements.
Definition Domaine.cpp:850
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
int nb_faces() const
Returns the total number of faces.
Definition Domaine_VF.h:471
virtual double face_normales(int face, int comp) const
Definition Domaine_VF.h:47
int premiere_face_int() const
A face is internal if and only if it separates two elements.
Definition Domaine_VF.h:463
int face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in direction i.
Definition Domaine_VF.h:418
int nb_faces_bord() const
Returns the number of faces on which boundary conditions are applied:
Definition Domaine_VF.h:512
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
int nb_faces() const
Definition Front_VF.h:53
int num_premiere_face() const
Definition Front_VF.h:63
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
const Champ_Fonc_base & diffusivite_turbulente() const
virtual void remplir_nu(DoubleTab &) const
const Domaine_VEF & domaine_vef() const
const Domaine_Cl_VEF & domaine_cl_vef() const
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
void modifier_flux(const Operateur_base &) const
DoubleTab flux_bords_
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
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
int line_size() const
Definition TRUSTVect.tpp:67
virtual const MD_Vector & get_md_vector() const
Definition TRUSTVect.h:123
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")