IFEM  90A354
SIMExplicitRK.h
Go to the documentation of this file.
1 //==============================================================================
11 //==============================================================================
12 
13 #ifndef SIM_EXPLICIT_RK_H_
14 #define SIM_EXPLICIT_RK_H_
15 
16 #include "SIMenums.h"
17 #include "TimeIntUtils.h"
18 #include "TimeStep.h"
19 
20 class DataExporter;
21 
22 
23 namespace TimeIntegration {
24 
28 template<class Solver>
30 {
31 public:
36  SIMExplicitRK(Solver& solv, Method type, bool standalone = true) :
37  solver(solv), alone(standalone)
38  {
39  if (type == EULER) {
40  RK.order = 1;
41  RK.b.push_back(1.0);
42  RK.c.push_back(0.0);
43  RK.A.resize(1,1);
44  }
45  else if (type == HEUN) {
46  RK.order = 2;
47  RK.b.push_back(0.5);
48  RK.b.push_back(0.5);
49  RK.c.push_back(0.0);
50  RK.c.push_back(1.0);
51  RK.A.resize(2,2);
52  RK.A(2,1) = 1.0;
53  }
54  else if (type == RK3) {
55  RK.order = 3;
56  RK.b.push_back(1.0/6.0);
57  RK.b.push_back(2.0/3.0);
58  RK.b.push_back(1.0/6.0);
59  RK.c.push_back(0.0);
60  RK.c.push_back(0.5);
61  RK.c.push_back(1.0);
62  RK.A.resize(3,3);
63  RK.A(2,1) = 0.5;
64  RK.A(3,1) = -1.0;
65  RK.A(3,2) = 2.0;
66  }
67  else if (type == RK4) {
68  RK.order = 4;
69  RK.b.push_back(1.0/6.0);
70  RK.b.push_back(1.0/3.0);
71  RK.b.push_back(1.0/3.0);
72  RK.b.push_back(1.0/6.0);
73  RK.c.push_back(0.0);
74  RK.c.push_back(0.5);
75  RK.c.push_back(0.5);
76  RK.c.push_back(1.0);
77  RK.A.resize(4,4);
78  RK.A(2,1) = 0.5;
79  RK.A(3,2) = 0.5;
80  RK.A(4,3) = 1.0;
81  }
82  else
83  RK.order = 0;
84 
85  Solver::msgLevel = 1; // prints primary solution summary only
86  }
87 
89  const ProcessAdm& getProcessAdm() const { return solver.getProcessAdm(); }
90 
92  virtual bool solveStep(TimeStep& tp)
93  {
94  if (alone)
95  solver.getProcessAdm().cout <<"\n step = "<< tp.step <<" time = "<< tp.time.t << std::endl;
96 
97  Vectors stages;
98  return this->solveRK(stages, tp);
99  }
100 
104  bool solveRK(Vectors& stages, const TimeStep& tp)
105  {
106  TimeDomain time(tp.time);
107  Vector dum;
108 
109  stages.resize(RK.b.size());
110 
111  for (size_t i=0;i<stages.size();++i) {
112  Vector tmp(solver.getSolution());
113  for (size_t j=0;j<i;++j)
114  tmp.add(stages[j], tp.time.dt*RK.A(i+1,j+1));
115  time.t = tp.time.t+tp.time.dt*(RK.c[i]-1.0);
116  solver.updateDirichlet(time.t, &dum);
117  solver.applyDirichlet(tmp);
118  if (!solver.assembleSystem(time, Vectors(1, tmp),
119  !linear || (tp.step == 1 && i == 0)))
120  return false;
121 
122  // solve Mu = Au + f
123  if (!solver.solveSystem(stages[i]))
124  return false;
125 
126  if (linear)
127  solver.setMode(SIM::RHS_ONLY);
128  }
129 
130  // finally construct solution as weighted stages
131  solver.updateDirichlet(tp.time.t, &dum);
132  for (size_t i=0;i<RK.b.size();++i)
133  solver.getSolution().add(stages[i], tp.time.dt*RK.b[i]);
134  solver.applyDirichlet(solver.getSolution());
135 
136  if (alone)
137  solver.printSolutionSummary(solver.getSolution(), 0,
138  solver.getProblem()->getField1Name(1).c_str());
139 
140  return true;
141  }
142 
145  {
146  return solver.advanceStep(tp);
147  }
148 
150  bool saveModel(char* fileName, int& geoBlk, int& nBlock)
151  {
152  return solver.saveModel(fileName, geoBlk, nBlock);
153  }
154 
156  bool saveStep(const TimeStep& tp, int& nBlock)
157  {
158  return solver.saveStep(tp, nBlock);
159  }
160 
162  void registerFields(DataExporter& exporter)
163  {
164  solver.registerFields(exporter);
165  }
166 
169  bool serialize(std::map<std::string,std::string>& data)
170  {
171  return solver.serialize(data);
172  }
173 
176  bool deSerialize(const std::map<std::string,std::string>& data)
177  {
178  return solver.deSerialize(data);
179  }
180 
182  void setLinear(bool enable) { linear = enable; }
183 
184 protected:
185  Solver& solver;
187  bool alone;
188  bool linear = false;
189 };
190 
191 }
192 
193 #endif
std::vector< Vector > Vectors
An array of real-valued vectors with algebraic operations.
Definition: MatVec.h:37
Various enums for simulation scope.
Various helpers for time integration.
Class for encapsulation of general time stepping parameters.
Administer and write data using DataWriters.
Definition: DataExporter.h:38
Class for administration of MPI processes in IFEM library.
Definition: ProcessAdm.h:33
Explicit Runge-Kutta based time stepping for SIM classes.
Definition: SIMExplicitRK.h:30
void setLinear(bool enable)
Mark operator as linear to avoid repeated assembly and factorization.
Definition: SIMExplicitRK.h:182
RKTableaux RK
Tableaux of Runge-Kutta coefficients.
Definition: SIMExplicitRK.h:186
bool deSerialize(const std::map< std::string, std::string > &data)
Set internal state from a serialized state.
Definition: SIMExplicitRK.h:176
const ProcessAdm & getProcessAdm() const
Returns the parallel process administrator.
Definition: SIMExplicitRK.h:89
virtual bool solveStep(TimeStep &tp)
Computes the solution for the current time step.
Definition: SIMExplicitRK.h:92
bool linear
If true mass matrix is constant.
Definition: SIMExplicitRK.h:188
bool saveStep(const TimeStep &tp, int &nBlock)
Saves the converged results of a given time step to VTF file.
Definition: SIMExplicitRK.h:156
bool serialize(std::map< std::string, std::string > &data)
Serialize internal state for restarting purposes.
Definition: SIMExplicitRK.h:169
SIMExplicitRK(Solver &solv, Method type, bool standalone=true)
Constructor.
Definition: SIMExplicitRK.h:36
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
bool alone
If true, this is a standalone solver.
Definition: SIMExplicitRK.h:187
bool saveModel(char *fileName, int &geoBlk, int &nBlock)
Opens a new VTF-file and writes the model geometry to it.
Definition: SIMExplicitRK.h:150
bool advanceStep(TimeStep &tp)
Advances the time step one step forward.
Definition: SIMExplicitRK.h:144
void registerFields(DataExporter &exporter)
Registers fields for output to a data exporter.
Definition: SIMExplicitRK.h:162
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
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
vector< T > & add(const std::vector< T > &X, const T &alfa=T(1), unsigned int ofsx=0, int stridex=1, unsigned int ofsy=0, int stridey=1)
Add the given vector X scaled by alfa to *this.
Definition: matrix.h:1562
bool resize(size_t n, char forceClear=0)
Resize the vector to length n.
Definition: matrix.h:277
Utilities for time integration.
Definition: BDF.h:21
Method
Enum defining various solution methods.
Definition: TimeIntUtils.h:28
@ HEUN
Heun-Euler, explicit.
Definition: TimeIntUtils.h:33
@ RK3
Kutta's third order method, explicit.
Definition: TimeIntUtils.h:34
@ RK4
Kutta's fourth order method, explicit.
Definition: TimeIntUtils.h:35
@ EULER
Forward Euler, explicit.
Definition: TimeIntUtils.h:32
Struct representing the time domain.
Definition: TimeDomain.h:23
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
Struct holding a Runge-Kutta tableaux.
Definition: TimeIntUtils.h:59
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