TrioCFD 1.9.8
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 << " n'est pas compris par " << 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 // on cast grad et grad_transp pour pouvoir les modifier : on utilise plus les static car pb avec plusieurs pbs
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 // On dimensionne et initialise le tableau des bilans de flux:
102 flux_bords_.resize(domaine_VEF.nb_faces_bord(), nbr_comp);
103 flux_bords_ = 0.;
104
105 // Construction du tableau grad_
106 if (!grad.get_md_vector())
107 {
109 domaine_VEF.domaine().creer_tableau_elements(grad);
110 }
111
112 // *** CALCUL DU GRADIENT ***
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 // *** CALCUL DE LA DIFFUSION ***
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 // Traitement des bords
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 : valable en regime turbulent d'apres profil lineaire de la vitesse dans la sous couche visqueuse
204 flux_bords_(num_face0, i) -= flux;
205 }
206 }
207 }
208 }
209 else // Pour les autres conditions aux limites
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 : en attendant de faire mieux
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
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
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
creation d'un tableau parallele de valeurs aux elements.
Definition Domaine.cpp:851
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
int nb_faces() const
renvoie le nombre global de 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
une face est interne ssi elle separe deux elements.
Definition Domaine_VF.h:463
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
int nb_faces_bord() const
renvoie le nombre de faces sur lesquelles sont appliquees les conditions limites :
Definition Domaine_VF.h:513
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:99
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
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)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
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")