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
22Implemente_instanciable(RK3_FT,"RK3_FT",RK3);
23
25
27
28
30{
31 Cerr << "on ne devrait pas passer ds faire_un_pas_de_temps_eqn_base de RK3_FT" << finl;
32 return 0;
33}
34
35/*! @brief Effectue un pas de temps de Runge Kutta d'ordre 3, sur l'equation passee en parametre.
36 *
37 * Le schema de Runge Kutta d'ordre 3
38 * (cas 7 de Williamson) s'ecrit :
39 * q1=h f(x0)
40 * x1=x0+b1 q1
41 * q2=h f(x1) +a2 q1
42 * x2=x1+b2 q2
43 * q3=h f(x2)+a3 q2
44 * x3=x2+b3 q3
45 * avec a1=0, a2=-5/9, a3=-153/128
46 * b1=1/3, b2=15/16, b3=8/15
47 *
48 * @param (Equation_base& eqn) l'equation que l'on veut faire avancer d'un pas de temps
49 * @return (int) renvoie toujours 1
50 */
51bool RK3_FT::iterateTimeStep(bool& converged)
52{
53
54 Probleme_base& prob=pb_base();
55
56 int i;
57 const double save_temps_courant=temps_courant_;
58 int nb_eqn=prob.nombre_d_equations();
59 for(i=0; i<nb_eqn; i++)
60 if (prob.equation(i).equation_non_resolue())
61 {
62 Cerr << "Option equation_non_resolue is not yet supported for the " << que_suis_je() << " scheme." << finl;
64 }
65 double dt_temp;
66
67 double a2=-5./9.;
68 double a3=-153./128.;
69 double b1=1./3.;
70 double b2=15./16.;
71 double b3=8./15.;
72
73 const double epsilon_dt = dt_ * 0.001;
74
75 Champ_Inc_base& inconnue_ = prob.equation(0).inconnue();
76
77 DoubleTab qNSi(inconnue_.valeurs());
78 DoubleTab qNSj(inconnue_.valeurs());
79 DoubleTabFT qIi;
80 DoubleTabFT qIj;
81
82 // ufinal =VI.valeurs();
83 // exemple
84 // equ_int.calculer_vitesse_transport_interpolee(
85 // champ_eulerien,
86 // equ_int.maillage_interface(),
87 // resu_vitesse_lagrange,
88 // 1 /* reprojeter la vitesse L2 a partir de N.S. */ );
89 //
90 // equ_int.transporter_sans_changement_topologie(vitesse, coeff);
91
92 //ss pas de temps 1
93 //mise a jour des conditions aux limites
94 ////////////////////////////////////////////////////////////////////////////////
95
96 for(i=0; i<nb_eqn; i++)
97 {
98 // Astuce pour calculer la derivee gpoint de la vitesse imposee au bord:
99 // gpoint est calcule par difference finie entre les deux derniers
100 // "mettre_a_jour". On fait une difference finie avec un delta_t tout petit:
101 prob.equation(i).domaine_Cl_dis().mettre_a_jour(temps_courant_ - epsilon_dt);
104 }
105
106 temps_courant_ += dt_*1./3.;
107
108 dt_temp=dt_;
109 dt_=0.;
110 prob.equation(0).initTimeStep(dt_);
111 dt_=dt_temp;
112
113 prob.equation(0).derivee_en_temps_inco(qNSi);
114 inconnue_.futur() = inconnue_.valeurs();
115 // B.M.: calcul identique a l'implementation precedente:
116 inconnue_.futur().ajoute_sans_ech_esp_virt(b1 * dt_, qNSi, VECT_ALL_ITEMS);
117
118 if (prob.que_suis_je() == "Probleme_FT_Disc_gen")
119 {
121 const Transport_Interfaces_FT_Disc& equ_int_const = equ_int;
123 equ_int_const.maillage_interface(),
124 qIi,
125 1);
127 }
128
129
130 //ss pas de temps 2
131
133
134 //mise a jour des conditions aux limites
135 ////////////////////////////////////////////////////////////////////////////////////////////
136
137 for(i=0; i<nb_eqn; i++)
138 {
139 prob.equation(i).domaine_Cl_dis().mettre_a_jour(temps_courant_ - epsilon_dt);
142 }
143
144 temps_courant_ += dt_*5./12.;
145
146 dt_temp=dt_;
147 dt_=0.;
148 prob.equation(0).initTimeStep(dt_);
149 dt_=dt_temp;
150
151
152 prob.equation(0).derivee_en_temps_inco(qNSj);
153 qNSj.ajoute_sans_ech_esp_virt(a2, qNSi, VECT_ALL_ITEMS);
154
155 inconnue_.futur() = inconnue_.valeurs();
156 inconnue_.futur().ajoute_sans_ech_esp_virt(b2 * dt_, qNSj, VECT_ALL_ITEMS);
157
158 if (prob.que_suis_je() == "Probleme_FT_Disc_gen")
159 {
161 const Transport_Interfaces_FT_Disc& equ_int_const = equ_int;
163 equ_int_const.maillage_interface(),
164 qIj,
165 1);
166 qIi *= -1.*a2;
167 qIj -= qIi;
169 }
170
171
172 //ss pas de temps 3
173
175
176 //mise a jour des conditions aux limites
177 //////////////////////////////////////////////////////////////////////////////////////////////
178
179 for(i=0; i<nb_eqn; i++)
180 {
181 prob.equation(i).domaine_Cl_dis().mettre_a_jour(temps_courant_ - epsilon_dt);
184 }
185
186 temps_courant_ += dt_*1./4.;
187
188 dt_temp=dt_;
189 dt_=0.;
190 prob.equation(0).initTimeStep(dt_);
191 dt_=dt_temp;
192
193 prob.equation(0).derivee_en_temps_inco(qNSi);
194 qNSi.ajoute_sans_ech_esp_virt(a3, qNSj);
195
196 inconnue_.futur() = qNSi;
197 inconnue_.futur() *= b3 * dt_;
198 update_critere_statio(inconnue_.futur(), prob.equation(0));
199 inconnue_.futur() += inconnue_.valeurs();
200
201
202 if (prob.que_suis_je() == "Probleme_FT_Disc_gen")
203 {
205 const Transport_Interfaces_FT_Disc& equ_int_const = equ_int;
207 equ_int_const.maillage_interface(),qIi,1);
208 qIj *= -1.*a3;
209 qIi -= qIj;
211 }
212
213 //fin du pas de temps
214 if (prob.que_suis_je() == "Probleme_FT_Disc_gen")
215 {
216 // pour ne pas deplacer les interfaces:
217 inconnue_.valeurs() = 0;
218 // on tourne la roue juste apres donc on s'en fout de perdre les valeurs.
220 }
221
223 ////assert(nb_eqn < 3);
224
225 // pb.postraiter();
226
227 temps_courant_=save_temps_courant;
228
229 // On applique le RK3 sur les equations restantes:
230 int premiere_equation;
231 if (prob.que_suis_je() == "Probleme_FT_Disc_gen")
232 premiere_equation=2;
233 else
234 premiere_equation=1;
235 for(i=premiere_equation; i<nb_eqn; i++)
237
238 converged=true;
239 return true;
240}
241
242
244{
245 // Il s'agit d'un prototype fait pour des problemes couples dont chacun a au plus deux equations :
246 // NS et une equation pr le transport de l'interface.
247 int i;
248 int n_pb= pbc.nb_problemes();
249 for(i=0; i<n_pb; i++)
250 {
251 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
252 const int nb_eqn=pb.nombre_d_equations();
253 if (nb_eqn > 2)
254 {
255 Cerr << "RK3_FT gere au plus deux equations par pb, votre nb d'equations est : "
256 << nb_eqn << finl;
257 assert(0);
258 }
259 }
260
261 double save_temps_courant=temps_courant_;
262 double dt_temp;
263
264 double a2=-5./9.;
265 double a3=-153./128.;
266 double b1=1./3.;
267 double b2=15./16.;
268 double b3=8./15.;
269
270 OBS_PTR(Champ_Inc_base) * inconnues = new OBS_PTR(Champ_Inc_base)[n_pb];
271 VECT(DoubleTab) qNSi(n_pb);
272 VECT(DoubleTab) qNSj(n_pb);
273 DoubleTabFT qIi;
274 DoubleTabFT qIj;
275 for (i=0; i<n_pb; i++)
276 {
277 // <OBS_PTR(Champ_Inc_base)> = <Champ_Inc_base>
278 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
279 inconnues[i] = pb.equation(0).inconnue();
280 qNSi[i] = inconnues[i]->valeurs();
281 qNSj[i] = inconnues[i]->valeurs();
282 }
283
284 //ss pas de temps 1
285 //mise a jour des conditions aux limites
286 for(i=0; i<n_pb; i++)
287 {
288 ////Probleme_base& pb = pbc.probleme(i);
289 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
290 const int nb_eqn=pb.nombre_d_equations();
291 for(int j=0; j<nb_eqn; j++)
292 {
293 Equation_base& eqn = pb.equation(j);
295 }
296 }
297 temps_courant_ += dt_*1./3.;
298
299 dt_temp=dt_;
300 dt_=0.;
301
302 for(i=0; i<n_pb; i++)
303 {
304 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
306 }
307
308 dt_=dt_temp;
309
310 for(i=0; i<n_pb; i++)
311 {
312 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
313 pb.equation(0).derivee_en_temps_inco(qNSi[i]);
314
315 //on teste si l'etat stationnaire est atteind
316 double accroissement_max_abs=qNSi[i].mp_max_abs_vect();
317 set_stationnaire_atteint() *= ( accroissement_max_abs < seuil_statio_ );
318
319 inconnues[i]->futur() = inconnues[i]->valeurs();
320 inconnues[i]->futur().ajoute_sans_ech_esp_virt(b1 * dt_, qNSi[i], VECT_ALL_ITEMS);
321
322 if (pbc.probleme(i).que_suis_je() == "Probleme_FT_Disc_gen")
323 {
326 const Transport_Interfaces_FT_Disc& equ_int_const = equ_int;
327 equ_int.calculer_vitesse_transport_interpolee(inconnues[i].valeur(),
328 equ_int_const.maillage_interface(),
329 qIi,
330 1);
332 }
333 }
334
335 //ss pas de temps 2
336 //mise a jour des conditions aux limites
337 for(i=0; i<n_pb; i++)
338 {
339 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
341 const int nb_eqn=pb.nombre_d_equations();
342 for(int j=0; j<nb_eqn; j++)
343 {
344 Equation_base& eqn = pb.equation(j);
346 }
347 }
348 temps_courant_ += dt_*5./12.;
349
350 dt_temp=dt_;
351 dt_=0.;
352 for(i=0; i<n_pb; i++)
353 {
354 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
356 }
357 dt_=dt_temp;
358
359 for(i=0; i<n_pb; i++)
360 {
361 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
362 pb.equation(0).derivee_en_temps_inco(qNSj[i]);
363 qNSj[i].ajoute_sans_ech_esp_virt(a2, qNSi[i]);
364 inconnues[i]->futur() = inconnues[i]->valeurs();
365 inconnues[i]->futur().ajoute(b2 * dt_, qNSj[i], VECT_ALL_ITEMS);
366 if (pbc.probleme(i).que_suis_je() == "Probleme_FT_Disc_gen")
367 {
370 const Transport_Interfaces_FT_Disc& equ_int_const = equ_int;
371 equ_int.calculer_vitesse_transport_interpolee(inconnues[i].valeur(),
372 equ_int_const.maillage_interface(),
373 qIj,
374 1);
375 qIi *= -1.*a2;
376 qIj -= qIi;
378 }
379 }
380
381 //ss pas de temps 3
382 //mise a jour des conditions aux limites
383 for(i=0; i<n_pb; i++)
384 {
385 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
387 const int nb_eqn=pb.nombre_d_equations();
388 for(int j=0; j<nb_eqn; j++)
389 {
390 Equation_base& eqn = pb.equation(j);
392 }
393 }
394 temps_courant_ += dt_*1./4.;
395
396 dt_temp=dt_;
397 dt_=0.;
398 for(i=0; i<n_pb; i++)
399 {
400 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
402 }
403 dt_=dt_temp;
404
405 for(i=0; i<n_pb; i++)
406 {
407 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
408 pb.equation(0).derivee_en_temps_inco(qNSi[i]);
409 qNSi[i].ajoute_sans_ech_esp_virt(a3, qNSj[i], VECT_ALL_ITEMS);
410 inconnues[i]->futur() = inconnues[i]->valeurs();
411 inconnues[i]->futur().ajoute_sans_ech_esp_virt(b3 * dt_, qNSi[i], VECT_ALL_ITEMS);
412 if (pbc.probleme(i).que_suis_je() == "Probleme_FT_Disc_gen")
413 {
416 const Transport_Interfaces_FT_Disc& equ_int_const = equ_int;
417 equ_int.calculer_vitesse_transport_interpolee(inconnues[i].valeur(),
418 equ_int_const.maillage_interface(),
419 qIi,
420 1);
421 qIj *= -1.*a3;
422 qIi = 0.;
424 }
425 }
426
427 //fin du pas de temps
428 for(i=0; i<n_pb; i++)
429 {
430 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
431
432 if ( pb.que_suis_je() == "Probleme_FT_Disc_gen")
433 {
434 // pour ne pas deplacer les interfaces:
435 inconnues[i]->valeurs() = 0;
436 // on tourne la roue juste apres donc on s'en fout de perdre les valeurs.
438 }
440 // On applique le RK3 sur les equations restantes:
441 int premiere_equation;
442 if (pb.que_suis_je() == "Probleme_FT_Disc_gen")
443 premiere_equation=2;
444 else
445 premiere_equation=1;
446 for(i=premiere_equation; i<pb.nombre_d_equations(); i++)
448 }
449 temps_courant_=save_temps_courant;
450 delete[] inconnues;
451
452 return 1;
453}
454
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:51
int faire_un_pas_de_temps_eqn_base(Equation_base &) override
Definition RK3_FT.cpp:29
int faire_un_pas_de_temps_pb_couple(Probleme_Couple &)
Definition RK3_FT.cpp:243
: 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