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 "ProcessAdm.h"
17#include "SIMenums.h"
18#include "TimeIntUtils.h"
19#include "TimeStep.h"
20
21class DataExporter;
22
23
24namespace TimeIntegration {
25
29template<class Solver>
31{
32public:
37 SIMExplicitRK(Solver& solv, Method type, bool standalone = true) :
38 solver(solv), alone(standalone)
39 {
40 if (type == EULER) {
41 RK.order = 1;
42 RK.b = {1.0};
43 RK.c = {0.0};
44 RK.A.resize(1,1);
45 }
46 else if (type == HEUN) {
47 RK.order = 2;
48 RK.b = {0.5, 0.5};
49 RK.c = {0.0, 1.0};
50 RK.A.resize(2,2);
51 RK.A(2,1) = 1.0;
52 }
53 else if (type == RK3) {
54 RK.order = 3;
55 RK.b = {1.0/6.0, 2.0/3.0, 1.0/6.0};
56 RK.c = {0.0, 0.5, 1.0};
57 RK.A.resize(3,3);
58 RK.A(2,1) = 0.5;
59 RK.A(3,1) = -1.0;
60 RK.A(3,2) = 2.0;
61 }
62 else if (type == RK4) {
63 RK.order = 4;
64 RK.b = {1.0/6.0, 1.0/3.0, 1.0/3.0, 1.0/6.0};
65 RK.c = {0.0, 0.5, 0.5, 1.0};
66 RK.A.resize(4,4);
67 RK.A(2,1) = 0.5;
68 RK.A(3,2) = 0.5;
69 RK.A(4,3) = 1.0;
70 }
71 else
72 RK.order = 0;
73
74 Solver::msgLevel = 1; // prints primary solution summary only
75 }
76
78 const ProcessAdm& getProcessAdm() const { return solver.getProcessAdm(); }
79
81 virtual bool solveStep(TimeStep& tp)
82 {
83 if (alone)
84 solver.getProcessAdm().cout <<"\n step = "<< tp.step <<" time = "<< tp.time.t << std::endl;
85
86 solver.setMode(this->assemble ? SIM::DYNAMIC : SIM::RHS_ONLY);
87
88 if (!solver.initDirichlet(tp.time.t))
89 return false;
90
91 Vectors stages;
92 return this->solveRK(stages, tp);
93 }
94
98 bool solveRK(Vectors& stages, const TimeStep& tp)
99 {
100 TimeDomain time(tp.time);
101 Vector dum;
102
103 stages.resize(RK.b.size());
104
105 for (size_t i = 0; i < stages.size(); ++i) {
106 Vector tmp(solver.getSolution());
107 for (size_t j = 0; j < i; ++j)
108 tmp.add(stages[j], tp.time.dt*RK.A(i+1,j+1));
109 time.t = tp.time.t+tp.time.dt*(RK.c[i]-1.0);
110
111 // 1) Update to stage time and impose stage-state boundary values.
112 // Passing an empty vector means absolute Dirichlet values.
113 if (!solver.updateDirichlet(time.t, &dum))
114 return false;
115
116 if (!solver.applyDirichlet(tmp))
117 return false;
118
119 // 2) Constrain stage unknowns to tangent boundary values dg/dt.
120 Vector zeroRef(solver.getSolution().size());
121 if (!solver.updateDirichlet(time.t, &zeroRef, true))
122 return false;
123
124 if (!solver.assembleSystem(time, Vectors(1, tmp),
125 !linear || (tp.step == 1 && i == 0)))
126 return false;
127
128 // solve Mk = Au + f
129 if (!solver.solveSystem(stages[i]))
130 return false;
131
132 if (linear) {
133 solver.setMode(SIM::RHS_ONLY);
134 assemble = false;
135 }
136 }
137
138 // finally construct solution as weighted stages
139 for (size_t i = 0; i < RK.b.size(); ++i)
140 solver.getSolution().add(stages[i], tp.time.dt*RK.b[i]);
141
142 // Enforce absolute boundary values at the new time level.
143 if (!solver.updateDirichlet(tp.time.t, &dum))
144 return false;
145 if (!solver.applyDirichlet(solver.getSolution()))
146 return false;
147
148 if (alone)
149 solver.printSolutionSummary(solver.getSolution(), 0,
150 solver.getProblem()->getField1Name(1).c_str());
151
152 return true;
153 }
154
157 {
158 return solver.advanceStep(tp);
159 }
160
162 bool saveModel(char* fileName, int& geoBlk, int& nBlock)
163 {
164 return solver.saveModel(fileName, geoBlk, nBlock);
165 }
166
168 bool saveStep(const TimeStep& tp, int& nBlock)
169 {
170 return solver.saveStep(tp, nBlock);
171 }
172
175 {
176 solver.registerFields(exporter);
177 }
178
181 bool serialize(std::map<std::string,std::string>& data)
182 {
183 return solver.serialize(data);
184 }
185
188 bool deSerialize(const std::map<std::string,std::string>& data)
189 {
190 return solver.deSerialize(data);
191 }
192
194 void setLinear(bool enable) { linear = enable; }
195
196protected:
197 Solver& solver;
199 bool alone;
200 bool linear = false;
201 bool assemble = true;
202};
203
204}
205
206#endif
std::vector< Vector > Vectors
An array of real-valued vectors with algebraic operations.
Definition MatVec.h:37
Class for administration MPI processes used by the IFEM library, in particular parallel linear algebr...
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:31
void setLinear(bool enable)
Mark operator as linear to avoid repeated assembly and factorization.
Definition SIMExplicitRK.h:194
RKTableaux RK
Tableaux of Runge-Kutta coefficients.
Definition SIMExplicitRK.h:198
const ProcessAdm & getProcessAdm() const
Returns the parallel process administrator.
Definition SIMExplicitRK.h:78
bool deSerialize(const std::map< std::string, std::string > &data)
Set internal state from a serialized state.
Definition SIMExplicitRK.h:188
virtual bool solveStep(TimeStep &tp)
Computes the solution for the current time step.
Definition SIMExplicitRK.h:81
bool linear
If true operators are constant.
Definition SIMExplicitRK.h:200
bool saveStep(const TimeStep &tp, int &nBlock)
Saves the converged results of a given time step to VTF file.
Definition SIMExplicitRK.h:168
bool serialize(std::map< std::string, std::string > &data)
Serialize internal state for restarting purposes.
Definition SIMExplicitRK.h:181
SIMExplicitRK(Solver &solv, Method type, bool standalone=true)
Constructor.
Definition SIMExplicitRK.h:37
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 alone
If true, this is a standalone solver.
Definition SIMExplicitRK.h:199
bool saveModel(char *fileName, int &geoBlk, int &nBlock)
Opens a new VTF-file and writes the model geometry to it.
Definition SIMExplicitRK.h:162
bool advanceStep(TimeStep &tp)
Advances the time step one step forward.
Definition SIMExplicitRK.h:156
bool assemble
If true, assemble operators.
Definition SIMExplicitRK.h:201
void registerFields(DataExporter &exporter)
Registers fields for output to a data exporter.
Definition SIMExplicitRK.h:174
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:1619
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