TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
RK3_FT.cpp
1/****************************************************************************
2* Copyright (c) 2015 - 2016, 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 <RK3_FT.h>
17#include <Equation_base.h>
18#include <Probleme_base.h>
19#include <Transport_Interfaces_FT_Disc.h>
20#include <TRUSTTabs.h>
21
22// XD rk3_ft runge_kutta_ordre_3 rk3_ft INHERITS_BRACE Keyword for Runge Kutta time scheme for Front_Tracking
23// XD_CONT calculation.
24Implemente_instanciable(RK3_FT,"RK3_FT",RK3);
25
27
29
30
32{
33 Cerr << "on ne devrait pas passer ds faire_un_pas_de_temps_eqn_base de RK3_FT" << finl;
34 return 0;
35}
36
37/*! @brief Effectue un pas de temps de Runge Kutta d'ordre 3, sur l'equation passee en parametre.
38 *
39 * Le schema de Runge Kutta d'ordre 3
40 * (cas 7 de Williamson) s'ecrit :
41 * q1=h f(x0)
42 * x1=x0+b1 q1
43 * q2=h f(x1) +a2 q1
44 * x2=x1+b2 q2
45 * q3=h f(x2)+a3 q2
46 * x3=x2+b3 q3
47 * avec a1=0, a2=-5/9, a3=-153/128
48 * b1=1/3, b2=15/16, b3=8/15
49 *
50 * @param (Equation_base& eqn) l'equation que l'on veut faire avancer d'un pas de temps
51 * @return (int) renvoie toujours 1
52 */
53bool RK3_FT::iterateTimeStep(bool& converged)
54{
55
56 Probleme_base& prob=pb_base();
57
58 int i;
59 const double save_temps_courant=temps_courant_;
60 int nb_eqn=prob.nombre_d_equations();
61 for(i=0; i<nb_eqn; i++)
62 if (prob.equation(i).equation_non_resolue())
63 {
64 Cerr << "Option equation_non_resolue is not yet supported for the " << que_suis_je() << " scheme." << finl;
66 }
67 double dt_temp;
68
69 double a2=-5./9.;
70 double a3=-153./128.;
71 double b1=1./3.;
72 double b2=15./16.;
73 double b3=8./15.;
74
75 const double epsilon_dt = dt_ * 0.001;
76
77 Champ_Inc_base& inconnue_ = prob.equation(0).inconnue();
78
79 DoubleTab qNSi(inconnue_.valeurs());
80 DoubleTab qNSj(inconnue_.valeurs());
81 DoubleTabFT qIi;
82 DoubleTabFT qIj;
83
84 // ufinal =VI.valeurs();
85 // exemple
86 // equ_int.calculer_vitesse_transport_interpolee(
87 // champ_eulerien,
88 // equ_int.maillage_interface(),
89 // resu_vitesse_lagrange,
90 // 1 /* reprojeter la vitesse L2 a partir de N.S. */ );
91 //
92 // equ_int.transporter_sans_changement_topologie(vitesse, coeff);
93
94 //ss pas de temps 1
95 //mise a jour des conditions aux limites
96 ////////////////////////////////////////////////////////////////////////////////
97
98 for(i=0; i<nb_eqn; i++)
99 {
100 // Astuce pour calculer la derivee gpoint de la vitesse imposee au bord:
101 // gpoint est calcule par difference finie entre les deux derniers
102 // "mettre_a_jour". On fait une difference finie avec un delta_t tout petit:
103 prob.equation(i).domaine_Cl_dis().mettre_a_jour(temps_courant_ - epsilon_dt);
106 }
107
108 temps_courant_ += dt_*1./3.;
109
110 dt_temp=dt_;
111 dt_=0.;
112 prob.equation(0).initTimeStep(dt_);
113 dt_=dt_temp;
114
115 prob.equation(0).derivee_en_temps_inco(qNSi);
116 inconnue_.futur() = inconnue_.valeurs();
117 // B.M.: calcul identique a l'implementation precedente:
118 inconnue_.futur().ajoute_sans_ech_esp_virt(b1 * dt_, qNSi, VECT_ALL_ITEMS);
119
120 if (prob.que_suis_je() == "Probleme_FT_Disc_gen")
121 {
123 const Transport_Interfaces_FT_Disc& equ_int_const = equ_int;
125 equ_int_const.maillage_interface(),
126 qIi,
127 1);
129 }
130
131
132 //ss pas de temps 2
133
135
136 //mise a jour des conditions aux limites
137 ////////////////////////////////////////////////////////////////////////////////////////////
138
139 for(i=0; i<nb_eqn; i++)
140 {
141 prob.equation(i).domaine_Cl_dis().mettre_a_jour(temps_courant_ - epsilon_dt);
144 }
145
146 temps_courant_ += dt_*5./12.;
147
148 dt_temp=dt_;
149 dt_=0.;
150 prob.equation(0).initTimeStep(dt_);
151 dt_=dt_temp;
152
153
154 prob.equation(0).derivee_en_temps_inco(qNSj);
155 qNSj.ajoute_sans_ech_esp_virt(a2, qNSi, VECT_ALL_ITEMS);
156
157 inconnue_.futur() = inconnue_.valeurs();
158 inconnue_.futur().ajoute_sans_ech_esp_virt(b2 * dt_, qNSj, VECT_ALL_ITEMS);
159
160 if (prob.que_suis_je() == "Probleme_FT_Disc_gen")
161 {
163 const Transport_Interfaces_FT_Disc& equ_int_const = equ_int;
165 equ_int_const.maillage_interface(),
166 qIj,
167 1);
168 qIi *= -1.*a2;
169 qIj -= qIi;
171 }
172
173
174 //ss pas de temps 3
175
177
178 //mise a jour des conditions aux limites
179 //////////////////////////////////////////////////////////////////////////////////////////////
180
181 for(i=0; i<nb_eqn; i++)
182 {
183 prob.equation(i).domaine_Cl_dis().mettre_a_jour(temps_courant_ - epsilon_dt);
186 }
187
188 temps_courant_ += dt_*1./4.;
189
190 dt_temp=dt_;
191 dt_=0.;
192 prob.equation(0).initTimeStep(dt_);
193 dt_=dt_temp;
194
195 prob.equation(0).derivee_en_temps_inco(qNSi);
196 qNSi.ajoute_sans_ech_esp_virt(a3, qNSj);
197
198 inconnue_.futur() = qNSi;
199 inconnue_.futur() *= b3 * dt_;
200 update_critere_statio(inconnue_.futur(), prob.equation(0));
201 inconnue_.futur() += inconnue_.valeurs();
202
203
204 if (prob.que_suis_je() == "Probleme_FT_Disc_gen")
205 {
207 const Transport_Interfaces_FT_Disc& equ_int_const = equ_int;
209 equ_int_const.maillage_interface(),qIi,1);
210 qIj *= -1.*a3;
211 qIi -= qIj;
213 }
214
215 //fin du pas de temps
216 if (prob.que_suis_je() == "Probleme_FT_Disc_gen")
217 {
218 // pour ne pas deplacer les interfaces:
219 inconnue_.valeurs() = 0;
220 // on tourne la roue juste apres donc on s'en fout de perdre les valeurs.
222 }
223
225 ////assert(nb_eqn < 3);
226
227 // pb.postraiter();
228
229 temps_courant_=save_temps_courant;
230
231 // On applique le RK3 sur les equations restantes:
232 int premiere_equation;
233 if (prob.que_suis_je() == "Probleme_FT_Disc_gen")
234 premiere_equation=2;
235 else
236 premiere_equation=1;
237 for(i=premiere_equation; i<nb_eqn; i++)
239
240 converged=true;
241 return true;
242}
243
244
246{
247 // Il s'agit d'un prototype fait pour des problemes couples dont chacun a au plus deux equations :
248 // NS et une equation pr le transport de l'interface.
249 int i;
250 int n_pb= pbc.nb_problemes();
251 for(i=0; i<n_pb; i++)
252 {
253 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
254 const int nb_eqn=pb.nombre_d_equations();
255 if (nb_eqn > 2)
256 {
257 Cerr << "RK3_FT gere au plus deux equations par pb, votre nb d'equations est : "
258 << nb_eqn << finl;
259 assert(0);
260 }
261 }
262
263 double save_temps_courant=temps_courant_;
264 double dt_temp;
265
266 double a2=-5./9.;
267 double a3=-153./128.;
268 double b1=1./3.;
269 double b2=15./16.;
270 double b3=8./15.;
271
272 OBS_PTR(Champ_Inc_base) * inconnues = new OBS_PTR(Champ_Inc_base)[n_pb];
273 VECT(DoubleTab) qNSi(n_pb);
274 VECT(DoubleTab) qNSj(n_pb);
275 DoubleTabFT qIi;
276 DoubleTabFT qIj;
277 for (i=0; i<n_pb; i++)
278 {
279 // <OBS_PTR(Champ_Inc_base)> = <Champ_Inc_base>
280 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
281 inconnues[i] = pb.equation(0).inconnue();
282 qNSi[i] = inconnues[i]->valeurs();
283 qNSj[i] = inconnues[i]->valeurs();
284 }
285
286 //ss pas de temps 1
287 //mise a jour des conditions aux limites
288 for(i=0; i<n_pb; i++)
289 {
290 ////Probleme_base& pb = pbc.probleme(i);
291 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
292 const int nb_eqn=pb.nombre_d_equations();
293 for(int j=0; j<nb_eqn; j++)
294 {
295 Equation_base& eqn = pb.equation(j);
297 }
298 }
299 temps_courant_ += dt_*1./3.;
300
301 dt_temp=dt_;
302 dt_=0.;
303
304 for(i=0; i<n_pb; i++)
305 {
306 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
308 }
309
310 dt_=dt_temp;
311
312 for(i=0; i<n_pb; i++)
313 {
314 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
315 pb.equation(0).derivee_en_temps_inco(qNSi[i]);
316
317 //on teste si l'etat stationnaire est atteind
318 double accroissement_max_abs=qNSi[i].mp_max_abs_vect();
319 set_stationnaire_atteint() *= ( accroissement_max_abs < seuil_statio_ );
320
321 inconnues[i]->futur() = inconnues[i]->valeurs();
322 inconnues[i]->futur().ajoute_sans_ech_esp_virt(b1 * dt_, qNSi[i], VECT_ALL_ITEMS);
323
324 if (pbc.probleme(i).que_suis_je() == "Probleme_FT_Disc_gen")
325 {
328 const Transport_Interfaces_FT_Disc& equ_int_const = equ_int;
329 equ_int.calculer_vitesse_transport_interpolee(inconnues[i].valeur(),
330 equ_int_const.maillage_interface(),
331 qIi,
332 1);
334 }
335 }
336
337 //ss pas de temps 2
338 //mise a jour des conditions aux limites
339 for(i=0; i<n_pb; i++)
340 {
341 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
343 const int nb_eqn=pb.nombre_d_equations();
344 for(int j=0; j<nb_eqn; j++)
345 {
346 Equation_base& eqn = pb.equation(j);
348 }
349 }
350 temps_courant_ += dt_*5./12.;
351
352 dt_temp=dt_;
353 dt_=0.;
354 for(i=0; i<n_pb; i++)
355 {
356 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
358 }
359 dt_=dt_temp;
360
361 for(i=0; i<n_pb; i++)
362 {
363 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
364 pb.equation(0).derivee_en_temps_inco(qNSj[i]);
365 qNSj[i].ajoute_sans_ech_esp_virt(a2, qNSi[i]);
366 inconnues[i]->futur() = inconnues[i]->valeurs();
367 inconnues[i]->futur().ajoute(b2 * dt_, qNSj[i], VECT_ALL_ITEMS);
368 if (pbc.probleme(i).que_suis_je() == "Probleme_FT_Disc_gen")
369 {
372 const Transport_Interfaces_FT_Disc& equ_int_const = equ_int;
373 equ_int.calculer_vitesse_transport_interpolee(inconnues[i].valeur(),
374 equ_int_const.maillage_interface(),
375 qIj,
376 1);
377 qIi *= -1.*a2;
378 qIj -= qIi;
380 }
381 }
382
383 //ss pas de temps 3
384 //mise a jour des conditions aux limites
385 for(i=0; i<n_pb; i++)
386 {
387 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
389 const int nb_eqn=pb.nombre_d_equations();
390 for(int j=0; j<nb_eqn; j++)
391 {
392 Equation_base& eqn = pb.equation(j);
394 }
395 }
396 temps_courant_ += dt_*1./4.;
397
398 dt_temp=dt_;
399 dt_=0.;
400 for(i=0; i<n_pb; i++)
401 {
402 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
404 }
405 dt_=dt_temp;
406
407 for(i=0; i<n_pb; i++)
408 {
409 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
410 pb.equation(0).derivee_en_temps_inco(qNSi[i]);
411 qNSi[i].ajoute_sans_ech_esp_virt(a3, qNSj[i], VECT_ALL_ITEMS);
412 inconnues[i]->futur() = inconnues[i]->valeurs();
413 inconnues[i]->futur().ajoute_sans_ech_esp_virt(b3 * dt_, qNSi[i], VECT_ALL_ITEMS);
414 if (pbc.probleme(i).que_suis_je() == "Probleme_FT_Disc_gen")
415 {
418 const Transport_Interfaces_FT_Disc& equ_int_const = equ_int;
419 equ_int.calculer_vitesse_transport_interpolee(inconnues[i].valeur(),
420 equ_int_const.maillage_interface(),
421 qIi,
422 1);
423 qIj *= -1.*a3;
424 qIi = 0.;
426 }
427 }
428
429 //fin du pas de temps
430 for(i=0; i<n_pb; i++)
431 {
432 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
433
434 if ( pb.que_suis_je() == "Probleme_FT_Disc_gen")
435 {
436 // pour ne pas deplacer les interfaces:
437 inconnues[i]->valeurs() = 0;
438 // on tourne la roue juste apres donc on s'en fout de perdre les valeurs.
440 }
442 // On applique le RK3 sur les equations restantes:
443 int premiere_equation;
444 if (pb.que_suis_je() == "Probleme_FT_Disc_gen")
445 premiere_equation=2;
446 else
447 premiere_equation=1;
448 for(i=premiere_equation; i<pb.nombre_d_equations(); i++)
450 }
451 temps_courant_=save_temps_courant;
452 delete[] inconnues;
453
454 return 1;
455}
456
Classe Champ_Inc_base.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
const Probleme_U & probleme(int i) const
Definition Couplage_U.h:127
int nb_problemes() const
Definition Couplage_U.h:117
void calculer_derivee_en_temps(double t1, double t2)
Calcule le taux d'accroissement des CLs instationnaires entre t1 et t2.
virtual void mettre_a_jour(double temps)
Effectue une mise a jour en temps de toutes les conditions aux limites.
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 int equation_non_resolue() const
virtual const Champ_Inc_base & inconnue() const =0
virtual void mettre_a_jour(double temps)
La valeur de l'inconnue sur le pas de temps a ete calculee.
virtual DoubleTab & derivee_en_temps_inco(DoubleTab &)
Returns the time derivative of the unknown I of the equation: dI/dt = M-1*(sum(operators(I) + sources...
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limite discretisee associee a l'equation.
virtual bool initTimeStep(double dt)
Allocation et initialisation de l'inconnue et des CLs jusqu'a present+dt.
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_Couple C'est la classe historique de couplage de TRUST.
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 exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
classe RK3 Cette classe represente un schema en temps de Runge Kutta d'ordre 3
Definition RK3_FT.h:43
bool iterateTimeStep(bool &converged) override
Effectue un pas de temps de Runge Kutta d'ordre 3, sur l'equation passee en parametre.
Definition RK3_FT.cpp:53
int faire_un_pas_de_temps_eqn_base(Equation_base &) override
Definition RK3_FT.cpp:31
int faire_un_pas_de_temps_pb_couple(Probleme_Couple &)
Definition RK3_FT.cpp:245
: classe RK3 Cette classe represente un schema en temps de Runge Kutta d'ordre 3, cas 7 de Williamson...
OBS_PTR(Probleme_base) mon_probleme
double dt_
Pas de temps de calcul.
Probleme_base & pb_base()
virtual int faire_un_pas_de_temps_eqn_base(Equation_base &)=0
void update_critere_statio(const DoubleTab &tab_critere, Equation_base &equation)
//Actualisation de stationnaire_atteint_ et residu_ (critere residu_<seuil_statio_)
Classe de base des flux de sortie.
Definition Sortie.h:52
_TYPE_ mp_max_abs_vect(Mp_vect_options opt=VECT_REAL_ITEMS) const
Definition TRUSTVect.h:160
void ajoute_sans_ech_esp_virt(_SCALAR_TYPE_ alpha, const TRUSTVect &y, Mp_vect_options opt=VECT_REAL_ITEMS)
virtual void transporter_sans_changement_topologie(DoubleTab &vitesse, const double coeff, const double temps)
virtual void calculer_vitesse_transport_interpolee(const Champ_base &champ_vitesse, const Maillage_FT_Disc &m, DoubleTab &vitesse_noeuds, int nv_calc) const
const Maillage_FT_Disc & maillage_interface() const