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 
19 namespace TimeIntegration {
20 
23  // and which derive from SIMbase.
24  template<class Solver>
25 class SIMExplicitRKE : public SIMExplicitRK<Solver>
26 {
27 public:
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.push_back(1.0);
38  this->RK.b.push_back(0.0);
39  bs.push_back(0.5);
40  bs.push_back(0.5);
41  this->RK.c.push_back(0.0);
42  this->RK.c.push_back(1.0);
43  this->RK.A.resize(2,2);
44  this->RK.A(2,1) = 1.0;
45  }
46  else if (type == BOGACKISHAMPINE) {
47  this->RK.order = 2;
48  this->RK.b.push_back(7.0/24.0);
49  this->RK.b.push_back(1.0/4.0);
50  this->RK.b.push_back(1.0/3.0);
51  this->RK.b.push_back(1.0/8.0);
52  bs.push_back(2.0/9.0);
53  bs.push_back(1.0/3.0);
54  bs.push_back(4.0/9.0);
55  bs.push_back(0.0);
56  this->RK.c.push_back(0.0);
57  this->RK.c.push_back(0.5);
58  this->RK.c.push_back(0.75);
59  this->RK.c.push_back(1.0);
60  this->RK.A.resize(4,4);
61  this->RK.A(2,1) = 0.5;
62  this->RK.A(3,2) = 0.75;
63  this->RK.A(4,1) = 2.0/9.0;
64  this->RK.A(4,2) = 1.0/3.0;
65  this->RK.A(4,3) = 4.0/9.0;
66  }
67  else if (type == FEHLBERG) {
68  this->RK.order = 4;
69  this->RK.b.push_back(25.0/216.0);
70  this->RK.b.push_back(0.0);
71  this->RK.b.push_back(1408.0/2565.0);
72  this->RK.b.push_back(2197.0/4104.0);
73  this->RK.b.push_back(-1.0/5.0);
74  this->RK.b.push_back(0.0);
75  bs.push_back(16.0/135);
76  bs.push_back(0.0);
77  bs.push_back(6656.0/12825.0);
78  bs.push_back(28561.0/56430.0);
79  bs.push_back(-9.0/50.0);
80  bs.push_back(2.0/55.0);
81  this->RK.c.push_back(0.0);
82  this->RK.c.push_back(1.0/4.0);
83  this->RK.c.push_back(3.0/8.0);
84  this->RK.c.push_back(12.0/13.0);
85  this->RK.c.push_back(1.0);
86  this->RK.c.push_back(1.0/2.0);
87  this->RK.A.resize(6,6);
88  this->RK.A(2,1) = 0.25;
89  this->RK.A(3,1) = 3.0/32.0;
90  this->RK.A(3,2) = 9.0/32.0;
91  this->RK.A(4,1) = 1932.0/2197.0;
92  this->RK.A(4,2) = -7200.0/2197.0;
93  this->RK.A(4,3) = 7296.0/2197.0;
94  this->RK.A(5,1) = 439.0/216.0;
95  this->RK.A(5,2) = -8.0;
96  this->RK.A(5,3) = 3680.0/513.0;
97  this->RK.A(5,4) = -845.0/4104.0;
98  this->RK.A(6,1) = -8.0/27;
99  this->RK.A(6,2) = 2.0;
100  this->RK.A(6,3) = -3544.0/2565.0;
101  this->RK.A(6,4) = 1859.0/4104.0;
102  this->RK.A(6,5) = -11.0/40.0;
103  }
104  }
105 
107  virtual bool solveStep(TimeStep& tp)
108  {
109  this->solver.getProcessAdm().cout <<"\n step = "<< tp.step <<" time = "<< tp.time.t << std::endl;
110 
111  Vectors stages;
112  Vector prevSol = this->solver.getSolution();
113  bool ok = this->solveRK(stages, tp);
114  double prevEst = 1.0;
115  while (ok && prevEst > errTol) {
116  Vector error(prevSol);
117  // construct the error estimate
118  for (size_t i=0;i<stages.size();++i)
119  error.add(stages[i], tp.time.dt*bs[i]);
120  this->solver.applyDirichlet(error);
121  error -= this->solver.getSolution();
122 
123  const size_t nf = this->solver.getNoFields(1);
124  std::vector<size_t> iMax(nf);
125  std::vector<double> dMax(nf);
126  prevEst = this->solver.solutionNorms(error, dMax.data(), iMax.data(), nf);
127  this->solver.getProcessAdm().cout << "Error estimate: " << prevEst << std::endl;
128  if (prevEst > errTol) {
129  if (!tp.cutback())
130  return false;
131  this->solver.getSolution() = prevSol;
132  ok = this->solveRK(stages, tp);
133  }
134  }
135 
136  if (ok && prevEst > 0.0) {
137  tp.time.dt = tp.time.dt * pow(errTol/prevEst,1.0/(this->RK.order+1));
138  this->solver.getProcessAdm().cout << "adjusting step size to " << tp.time.dt << std::endl;
139  }
140 
141  return ok;
142  }
143 
144 private:
146  double errTol;
147 };
148 
149 }
150 
151 #endif
std::vector< Real > RealArray
A real-valued array without algebraic operations.
Definition: ImmersedBoundaries.h:29
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
RealArray bs
Runge-Kutta coefficients for embedded method.
Definition: SIMExplicitRKE.h:145
SIMExplicitRKE(Solver &solv, Method type, double tol)
Constructor.
Definition: SIMExplicitRKE.h:32
double errTol
Truncation error tolerance.
Definition: SIMExplicitRKE.h:146
virtual bool solveStep(TimeStep &tp)
Computes the solution for the current time step.
Definition: SIMExplicitRKE.h:107
Explicit Runge-Kutta based time stepping for SIM classes.
Definition: SIMExplicitRK.h:30
RKTableaux RK
Tableaux of Runge-Kutta coefficients.
Definition: SIMExplicitRK.h:186
Solver & solver
Reference to simulator.
Definition: SIMExplicitRK.h:185
bool solveRK(Vectors &stages, const TimeStep &tp)
Applies the Runge-Kutta scheme.
Definition: SIMExplicitRK.h:104
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