TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Terme_Source_Qdm_lambdaup_VEF_Face.cpp
1/****************************************************************************
2* Copyright (c) 2024, 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 <Terme_Source_Qdm_lambdaup_VEF_Face.h>
17#include <Domaine_VEF.h>
18#include <Navier_Stokes_std.h>
19#include <Probleme_base.h>
20#include <Schema_Temps_base.h>
21#include <Champ_P1NC.h>
22#include <SFichier.h>
23
24Implemente_instanciable(Terme_Source_Qdm_lambdaup_VEF_Face,"Source_Qdm_lambdaup_VEF_P1NC",Source_base);
25// XD source_qdm_lambdaup source_base source_qdm_lambdaup BRACE This source term is a dissipative term which is intended
26// XD_CONT to minimise the energy associated to non-conformscales u\' (responsible for spurious oscillations in some
27// XD_CONT cases). The equation for these scales can be seen as: du\'/dt= -lambda. u\' + grad P\' where -lambda. u\'
28// XD_CONT represents the dissipative term, with lambda = a/Delta t For Crank-Nicholson temporal scheme, recommended
29// XD_CONT value for a is 2. NL2 Remark : This method requires to define a filtering operator.
30
32{
33 return s << que_suis_je() ;
34}
35
37{
38 Motcle accouverte = "{" , accfermee = "}" ;
39 Motcle motlu;
40 is >> motlu;
41 if(motlu!=accouverte)
42 {
43 Cerr << motlu << " --> " << finl;
44 Cerr << "{ attendue a la lecture du terme source lambda uprime " << finl;
45 Cerr << "La syntaxe du mot cle Source_Qdm_lambdaup a change, voir le" << finl;
46 Cerr << "manuel utilisateur de la version 1.5.5 ou plus recent." << finl;
47 Cerr << "La valeur de lambda, qui peut etre desormais variable" << finl;
48 Cerr << "doit etre precedee d'un mot cle:" << finl;
49 Cerr << "Ainsi, Source_Qdm_lambdaup valeur devient:" <<finl;
50 Cerr << "Source_Qdm_lambdaup { lambda valeur }" <<finl;
52 }
53 Motcles les_mots(4);
54 {
55 les_mots[0] = "lambda"; // XD attr lambda floattant lambda_u REQ value of lambda
56 les_mots[1] = "lambda_min"; // XD attr lambda_min floattant lambda_min OPT value of lambda_min
57 les_mots[2] = "lambda_max"; // XD attr lambda_max floattant lambda_max OPT value of lambda_max
58 les_mots[3] = "ubar_umprim_cible"; // XD attr ubar_umprim_cible floattant ubar_umprim_cible OPT value of
59 // XD_CONT ubar_umprim_cible
60 }
61 lambda=-1;
62 while(motlu!=accfermee)
63 {
64 is>>motlu;
65 int rang=les_mots.search(motlu);
66 switch(rang)
67 {
68 case 0:
69 {
70 is >> lambda;
73 break;
74 }
75 case 1:
76 {
77 is >> lambda_min;
78 break;
79 }
80 case 2:
81 {
82 is >> lambda_max;
83 break;
84 }
85 case 3:
86 {
87 is >> cible;
88 break;
89 }
90 default :
91 {
92 if(motlu!=accfermee)
93 {
94 Cerr << motlu
95 << " non compris dans terme source lambda uprime "
96 << finl;
98 }
99 }
100 }
101 }
102 if(lambda < 0)
104 if (lambda < 0.)
105 {
106 Cerr << "Erreur a la lecture de lambda dans " << que_suis_je() << finl;
107 Cerr << " lambda doit etre defini et superieur a 0 " << finl;
108 exit();
109 }
110 Cerr << "Sortie du readOn " << finl;
111 return is ;
112}
113
115{
116 int nb_eqn = pb.nombre_d_equations();
117 int ok=0;
118 for (int i=0; i<nb_eqn; i++)
119 {
120 const Equation_base& eqn = pb.equation(i);
121 if (sub_type(Navier_Stokes_std,eqn))
122 {
123 la_vitesse = ref_cast(Champ_P1NC,eqn.inconnue());
125 i = nb_eqn;
126 ok = 1;
127 }
128 else
129 Cerr << "Lambdaup : " << eqn.que_suis_je() << finl;
130 }
131
132 if (!ok)
133 {
134 Cerr << "Erreur TRUST dans " << que_suis_je() << finl;
135 Cerr << "On ne trouve pas d'equation d'hydraulique dans le probleme" << finl;
136 exit();
137 }
138}
139
141 const Domaine_Cl_dis_base& domaine_Cl_dis)
142{
143 le_dom_VEF = ref_cast(Domaine_VEF, domaine_dis);
144 le_dom_Cl_VEF = ref_cast(Domaine_Cl_VEF, domaine_Cl_dis);
145}
146
147
148DoubleTab& Terme_Source_Qdm_lambdaup_VEF_Face::ajouter(DoubleTab& resu) const
149{
150 static double rapport_old=1.;
151 const Domaine_VEF& domaine_VEF = le_dom_VEF.valeur();
152 const DoubleVect& volumes_entrelaces=domaine_VEF.volumes_entrelaces();
153 const DoubleVect& porosite_face = equation().milieu().porosite_face();
154 const DoubleTab& vitesse=la_vitesse->valeurs();
155 DoubleTab ubar(vitesse);
156 DoubleTab uprime(vitesse);
157 const int nb_faces = domaine_VEF.nb_faces();
158 int face, k;
159
160 int nb_comp = resu.line_size();
161
162 la_vitesse->filtrer_L2(ubar);
163 uprime-=ubar;
164 // Optimization: combine 2 mp_norme_vect into 1 collective call
165 double normbar_carre = local_carre_norme_vect(ubar);
166 double normprim_carre = local_carre_norme_vect(uprime);
167 Process::mp_sum_for_each(normbar_carre, normprim_carre);
168 double normbar = sqrt(normbar_carre);
169 double normprim = sqrt(normprim_carre);
170 //double rapport=normbar/(normprim+DMINFLOAT) ;
171 double rapport=(normprim!=0?normbar/normprim:0);
172 double& l=lambda;
173 if( (rapport < cible) && (rapport<rapport_old) ) l*=2.;
174 if( (rapport < cible) && (rapport>rapport_old) ) l*=1.1;
175 if( (rapport>cible) && (rapport>rapport_old) ) l*=0.95;
176 l=std::min(lambda, lambda_max);
177 l=std::max(lambda_min, lambda);
178 Cerr << "|ubar| = " << normbar << finl;
179 Cerr << "|ubar|/|uprim| = " << rapport << finl;
180 Cerr << "lambda " << lambda << finl;
181 for(face=0; face<nb_faces; face++)
182 for(k=0; k< dimension; k++)
183 {
184 double v=volumes_entrelaces(face)*porosite_face(face);
185 if(nb_comp>1)
186 {
187 uprime(face,k)*=v;
188 }
189 else
190 {
191 uprime(face)*=v;
192 }
193 }
194
195 double dt=la_vitesse->equation().schema_temps().pas_de_temps();
196 resu.ajoute(-lambda/dt, uprime);
197 rapport_old=rapport;
198 return resu;
199}
200
201DoubleTab& Terme_Source_Qdm_lambdaup_VEF_Face::calculer(DoubleTab& resu) const
202{
203 resu = 0;
204 return ajouter(resu);
205}
206
208{
209 ;
210}
211
212double Terme_Source_Qdm_lambdaup_VEF_Face::norme_H1(const DoubleTab& vitesse) const
213{
214 const Domaine_VEF& domaine_VEF = le_dom_VEF.valeur();
215 const Domaine& domaine = domaine_VEF.domaine();
216
217 double dnorme_H1,norme_H1_comp,int_grad_elem,norme_grad_elem;
218 int face_globale;
219
220 //On va calculer la norme H1 d'une inconnue P1NC.
221 //L'algorithme tient compte des contraintes suivantes:
222 //- l'inconnue peut avoir plusieurs composantes
223 // (i.e etre un scalaire ou etre un vecteur)
224 //- la dimension du probleme est arbitraire (1, 2 ou 3).
225 //ATTENTION: les prismes ne sont pas supportes.
226
227 dnorme_H1=0.;
228 for (int composante=0; composante<vitesse.line_size(); composante++)
229 {
230 norme_H1_comp=0.; //pour eviter les accumulations
231 for (int K=0; K<domaine.nb_elem(); K++) //boucle sur les elements
232 {
233 norme_grad_elem=0.; //pour eviter les accumulations
234 for (int i=0; i<dimension; i++) //boucle sur la dimension du pb
235 {
236 int_grad_elem=0.; //pour eviter les accumulations
237 for (int face=0; face<domaine.nb_faces_elem(); face++) //boucle sur les faces d'un "K"
238 {
239 face_globale = domaine_VEF.elem_faces(K,face);
240
241 int_grad_elem += vitesse(face_globale,composante)*
242 domaine_VEF.face_normales(face_globale,i)*
243 domaine_VEF.oriente_normale(face_globale,K);
244 } //fin du for sur "face"
245
246 norme_grad_elem += int_grad_elem*int_grad_elem;
247 } //fin du for sur "i"
248
249 norme_H1_comp += norme_grad_elem/domaine_VEF.volumes(K);
250 } //fin du for sur "K"
251
252 dnorme_H1 += norme_H1_comp;
253 } // fin du for sur "composante"
254
255 return sqrt(dnorme_H1);
256}
257
259{
260 double pas_de_temps = la_vitesse->equation().schema_temps().pas_de_temps();
261
262 return ((1./pas_de_temps)*norme_L2(u))+norme_H1(u);
263}
264
265double Terme_Source_Qdm_lambdaup_VEF_Face::norme_L2(const DoubleTab& u) const
266{
267 const Domaine_VEF& domaine_VEF = le_dom_VEF.valeur();
268 const DoubleVect& volumes = domaine_VEF.volumes_entrelaces();
269 const int nb_faces = domaine_VEF.nb_faces();
270
271 int i=0;
272 double norme =0;
273 int nb_compo_=u.line_size();
274
275 for(; i<nb_faces; i++)
276 {
277 double s=0;
278 for(int j=0; j<nb_compo_; j++)
279 s+=u(i,j)*u(i,j);
280 norme+=volumes(i)*s;
281 }
282
283 return sqrt(norme);
284}
285
classe Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
class Domaine_VEF
Definition Domaine_VEF.h:54
int nb_faces() const
renvoie le nombre global de faces.
Definition Domaine_VF.h:471
DoubleVect & volumes_entrelaces()
Definition Domaine_VF.h:99
virtual double face_normales(int face, int comp) const
Definition Domaine_VF.h:47
double volumes(int i) const
Definition Domaine_VF.h:113
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 oriente_normale(int f, int e) const
Definition Domaine_VF.h:194
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
virtual const Milieu_base & milieu() const =0
virtual const Champ_Inc_base & inconnue() const =0
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limite discretisee associee a l'equation.
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise associe a l'equation.
DoubleVect & porosite_face()
Definition Milieu_base.h:62
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
classe Navier_Stokes_std Cette classe porte les termes de l'equation de la dynamique
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
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
virtual int nombre_d_equations() const =0
virtual const Equation_base & equation(int) const =0
static void mp_sum_for_each(T &arg1, T &arg2)
C++14 compatible mp_sum_for_each: combine multiple mp_sum calls into one collective operation Usage: ...
Definition Process.cpp:207
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
classe Source_base Un objet Source_base est un terme apparaissant au second membre d'une
Definition Source_base.h:42
int line_size() const
Definition TRUSTVect.tpp:67
void ajoute(_SCALAR_TYPE_ alpha, const TRUSTVect &y, Mp_vect_options opt=VECT_ALL_ITEMS)
Definition TRUSTVect.tpp:52
class Terme_Source_Qdm_lambdaup_VEF_Face
void mettre_a_jour(double) override
DOES NOTHING - to override in derived classes.
DoubleTab & calculer(DoubleTab &) const override
void associer_domaines(const Domaine_dis_base &, const Domaine_Cl_dis_base &) override
DoubleTab & ajouter(DoubleTab &) const override