TrioCFD 1.9.9_beta
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 Prints to an output stream in the format: size
30 *
31 * valeur(0) ... valeur(i) ... valeur(taille-1)
32 *
33 * @param os an output stream
34 * @return the modified output stream
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 Updates the time.
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 Reads from an input stream in the 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 is an input stream
67 * @return the modified input stream
68 * @throws opening brace expected
69 * @throws unknown keyword at this location
70 * @throws closing brace expected
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 Not implemented!!
214 *
215 * @param ch the source boundary field
216 * @return reference to this boundary field
217 */
219{
220 return *this;
221}
222
224{
225
226 // Access the equation from the unknown, then access the medium
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 /// initialisation data ///
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(); // retrieve the 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) ) ; // square root of the average inlet face area, used as a characteristic mesh size
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); // estimate of turbulent kinetic energy = 3/2*(I*Uref)^2
278 //double turbDissRate = pow(Cmu,0.75)*pow(turbKinEn,1.5)/lenghtScale; // compute epsilon for a fully developed pipe flow. TODO: adapt for grid turbulence? (energy decay)
279
280 /////////////////////////////////////////////
281 /// remarkable wavenumber values ///
282 /////////////////////////////////////////////
283
284 double kappa_max = (pi/dmin)*ratioCutoffWavenumber; // largest wavenumber (depends on the mesh)
285 double kappa_e = 9*pi*amp/(55*lenghtScale); // energy peak wavenumber
286 double kappa_eta = pow((turbDissRate/(visc*visc*visc)),0.25); // Kolmogorov wavenumber
287 double kappa_min = kappa_e / KeOverKmin; // smallest wavenumber
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 /// random generation of 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 /// wave vector in Cartesian coordinates ///
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 /// direction orthogonal to the wave vector ///
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 /// retrieval of the face barycenters ///
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 /// AUTOCORRELATION SETUP ///
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}
class Ch_front_var_instationnaire_dep This abstract class represents a field on a boundary,
int initialiser(double temps, const Champ_Inc_base &inco) override
Initialization at the beginning of calculation.
Class Champ_Inc_base.
int lire_dimension(Entree &, const Nom &)
Verification of the field dimension Returns the dimension of the field.
class Champ_front_base Base class for the hierarchy of boundary fields.
virtual DoubleTab & valeurs() override
Returns the array of field values.
Champ_front_synt Derived from Champ_front_base.
void mettre_a_jour(double temps) override
DOES NOTHING, to override.
Champ_front_base & affecter_(const Champ_front_base &ch) override
Not implemented!!
int initialiser(double temps, const Champ_Inc_base &inco) override
Updates the time.
DoubleTab & valeurs_au_temps(double temps) override
Returns the values at the desired time.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Equation_base The role of an equation is the calculation of one or more fields....
virtual const Milieu_base & milieu() const =0
Schema_Temps_base & schema_temps()
Returns the time scheme associated with the equation.
void calculer_surfaces(DoubleVect_t &surf) const
Computes the surface area of the faces.
Definition Faces.cpp:487
void calculer_centres_gravite(DoubleTab_t &xv) const
Computes the centers of gravity of each face.
Definition Faces.cpp:768
virtual void fixer_nb_comp(int i)
Sets the number of components of the field.
virtual int nb_comp() const
Definition Field_base.h:56
Base class for an incompressible fluid and its properties:
Definition Fluide_base.h:36
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
Returns the associated geometric boundary.
Milieu_base This class is the base of the (physical) medium hierarchy.
Definition Milieu_base.h:50
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
static double mp_sum(double)
Computes the sum of x over all processors in the current group.
Definition Process.cpp:145
static double mp_sum_as_double(int v)
Definition Process.h:97
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
double pas_de_temps() const
Returns the current time step (delta_t).
Base class for output streams.
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")