20 "\n\tExplicit solver: \n\t"
21 " RK : 1 - Forward Euler, 2 - RK2(0.5), 3 - RK3 SSP, 4 - RK4, 6 - RK6,\n\t"
22 " AB : 11 - AB1, 12 - AB2, 13 - AB3, 14 - AB4, 15 - AB5\n";
25 "\n\tImplicit solver: \n\t"
26 " (L-Stab): 21 - Backward Euler, 22 - SDIRK23(2), 23 - SDIRK33,\n\t"
27 " (A-Stab): 32 - Implicit Midpoint, 33 - SDIRK23, 34 - SDIRK34,\n\t"
28 " GA : 40 -- 50 - Generalized-alpha,\n\t"
29 " AM : 51 - AM1, 52 - AM2, 53 - AM3, 54 - AM4\n";
36 if (ode_solver_type < 20)
48 using ode_ptr = std::unique_ptr<ODESolver>;
49 switch (ode_solver_type)
53 case 2:
return ode_ptr(
new RK2Solver(0.5));
66 MFEM_ABORT(
"Unknown ODE solver type: " << ode_solver_type);
72 using ode_ptr = std::unique_ptr<ODESolver>;
73 switch (ode_solver_type)
105 MFEM_ABORT(
"Unknown ODE solver type: " << ode_solver_type );
113 for (
int i = 0; i < smax; i++)
115 idx[i] = smax - i - 1;
116 data[i].SetSize(vsize, mem_type);
124 MFEM_ASSERT_INDEX_IN_RANGE(i,0,ss);
130 MFEM_ASSERT_INDEX_IN_RANGE(i,0,ss);
136 MFEM_ASSERT_INDEX_IN_RANGE(i,0,ss);
142 MFEM_ASSERT_INDEX_IN_RANGE(i,0,smax);
143 data[idx[i]] = state;
149 data[idx[0]] = state;
155 os << ss <<
"/" <<smax<<std::endl;
157 for (
int i = 0; i < ss; i++) { data[idx[i]].Print(os); }
201 add(x, (1. -
b)*dt, dxdt, x1);
206 add(x1,
b*dt, dxdt, x);
232 add(3./4, x, 1./4, y, y);
238 add(1./3, x, 2./3, y, x);
296 for (
int i = 0; i < s; i++)
314 for (
int l = 0, i = 1; i < s; i++)
316 add(x, a[l++]*dt, k[0], y);
317 for (
int j = 1; j < i; j++)
319 y.
Add(a[l++]*dt, k[j]);
325 for (
int i = 0; i < s; i++)
327 x.
Add(b[i]*dt, k[i]);
337const real_t RK6Solver::a[] =
340 .1923996296296296296296296296296296296296e-1,
341 .7669337037037037037037037037037037037037e-1,
345 1.318683415233148260919747276431735612861,
347 -5.042058063628562225427761634715637693344,
348 4.220674648395413964508014358283902080483,
349 -41.87259166432751461803757780644346812905,
351 159.4325621631374917700365669070346830453,
352 -122.1192135650100309202516203389242140663,
353 5.531743066200053768252631238332999150076,
354 -54.43015693531650433250642051294142461271,
356 207.0672513650184644273657173866509835987,
357 -158.6108137845899991828742424365058599469,
358 6.991816585950242321992597280791793907096,
359 -.1859723106220323397765171799549294623692e-1,
360 -54.66374178728197680241215648050386959351,
362 207.9528062553893734515824816699834244238,
363 -159.2889574744995071508959805871426654216,
364 7.018743740796944434698170760964252490817,
365 -.1833878590504572306472782005141738268361e-1,
366 -.5119484997882099077875432497245168395840e-3
368const real_t RK6Solver::b[] =
370 .3438957868357036009278820124728322386520e-1,
373 .2582624555633503404659558098586120858767,
374 .4209371189673537150642551514069801967032,
375 4.405396469669310170148836816197095664891,
376 -176.4831190242986576151740942499002125029,
377 172.3641334014150730294022582711902413315
379const real_t RK6Solver::c[] =
382 .9593333333333333333333333333333333333333e-1,
390const real_t RK8Solver::a[] =
398 .3613975628004575124052940721184028345129,
400 -1.341524066700492771819987788202715834917,
401 1.370126503900035259414693716084313000404,
402 .490472027972027972027972027972027972028e-1,
405 .2350972042214404739862988335493427143122,
406 .180855592981356728810903963653454488485,
407 .6169289044289044289044289044289044289044e-1,
410 .1123656831464027662262557035130015442303,
411 -.3885046071451366767049048108111244567456e-1,
412 .1979188712522045855379188712522045855379e-1,
413 -1.767630240222326875735597119572145586714,
417 -6.061889377376669100821361459659331999758,
418 5.650823198222763138561298030600840174201,
419 65.62169641937623283799566054863063741227,
420 -1.180945066554970799825116282628297957882,
423 -41.50473441114320841606641502701994225874,
424 -4.434438319103725011225169229846100211776,
425 4.260408188586133024812193710744693240761,
426 43.75364022446171584987676829438379303004,
427 .787142548991231068744647504422630755086e-2,
428 -1.281405999441488405459510291182054246266,
431 -45.04713996013986630220754257136007322267,
432 -4.731362069449576477311464265491282810943,
433 4.514967016593807841185851584597240996214,
434 47.44909557172985134869022392235929015114,
435 .1059228297111661135687393955516542875228e-1,
436 -.5746842263844616254432318478286296232021e-2,
437 -1.724470134262485191756709817484481861731,
440 -60.92349008483054016518434619253765246063,
441 -5.95151837622239245520283276706185486829,
442 5.556523730698456235979791650843592496839,
443 63.98301198033305336837536378635995939281,
444 .1464202825041496159275921391759452676003e-1,
445 .6460408772358203603621865144977650714892e-1,
446 -.7930323169008878984024452548693373291447e-1,
447 -3.301622667747079016353994789790983625569,
450 -118.011272359752508566692330395789886851,
451 -10.14142238845611248642783916034510897595,
452 9.139311332232057923544012273556827000619,
453 123.3759428284042683684847180986501894364,
454 4.623244378874580474839807625067630924792,
455 -3.383277738068201923652550971536811240814,
456 4.527592100324618189451265339351129035325,
457 -5.828495485811622963193088019162985703755
459const real_t RK8Solver::b[] =
461 .4427989419007951074716746668098518862111e-1,
466 .3541049391724448744815552028733568354121,
467 .2479692154956437828667629415370663023884,
468 -15.69420203883808405099207034271191213468,
469 25.08406496555856261343930031237186278518,
470 -31.73836778626027646833156112007297739997,
471 22.93828327398878395231483560344797018313,
472 -.2361324633071542145259900641263517600737
474const real_t RK8Solver::c[] =
483 .901802041735856958259707940678372149956,
491 stages(s_), state(s_)
508 if (state.
Size() >= stages -1)
511 f->
Mult(x, state[0]);
513 for (
int i = 0; i < stages; i++)
515 x.
Add(a[i]*dt, state[i]);
536 else if (fabs(dt-dt_) >10*std::numeric_limits<real_t>::epsilon())
544 mfem::out <<
" - Time step changed" << std::endl;
545 mfem::out <<
" - Purging time stepping history" << std::endl;
546 mfem::out <<
" - Will run Runge-Kutta to rebuild history" << std::endl;
551const real_t AB1Solver::a[] =
553const real_t AB2Solver::a[] =
555const real_t AB3Solver::a[] =
556{23.0/12.0,-4.0/3.0, 5.0/12.0};
557const real_t AB4Solver::a[] =
558{55.0/24.0,-59.0/24.0, 37.0/24.0,-9.0/24.0};
559const real_t AB5Solver::a[] =
560{1901.0/720.0,-2774.0/720.0, 2616.0/720.0,-1274.0/720.0, 251.0/720.0};
564 stages(s_), state(s_)
583 else if (fabs(dt-dt_) > 10*std::numeric_limits<real_t>::epsilon())
591 mfem::out <<
" - Time step changed" << std::endl;
592 mfem::out <<
" - Purging time stepping history" << std::endl;
593 mfem::out <<
" - Will run Runge-Kutta to rebuild history" << std::endl;
597 if ((state.
Size() == 0)&&(stages>1))
603 if (state.
Size() >= stages )
606 for (
int i = 0; i < stages; i++)
608 x.
Add(a[i+1]*dt, state[i]);
612 x.
Add(a[0]*dt, state[0]);
624const real_t AM1Solver::a[] =
626const real_t AM2Solver::a[] =
627{5.0/12.0, 2.0/3.0, -1.0/12.0};
628const real_t AM3Solver::a[] =
629{3.0/8.0, 19.0/24.0,-5.0/24.0, 1.0/24.0};
630const real_t AM4Solver::a[] =
631{251.0/720.0,646.0/720.0,-264.0/720.0, 106.0/720.0, -19.0/720.0};
668 gamma = (3. - sqrt(3.))/6.;
670 else if (gamma_opt == 2)
672 gamma = (2. - sqrt(2.))/2.;
674 else if (gamma_opt == 3)
676 gamma = (2. + sqrt(2.))/2.;
680 gamma = (3. + sqrt(3.))/6.;
727 const real_t a = 1./sqrt(3.)*cos(M_PI/18.) + 0.5;
728 const real_t b = 1./(6.*(2.*
a-1.)*(2.*
a-1.));
739 x.
Add((1.-2.*
b)*dt,
k);
762 const real_t a = 0.435866521508458999416019;
763 const real_t b = 1.20849664917601007033648;
764 const real_t c = 0.717933260754229499708010;
796 add(x, dt/2.0,
k,
y);
820 const real_t a = (2.0 - sqrt(2.0)) / 2.0;
821 const real_t b = (1.0 - 2.0*
a) / (4.0*
a);
855 const real_t a = (3.0 + sqrt(3.0)) / 6.0;
856 const real_t b = (1.0 - 2.0*
a) / (4.0*
a);
857 const real_t b_2 = 1.0 / ( 12.0*
a*(1.0 - 2.0*
a) );
858 const real_t b_3 = (1.0 - 3.0*
a) / ( 3.0*(1.0 - 2.0*
a) );
864 x.
Add((1.0-b_2-b_3)*dt,
k);
887 rho_inf = (rho_inf > 1.0) ? 1.0 : rho_inf;
888 rho_inf = (rho_inf < 0.0) ? 0.0 : rho_inf;
891 alpha_m = 0.5*(3.0 - rho_inf)/(1.0 + rho_inf);
898 os <<
"Generalized alpha time integrator:" << std::endl;
899 os <<
"alpha_m = " <<
alpha_m << std::endl;
900 os <<
"alpha_f = " <<
alpha_f << std::endl;
901 os <<
"gamma = " <<
gamma << std::endl;
905 os<<
"Second order"<<
" and ";
909 os<<
"First order"<<
" and ";
914 os<<
"Stable"<<std::endl;
918 os<<
"Unstable"<<std::endl;
925 if (state.
Size() == 0)
943 state[0] *= (1.0-(1.0/
alpha_m));
1015 a_[0] = (2.0+pow(2.0,1.0/3.0)+pow(2.0,-1.0/3.0))/6.0;
1016 a_[1] = (1.0-pow(2.0,1.0/3.0)-pow(2.0,-1.0/3.0))/6.0;
1020 b_[1] = 1.0/(2.0-pow(2.0,1.0/3.0));
1021 b_[2] = 1.0/(1.0-pow(2.0,2.0/3.0));
1025 MFEM_ASSERT(
false,
"Unsupported order in SIAVSolver");
1032 for (
int i=0; i<order_; i++)
1045 p.Add(b_[i] * dt,
dp_);
1057 " [0--10] - GeneralizedAlpha(0.1 * s),\n\t"
1058 " 11 - Average Acceleration, 12 - Linear Acceleration\n\t"
1059 " 13 - CentralDifference, 14 - FoxGoodwin";
1064 switch (ode_solver_type)
1085 MFEM_ABORT(
"Unknown ODE solver type: " << ode_solver_type);
1108 x.
Add(0.5*dt, dxdt);
1113 x.
Add(0.5*dt, dxdt);
1128 os <<
"Newmark time integrator:" << std::endl;
1129 os <<
"beta = " << beta << std::endl;
1130 os <<
"gamma = " << gamma << std::endl;
1134 os<<
"Second order"<<
" and ";
1138 os<<
"First order"<<
" and ";
1141 if ((gamma >= 0.5) && (beta >= (gamma + 0.5)*(gamma + 0.5)/4))
1143 os<<
"A-Stable"<<std::endl;
1145 else if ((gamma >= 0.5) && (beta >= 0.5*gamma))
1147 os<<
"Conditionally stable"<<std::endl;
1151 os<<
"Unstable"<<std::endl;
1158 real_t fac0 = 0.5 - beta;
1159 real_t fac2 = 1.0 - gamma;
1201 os <<
"Generalized alpha time integrator:" << std::endl;
1202 os <<
"alpha_m = " <<
alpha_m << std::endl;
1203 os <<
"alpha_f = " <<
alpha_f << std::endl;
1204 os <<
"beta = " <<
beta << std::endl;
1205 os <<
"gamma = " <<
gamma << std::endl;
1209 os<<
"Second order"<<
" and ";
1213 os<<
"First order"<<
" and ";
1220 os<<
"Stable"<<std::endl;
1224 os<<
"Unstable"<<std::endl;
1268 x *= 1.0 - 1.0/fac1;
1269 x.
Add (1.0/fac1,
xa);
1271 dxdt *= 1.0 - 1.0/fac1;
1272 dxdt.
Add (1.0/fac1,
va);
1274 state[0] *= 1.0 - 1.0/fac5;
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void CheckTimestep(real_t dt)
AdamsBashforthSolver(int s_, const real_t *a_)
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
std::unique_ptr< ODESolver > RKsolver
std::unique_ptr< ODESolver > RKsolver
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
AdamsMoultonSolver(int s_, const real_t *a_)
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void Print(std::ostream &out=mfem::out, int width=4) const
Prints array to stream with width elements per row.
The classical midpoint method.
Backward Euler ODE solver. L-stable.
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
virtual ~ExplicitRKSolver()
ExplicitRKSolver(int s_, const real_t *a_, const real_t *b_, const real_t *c_)
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
The classical forward Euler method.
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void PrintProperties(std::ostream &os=mfem::out)
void Init(SecondOrderTimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void Step(Vector &x, Vector &dxdt, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void SetRhoInf(real_t rho_inf)
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
void PrintProperties(std::ostream &os=mfem::out)
Implicit midpoint method. A-stable, not L-stable.
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void Step(Vector &x, Vector &dxdt, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
void PrintProperties(std::ostream &os=mfem::out)
TimeDependentOperator * f
Pointer to the associated TimeDependentOperator.
virtual void Init(TimeDependentOperator &f_)
Associate a TimeDependentOperator with the ODE solver.
static MFEM_EXPORT std::unique_ptr< ODESolver > SelectImplicit(const int ode_solver_type)
static MFEM_EXPORT std::string Types
static MFEM_EXPORT std::unique_ptr< ODESolver > Select(const int ode_solver_type)
static MFEM_EXPORT std::string ImplicitTypes
static MFEM_EXPORT std::string ExplicitTypes
static MFEM_EXPORT std::unique_ptr< ODESolver > SelectExplicit(const int ode_solver_type)
void Increment()
Increment the stage counter.
const Vector & Get(int i) const override
Get the ith state vector.
void Set(int i, Vector &state) override
Set the ith state vector.
void SetSize(int vsize, MemoryType mem_type)
Set the number of stages and the size of the vectors.
void Append(Vector &state) override
Add state vector and increment state size.
void ShiftStages()
Shift the stage counter for the next timestep.
void Print(std::ostream &os=mfem::out) const
Print state data.
int Size() const override
Get the current number of stored stages.
void Reset()
Reset the stage counter.
virtual MemoryClass GetMemoryClass() const
Return the MemoryClass preferred by the Operator.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Third-order, strong stability preserving (SSP) Runge-Kutta method.
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
The classical explicit forth-order Runge-Kutta method, RK4.
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
SDIRK23Solver(int gamma_opt=1)
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void Step(Vector &q, Vector &p, real_t &t, real_t &dt) override
void Step(Vector &q, Vector &p, real_t &t, real_t &dt) override
TimeDependentOperator * F_
virtual void Init(Operator &P, TimeDependentOperator &F)
void Step(Vector &q, Vector &p, real_t &t, real_t &dt) override
Abstract class for solving systems of ODEs: d2x/dt2 = f(x,dx/dt,t)
SecondOrderTimeDependentOperator * f
Pointer to the associated TimeDependentOperator.
void MidPointStep(Vector &x, Vector &dxdt, real_t &t, real_t &dt)
static MFEM_EXPORT std::string Types
Help info for SecondOrderODESolver options.
void EulerStep(Vector &x, Vector &dxdt, real_t &t, real_t &dt)
static MFEM_EXPORT SecondOrderODESolver * Select(const int ode_solver_type)
Function selecting the desired SecondOrderODESolver.
virtual void Init(SecondOrderTimeDependentOperator &f)
Associate a TimeDependentOperator with the ODE solver.
Base abstract class for second order time dependent operators.
virtual void Mult(const Vector &x, const Vector &dxdt, Vector &y) const
Perform the action of the operator: y = k = f(x,@ dxdt, t), where k solves the algebraic equation F(x...
virtual void ImplicitSolve(const real_t fac0, const real_t fac1, const Vector &x, const Vector &dxdt, Vector &k)
Solve the equation: k = f(x + fac0 k, dxdt + fac1 k, t), for the unknown k at the current time t.
Base abstract class for first order time dependent operators.
bool isExplicit() const
True if type is EXPLICIT.
virtual void ImplicitSolve(const real_t gamma, const Vector &u, Vector &k)
Solve for the unknown k, at the current time t, the following equation: F(u + gamma k,...
void Mult(const Vector &u, Vector &k) const override
Perform the action of the operator (u,t) -> k(u,t) where t is the current time set by SetTime() and k...
virtual void SetTime(const real_t t_)
Set the current time.
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
void SetSize(int s)
Resize the vector to size s.
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
void add(const Vector &v1, const Vector &v2, Vector &v)
MemoryType GetMemoryType(MemoryClass mc)
Return a suitable MemoryType for a given MemoryClass.
MemoryType
Memory types supported by MFEM.
real_t p(const Vector &x, real_t t)