IFEM 90A354
SIMExplicitRKE.h
Go to the documentation of this file.
1//==============================================================================
11//==============================================================================
12
13#ifndef SIM_EXPLICIT_RKE_H_
14#define SIM_EXPLICIT_RKE_H_
15
16#include "SIMExplicitRK.h"
17
18
19namespace TimeIntegration {
20
24template<class Solver>
25class SIMExplicitRKE : public SIMExplicitRK<Solver>
26{
27public:
32 SIMExplicitRKE(Solver& solv, Method type, double tol) :
33 SIMExplicitRK<Solver>(solv, NONE), errTol(tol)
34 {
35 if (type == HEUNEULER) {
36 this->RK.order = 1;
37 this->RK.b = {1.0, 0.0};
38 bs = {0.5, 0.5};
39 this->RK.c = {0.0, 1.0};
40 this->RK.A.resize(2,2);
41 this->RK.A(2,1) = 1.0;
42 }
43 else if (type == BOGACKISHAMPINE) {
44 this->RK.order = 2;
45 this->RK.b = {7.0/24.0, 1.0/4.0, 1.0/3.0, 1.0/8.0};
46 bs = {2.0/9.0, 1.0/3.0, 4.0/9.0, 0.0};
47 this->RK.c = {0.0, 0.5, 0.75, 1.0};
48 this->RK.A.resize(4,4);
49 this->RK.A(2,1) = 0.5;
50 this->RK.A(3,2) = 0.75;
51 this->RK.A(4,1) = 2.0/9.0;
52 this->RK.A(4,2) = 1.0/3.0;
53 this->RK.A(4,3) = 4.0/9.0;
54 }
55 else if (type == FEHLBERG) {
56 this->RK.order = 4;
57 this->RK.b = {25.0/216.0, 0.0, 1408.0/2565.0, 2197.0/4104.0, -1.0/5.0, 0.0};
58 bs = {16.0/135.0, 0.0, 6656.0/12825.0, 28561.0/56430.0, -9.0/50.0, 2.0/55.0};
59 this->RK.c = {0.0, 1.0/4.0, 3.0/8.0, 12.0/13.0, 1.0, 1.0/2.0};
60 this->RK.A.resize(6,6);
61 this->RK.A(2,1) = 0.25;
62 this->RK.A(3,1) = 3.0/32.0;
63 this->RK.A(3,2) = 9.0/32.0;
64 this->RK.A(4,1) = 1932.0/2197.0;
65 this->RK.A(4,2) = -7200.0/2197.0;
66 this->RK.A(4,3) = 7296.0/2197.0;
67 this->RK.A(5,1) = 439.0/216.0;
68 this->RK.A(5,2) = -8.0;
69 this->RK.A(5,3) = 3680.0/513.0;
70 this->RK.A(5,4) = -845.0/4104.0;
71 this->RK.A(6,1) = -8.0/27;
72 this->RK.A(6,2) = 2.0;
73 this->RK.A(6,3) = -3544.0/2565.0;
74 this->RK.A(6,4) = 1859.0/4104.0;
75 this->RK.A(6,5) = -11.0/40.0;
76 }
77 }
78
80 bool solveStep(TimeStep& tp) override
81 {
82 this->solver.getProcessAdm().cout <<"\n step = "<< tp.step <<" time = "<< tp.time.t << std::endl;
83
84 Vectors stages;
85 Vector prevSol = this->solver.getSolution();
86 this->solver.setMode(this->assemble ? SIM::DYNAMIC: SIM::RHS_ONLY);
87 if (!this->solver.initDirichlet(tp.time.t))
88 return false;
89 bool ok = this->solveRK(stages, tp);
90 double prevEst = 1.0;
91 while (ok && prevEst > errTol) {
92 Vector error(prevSol);
93 // construct the error estimate
94 for (size_t i=0;i<stages.size();++i)
95 error.add(stages[i], tp.time.dt*bs[i]);
96 this->solver.applyDirichlet(error);
97 error -= this->solver.getSolution();
98
99 const size_t nf = this->solver.getNoFields(1);
100 std::vector<size_t> iMax(nf);
101 std::vector<double> dMax(nf);
102 prevEst = this->solver.solutionNorms(error, dMax.data(), iMax.data(), nf);
103 this->solver.getProcessAdm().cout << "Error estimate: " << prevEst << std::endl;
104 if (prevEst > errTol) {
105 if (!tp.cutback())
106 return false;
107 this->solver.getSolution() = prevSol;
108 this->solver.setMode(this->assemble ? SIM::DYNAMIC: SIM::RHS_ONLY);
109 if (!this->solver.initDirichlet(tp.time.t))
110 return false;
111 ok = this->solveRK(stages, tp);
112 }
113 }
114
115 if (ok && prevEst > 0.0) {
116 tp.time.dt = tp.time.dt * pow(errTol/prevEst,1.0/(this->RK.order+1));
117 this->solver.getProcessAdm().cout << "adjusting step size to " << tp.time.dt << std::endl;
118 }
119
120 return ok;
121 }
122
123private:
125 double errTol;
126};
127
128}
129
130#endif
std::vector< Real > RealArray
A real-valued array without algebraic operations.
Definition ImmersedBoundaries.h:32
std::vector< Vector > Vectors
An array of real-valued vectors with algebraic operations.
Definition MatVec.h:37
Explicit Runge-Kutta based time stepping for SIM classes.
const double * error(int n)
Prints an error message for non-supported quadrature rules.
Definition TriangleQuadrature.C:52
Explicit embedded Runge-Kutta based time stepping for SIM classes.
Definition SIMExplicitRKE.h:26
bool solveStep(TimeStep &tp) override
Computes the solution for the current time step.
Definition SIMExplicitRKE.h:80
RealArray bs
Runge-Kutta coefficients for embedded method.
Definition SIMExplicitRKE.h:124
SIMExplicitRKE(Solver &solv, Method type, double tol)
Constructor.
Definition SIMExplicitRKE.h:32
double errTol
Truncation error tolerance.
Definition SIMExplicitRKE.h:125
Explicit Runge-Kutta based time stepping for SIM classes.
Definition SIMExplicitRK.h:31
RKTableaux RK
Tableaux of Runge-Kutta coefficients.
Definition SIMExplicitRK.h:198
Solver & solver
Reference to simulator.
Definition SIMExplicitRK.h:197
bool solveRK(Vectors &stages, const TimeStep &tp)
Applies the Runge-Kutta scheme.
Definition SIMExplicitRK.h:98
bool assemble
If true, assemble operators.
Definition SIMExplicitRK.h:201
Class for encapsulation of general time stepping parameters.
Definition TimeStep.h:31
int step
Time step counter.
Definition TimeStep.h:72
TimeDomain time
Time domain data.
Definition TimeStep.h:74
bool cutback()
Restarts current increment with a smaller step size on divergence.
Definition TimeStep.C:303
void resize(size_t r, size_t c, bool forceClear=false)
Resize the matrix to dimension .
Definition matrix.h:488
A vector class with some added algebraic operations.
Definition matrix.h:64
Utilities for time integration.
Definition BDF.h:21
Method
Enum defining various solution methods.
Definition TimeIntUtils.h:28
@ BOGACKISHAMPINE
Bogacki-Shampine order 2(3)
Definition TimeIntUtils.h:52
@ NONE
No time integration.
Definition TimeIntUtils.h:29
@ HEUNEULER
Heun-Euler embedded order 1(2)
Definition TimeIntUtils.h:51
@ FEHLBERG
Runge-Kutta-Fehlberg order 4(5)
Definition TimeIntUtils.h:53
double dt
Current timestep (or load parameter) increment.
Definition TimeDomain.h:25
double t
Current time (or pseudo time, load parameter)
Definition TimeDomain.h:24
RealArray c
Stage levels.
Definition TimeIntUtils.h:63
Matrix A
Coefficient matrix.
Definition TimeIntUtils.h:61
int order
Order of scheme.
Definition TimeIntUtils.h:60
RealArray b
Stage weights.
Definition TimeIntUtils.h:62