TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Champ_front_synt.cpp
1/****************************************************************************
2* Copyright (c) 2025, 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 <Frontiere_dis_base.h>
17#include <Schema_Temps_base.h>
18#include <Navier_Stokes_std.h>
19#include <Champ_front_synt.h>
20#include <Champ_Uniforme.h>
21#include <Fluide_base.h>
22#include <Domaine_VF.h>
23#include <Frontiere.h>
24#include <random>
25#include <string>
26
27Implemente_instanciable(Champ_front_synt,"Champ_front_synt",Ch_front_var_instationnaire_dep);
28
29/*! @brief Impression sur un flot de sortie au format: taille
30 *
31 * valeur(0) ... valeur(i) ... valeur(taille-1)
32 *
33 * @param (Sortie& os) un flot de sortie
34 * @return (Sortie&) le flot de sortie modifie
35 */
37{
38 const DoubleTab& tab=valeurs();
39 os << tab.size() << " ";
40 for(int i=0; i<tab.size(); i++)
41 os << tab(0,i);
42 return os;
43}
44
45/*! @brief Mise a jour du temps
46 *
47 */
48
50{
52 return 0;
53
54 ref_inco_ = inco;
55 temps_d_avant_ = tps;
56
57 return 1;
58}
59
60
61/*! @brief Lecture a partir d'un flot d'entree au format: nombre_de_composantes
62 *
63 * moyenne moyenne(0) ... moyenne(nombre_de_composantes-1)
64 * moyenne amplitude(0) ... amplitude(nombre_de_composantes-1)
65 *
66 * @param (Entree& is) un flot d'entree
67 * @return (Entree&) le flot d'entree modifie
68 * @throws accolade ouvrante attendue
69 * @throws mot clef inconnu a cet endroit
70 * @throws accolade fermante attendue
71 */
73{
74
75 int dim;
77 if( dim != 3)
78 {
79 Cerr << "Error the dimension must be equal to 3" << finl;
80 exit();
81 }
82 Motcle motlu;
83 Motcles les_mots(9);
84 les_mots[0]="moyenne";
85 les_mots[1]="lenghtScale";
86 les_mots[2]="nbModes";
87 les_mots[3]="turbKinEn";
88 les_mots[4]="turbDissRate";
89 les_mots[5]="KeOverKmin";
90 les_mots[6]="timeScale";
91 les_mots[7]="ratioCutoffWavenumber";
92 les_mots[8]="dir_fluct";
93
94 is >> motlu;
95 if (motlu != "{")
96 {
97 Cerr << "Error while reading Champ_front_synt" << finl;
98 Cerr << "We expected a { instead of " << motlu << finl;
99 exit();
100 }
101 int cpt = 0;
102 is >> motlu;
103 while (motlu!="}")
104 {
105 int rang=les_mots.search(motlu);
106 switch(rang)
107 {
108 case 0:
109 {
110 cpt++;
111 moyenne.resize(dim);
112 fixer_nb_comp(dim);
113 for(int i=0; i<dim; i++)
114 is >> moyenne(i);
115 break;
116 }
117 case 1:
118 {
119 cpt++;
120 is >> lenghtScale;
121 break;
122 }
123 case 2:
124 {
125 cpt++;
126 is >> nbModes;
127 break;
128 }
129 case 3:
130 {
131 cpt++;
132 is >> turbKinEn;
133 break;
134 }
135 case 4:
136 {
137 cpt++;
138 is >> turbDissRate;
139 break;
140 }
141 case 5:
142 {
143 cpt++;
144 is >> KeOverKmin;
145 break;
146 }
147 case 6:
148 {
149 cpt++;
150 is >> timeScale;
151 break;
152 }
153 case 7:
154 {
155 cpt++;
157 break;
158 }
159 case 8:
160 {
161 cpt++;
162 dir_fluct.resize(dim);
163 fixer_nb_comp(dim);
164 for(int i=0; i<dim; i++)
165 {
166 is >> dir_fluct(i);
167 }
168 break;
169 }
170 default :
171 {
172 if (motlu == "p")
173 {
174 Cerr << "Error while reading Champ_front_synt:" << finl;
175 Cerr << " Parameter " << motlu << " has been renamed to KeOverKmin since TRUST v1.9.0"<< finl;
176 Cerr << " Update your datafile."<< finl;
177 }
178 else
179 {
180 Cerr << "Error while reading Champ_front_synt:" << finl;
181 Cerr << " " << motlu << "is not understood."<< finl;
182 Cerr << " We are expecting a parameter among " << les_mots << finl;
183 }
184 exit();
185 }
186 }
187 is >> motlu;
188 }
189 if(cpt != 9)
190 {
191 Cerr << "Error while reading Champ_front_synt: wrong number of parameters" << finl;
192 Cerr << "You should specify all these parameters: " << les_mots << finl;
193 exit();
194 }
195 if( lenghtScale == 0 || nbModes == 0 || turbKinEn == 0 || turbDissRate == 0 || KeOverKmin == 0 || timeScale == 0 || ratioCutoffWavenumber == 0 )
196 {
197 Cerr << "Error while reading Champ_front_synt" << finl;
198 Cerr << "There is at least one parameter among: timeScale, lenghtScale, nbModes, turbKinEn, turbDissRate and ratioCutoffWavenumber set to 0" << finl;
199 exit();
200 }
201
202 for(int i=0; i<dim; i++)
203 {
204 Cerr << dir_fluct(i) << " ";
205 }
206 Cerr << finl;
207
208
209 return is;
210}
211
212
213/*! @brief Pas code !!
214 *
215 * @param (Champ_front_base& ch)
216 * @return (Champ_front_base&)
217 */
219{
220 return *this;
221}
222
224{
225
226 // Acceder a l'equation depuis l'inconnue, ensuite acceder au milieu
227 const Equation_base& equ = ref_inco_->equation();
228 const Milieu_base& mil = equ.milieu();
229
230 /*
231 Cerr << "*************************************************" << finl;
232 Cerr << "mil = " << mil.masse_volumique()(0,0) << finl;
233 Cerr << "temps = " << equ.inconnue().temps() << finl;
234 Cerr << "dt = " << equ.schema_temps().pas_de_temps() << finl;
235 Cerr << "visco cinematique = " << ref_cast(Fluide_base,mil).viscosite_cinematique().valeur()(0,0) << finl;
236 Cerr << "visco dynamique = " << ref_cast(Fluide_base,mil).viscosite_dynamique()(0,0) << finl;
237 Cerr << "*************************************************" << finl;
238
239 const Champ_Don_base& visco = ref_cast(Fluide_base,mil).viscosite_dynamique();
240 if (sub_type(Champ_Uniforme,visco.valeur()))
241 Cerr << "visco dynamique = " << visco(0,0) << finl;
242 else
243 {
244 const DoubleTab& val_visco = visco->valeurs();
245 Cerr << "valeurs viscosite = " << val_visco << finl;\
246 }
247 */
248
249 ////////////////////////////////////////////
250 /// donnees d'initialisation ///
251 ////////////////////////////////////////////
252
253 double visc = ref_cast(Fluide_base,mil).viscosite_cinematique().valeurs()(0,0);
254 const Front_VF& front = ref_cast(Front_VF,la_frontiere_dis.valeur());
255 int nb_face = front.nb_faces(); // real only
256 const Faces& tabFaces = front.frontiere().faces(); // recuperation des faces
257
258 //Cerr << "We store : temps_d_avant_ = "<<temps_d_avant_<<finl;
259 DoubleTab& tab_avant=valeurs_au_temps(temps_d_avant_);
260 DoubleTab& tab=valeurs_au_temps(temps);
261
262 DoubleVect aireFaces; // Attention : contains real + virtual faces
263 tabFaces.calculer_surfaces(aireFaces);
264
265 double sum_aire=0.;
266 for(int i=0; i<nb_face; i++)
267 sum_aire += aireFaces[i];
268
269 sum_aire = mp_sum(sum_aire);
270 double dmin = sqrt( sum_aire / mp_sum_as_double(nb_face) ) ; // on prend la racine de l'aire moyenne des faces d'entree pour avoir une taille de maille caracteristique
271
272 //double Uref = 0.; // vitesse de reference = norme du vecteur moyenne
273 //for (int i=0; i<moyenne.size_reelle(); i++) Uref += moyenne(i)*moyenne(i);
274 //Uref = sqrt(Uref);
275
276 //double turbScale = turbIntensity * Uref; //urms=I*Uref
277 //double turbKinEn = 3./2. * (turbIntensity * Uref) * (turbIntensity * Uref); // evaluation de l'energie cinetique turbulente = 3/2*(I*Uref)^2
278 //double turbDissRate = pow(Cmu,0.75)*pow(turbKinEn,1.5)/lenghtScale; // calcul de epsilon pour un ecoulement etabli en conduite. A faire pour un ecoulement de grille ? (decroissance energetique)
279
280 /////////////////////////////////////////////
281 /// valeurs remarquables du nombre d'onde ///
282 /////////////////////////////////////////////
283
284 double kappa_max = (pi/dmin)*ratioCutoffWavenumber; // plus grand nombre d'onde (depend du maillage)
285 double kappa_e = 9*pi*amp/(55*lenghtScale); // pic d'energie
286 double kappa_eta = pow((turbDissRate/(visc*visc*visc)),0.25); // nombre d'onde de Kolmogorov
287 double kappa_min = kappa_e / KeOverKmin; // plus petit nombre d'onde
288 //double delta_kappa = (min(kappa_eta,kappa_max) - kappa_min) / nbModes; // repartition lineaire des modes => pas bon
289 double delta_kappa = pow( (std::min(kappa_eta,kappa_max) / kappa_min ), 1./(nbModes-1.)); // repartition logarithmique des modes => OK
290 if (kappa_max <= kappa_min)
291 {
292 Cerr << "Error: kappa_max(=" << kappa_max << ") <= kappa_min(=" << kappa_min << ")" << finl;
293 Cerr << "You should either refine your mesh or increase the ratioCutoffWavenumber value in " << que_suis_je() << finl;
295 }
296 //Cerr << "Remarkable wavenumbers for the method of synthetic turbulence generation:" << finl;
297 //Cerr << "kappa_min = " << kappa_min << finl;
298 //Cerr << "kappa_e = " << kappa_e << finl;
299 //Cerr << "kappa_mesh = " << kappa_max << finl;
300 //Cerr << "kappa_eta = " << kappa_eta << finl;
301 //Cerr << "delta_kappa = " << delta_kappa << finl;
302
303 DoubleVect kappa_face(nbModes+1);
304 DoubleVect kappa_center(nbModes);
305 DoubleVect dkn(nbModes);
306
307 DoubleVect kappa_x(nbModes);
308 DoubleVect kappa_y(nbModes);
309 DoubleVect kappa_z(nbModes);
310
311 DoubleVect sigma_x(nbModes);
312 DoubleVect sigma_y(nbModes);
313 DoubleVect sigma_z(nbModes);
314
315 DoubleVect phi(nbModes);
316 DoubleVect alpha(nbModes);
317 DoubleVect psi(nbModes);
318 DoubleVect tetha(nbModes);
319
320 ////////////////////////////////////////////
321 /// generation aleatoire des angles ///
322 ////////////////////////////////////////////
323
324 for(int i = 0; i<nbModes; i++)
325 {
326 phi(i) = drand48()* 2*pi ;
327 alpha(i) = drand48()* 2*pi ;
328 psi(i) = drand48()* 2*pi ;
329 //tetha(i) = drand48()* pi ; // pour une densite de probabilite de 1/pi => pas bon
330 tetha(i) = acos(1-2*drand48()) ; // pour une densite de probabilite de 0.5*sin(theta) => OK
331
332 /// creation vecteur onde en coordonnee cartesienne ///
333 kappa_x(i) = sin(tetha(i))*cos(phi(i));
334 kappa_y(i) = sin(tetha(i))*sin(phi(i));
335 kappa_z(i) = cos(tetha(i));
336
337 /// creation de la direction orthogonal au vecteur onde ///
338 sigma_x(i) = cos(phi(i))*cos(tetha(i))*cos(alpha(i)) - sin(phi(i))*sin(alpha(i));
339 sigma_y(i) = sin(phi(i))*cos(tetha(i))*cos(alpha(i)) + cos(phi(i))*sin(alpha(i));
340 sigma_z(i) = -sin(tetha(i))*cos(alpha(i));
341 }
342
343 //for(int i = 0; i< nbModes+1; i++) kappa_face(i) = kappa_min + delta_kappa*i; // repartition lineaire
344 for(int i = 0; i< nbModes+1; i++)
345 {
346 kappa_face(i) = kappa_min * pow(delta_kappa,i); // repartition logarithmique
347 //Cerr << "Kappa(n) = " << kappa_face(i) << finl;
348 }
349
350 for(int i = 0; i< nbModes; i++)
351 {
352 kappa_center(i) = 1.0/2.0*(kappa_face(i+1)+kappa_face(i));
353 dkn(i) = kappa_face(i+1)- kappa_face(i);
354 }
355
356 /// recuperation des centres de gravite ///
357 DoubleTab centreGrav(nb_face);
358 tabFaces.calculer_centres_gravite(centreGrav);
359
360 for( int i = 0; i<nb_face; i++ )
361 {
362 DoubleTab turb(nb_comp());
363 //recuperer les points du milieu du maillage
364
365 double x_center = centreGrav(i,0);
366 double y_center = centreGrav(i,1);
367 double z_center = centreGrav(i,2);
368
369 for(int m = 0; m<nbModes; m++)
370 {
371 double kx = kappa_x(m) * kappa_center(m);
372 double ky = kappa_y(m) * kappa_center(m);
373 double kz = kappa_z(m) * kappa_center(m);
374
375 double arg = kx*x_center + ky*y_center + kz*z_center + psi(m);
376
377 double tfunk = cos(arg);
378
379 double karman_spectrum = amp/kappa_e * (2.*turbKinEn/3.) * pow((kappa_center(m)/kappa_e),4)/pow(1+pow(kappa_center(m)/kappa_e, 2),17.0/6.0) * exp(-2*(pow(kappa_center(m)/kappa_eta, 2)));
380 double amplitude = sqrt(karman_spectrum * dkn(m));
381
382 turb(0) += 2*amplitude*tfunk*sigma_x(m);
383 turb(1) += 2*amplitude*tfunk*sigma_y(m);
384 turb(2) += 2*amplitude*tfunk*sigma_z(m);
385
386 //Cerr << "Kappa = " << kappa_center(m) << finl;
387 //Cerr << "Kappa, Spectre = " << kappa_center(m) << " , " << karman_spectrum << finl;
388 //Cerr << "Amplitude = " << amplitude << finl;
389 }
390
391 //////////////////////////////////////
392 /// MISE EN PLACE AUTOCORRELATION ///
393 //////////////////////////////////////
394
395 double dt = equ.schema_temps().pas_de_temps();
396 double a = exp(-dt/timeScale);
397 double b = sqrt(1-a*a);
398
399 tab(i,0) = moyenne(0) + dir_fluct(0) * (a * (tab_avant(i,0) - moyenne(0)) + b * turb(0));
400 tab(i,1) = moyenne(1) + dir_fluct(1) * (a * (tab_avant(i,1) - moyenne(1)) + b * turb(1));
401 tab(i,2) = moyenne(2) + dir_fluct(2) * (a * (tab_avant(i,2) - moyenne(2)) + b * turb(2));
402
403 //Cerr << "r, a, b = " << dt/timeScale << " , " << a << " , " << b << finl;
404 //Cerr << "Uprime, uprime = " << tab(i,0) << " , " << turb(0) << finl;
405 //Cerr << "face, Uprime, uprime = " << i << " , " << tab(i,0) << " , " << turb(0) << finl;
406 }
407
409 temps_d_avant_ = temps;
410
411}
classe Ch_front_var_instationnaire_dep Cette classe abstraite represente un champ sur une frontiere,
int initialiser(double temps, const Champ_Inc_base &inco) override
Initialisation en debut de calcul.
Classe Champ_Inc_base.
int lire_dimension(Entree &, const Nom &)
Verification de la dimension du champ Renvoie la dimension du champ.
classe Champ_front_base Classe de base pour la hierarchie des champs aux frontieres.
virtual DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ.
classe Champ_front_synt Classe derivee de Champ_front_base
void mettre_a_jour(double temps) override
NE FAIT RIEN, a surcharger.
Champ_front_base & affecter_(const Champ_front_base &ch) override
Pas code !!
int initialiser(double temps, const Champ_Inc_base &inco) override
Mise a jour du temps.
DoubleTab & valeurs_au_temps(double temps) override
Renvoie les valeurs au temps desire.
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
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
void calculer_surfaces(DoubleVect_t &surf) const
Calcule la surface des faces.
Definition Faces.cpp:495
void calculer_centres_gravite(DoubleTab_t &xv) const
Calcule les centres de gravite de chaque face.
Definition Faces.cpp:776
virtual void fixer_nb_comp(int i)
Fixe le nombre de composantes du champ.
virtual int nb_comp() const
Definition Field_base.h:56
classe Fluide_base Cette classe represente un d'un fluide incompressible ainsi que
Definition Fluide_base.h:38
class Front_VF
Definition Front_VF.h:36
int nb_faces() const
Definition Front_VF.h:53
const Faces_t & faces() const
Definition Frontiere.h:54
const Frontiere & frontiere() const
Renvoie la frontiere geometrique associee.
classe Milieu_base Cette classe est la base de la hierarchie des milieux (physiques)
Definition Milieu_base.h:50
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
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
Definition Process.cpp:146
static double mp_sum_as_double(int v)
Definition Process.h:99
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
double pas_de_temps() const
Renvoie le pas de temps (delta_t) courant.
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ size() const
Definition TRUSTVect.tpp:45
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")