KerMor  0.9
Model order reduction for nonlinear dynamical systems and nonlinear approximation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SemiImplicitEuler.m
Go to the documentation of this file.
1 namespace solvers{
2 
3 
4 /* (Autoinserted by mtoc++)
5  * This source code has been filtered by the mtoc++ executable,
6  * which generates code that can be processed by the doxygen documentation tool.
7  *
8  * On the other hand, it can neither be interpreted by MATLAB, nor can it be compiled with a C++ compiler.
9  * Except for the comments, the function bodies of your M-file functions are untouched.
10  * Consequently, the FILTER_SOURCE_FILES doxygen switch (default in our Doxyfile.template) will produce
11  * attached source files that are highly readable by humans.
12  *
13  * Additionally, links in the doxygen generated documentation to the source code of functions and class members refer to
14  * the correct locations in the source code browser.
15  * However, the line numbers most likely do not correspond to the line numbers in the original MATLAB source files.
16  */
17 
19  :public solvers.BaseCustomSolver {
49  private:
50 
51  model;
52 
53 
54  public:
55 
57  this.model= model;
58  if ~isa(model.System," models.BaseFirstOrderSystem ")
59  error(" Solver not implemented for non-first order systems. ");
60  end
61  this.Name= " Semi-implicit euler method ";
62  this.SolverType= solvers.SolverTypes.Implicit;
63  }
64 
65 
66  protected:
67 
68  function matrix<double>x = customSolve(unused1,rowvec<double> t,colvec<double> x0,rowvec<integer> outputtimes) {
69  s = this.model.System;
70  if isempty(s.A)
71  error(" This solver requires an (affine) linear system component A. ");
72  end
73 /* if isa(s.Model,'models.ReducedModel') && ~isempty(s.Model.ErrorEstimator)...
74  * && s.Model.ErrorEstimator.Enabled && s.Model.ErrorEstimator.ExtraODEDims > 0
75  * error('Cannot use this solver with reduced models that have an error estimator enabled with ExtraODEDims > 0 (this solver overrides the odefun handle)');
76  * end
77  * Initialize result */
78  steps = length(t);
79 
80  dt = t(2)-t(1);
81  if ~isempty(find((abs(t(2:end)-t(1:end-1) - dt)) / dt > 1e-6,1)) /* any(t(2:end)-t(1:end-1) - dt > 100*eps) */
82 
83  error(" non-equidistant dt timesteps. ");
84  end
85 
86  rtm = this.RealTimeMode;
87  /* Initialize output index counter */
88  outidx = 2;
89  if rtm
90  ed = solvers.SolverEventData;
91  x = [];
92  else
93  effsteps = length(outputtimes);
94  /* Create return matrix in size of effectively desired timesteps */
95  x = [x0 zeros(size(x0,1),effsteps-1)];
96  end
97 
98  oldex = []; newex = []; edim = 0; est = [];
99  if isa(this.model," models.ReducedModel ")
100  est = this.model.ErrorEstimator;
101  if ~isempty(est) && est.Enabled
102  edim = est.ExtraODEDims;
103  oldex = x0(end-edim+1:end);
104  end
105  end
106 
107  /* Check if a mass matrix is present, otherwise assume identity matrix */
108  M = s.getMassMatrix;
109  mdep = M.TimeDependent;
110  if ~mdep
111  M = M.evaluate(0);
112  end
113 
114  fdep = s.A.TimeDependent;
115  if ~fdep
116  /* Evaluation with x=1 "extracts" the matrix A of the (affine) linear system */
117  A = s.A.getStateJacobian;
118  end
119 
120  /* Precompute lu decomp for iteration steps if all components are not time-dependent */
121  if ~mdep && ~fdep
122  [l, u] = lu(M - dt * A);
123  end
124 
125  /* Solve for each time step */
126  oldx = x0(1:end-edim);
127  for idx = 2:steps;
128  RHS = M*oldx;
129  if ~isempty(s.f)
130  RHS = RHS + dt*s.f.evaluate(oldx, t(idx-1));
131  end
132  if ~isempty(s.B)
133  RHS = RHS + dt*s.B.evaluate(t(idx-1), s.mu)*s.u(t(idx-1));
134  end
135 
136  /* Time-independent case: constant */
137  if ~fdep && ~mdep
138  newx = u\(l\RHS);
139  /* Time-dependent case: compute time-dependent components with updated time */
140  else
141  if fdep
142  A = s.A.evaluate(1, t(idx));
143  end
144  if mdep
145  M = s.M.evaluate(t(idx));
146  end
147  newx = (M - dt * A)\RHS;
148  end
149 
150  /* Implicit error estimation computation */
151  if ~isempty(oldex)
152  ut = [];
153  if ~isempty(s.u)
154  ut = s.u(t(idx));
155  end
156  /* al = est.getAlpha(newx, t(idx), s.mu, ut);
157  *bet = est.getBeta(newx, t(idx), s.mu); */
158 
159  /* Explicit */
160  odepart = est.evalODEPart([newx; oldex], t(idx-1), ut);
161  newex = oldex + dt * odepart;
162  /* newex = oldex + dt*(bet*oldex + al); */
163 
164  /* Implicit
165  *newex = (dt*al+oldex)/(1-dt*bet); */
166 
167 /* fun = @(y)y-dt*est.evalODEPart([oldx; y], t(idx), s.mu, ut)-oldex/dt;
168  * opts = optimset('Display','off');
169  * newex2 = fsolve(fun, oldex, opts); */
170  end
171 
172  /* Only produce output at wanted timesteps */
173  if outputtimes(outidx) == idx
174  if rtm
175  /* Real time mode: Fire StepPerformed event */
176  ed.Times= t(idx);
177  ed.States= [newx; newex];
178  this.notify(" StepPerformed ",ed);
179  /* Normal mode: Collect solution in result vector */
180  else
181  x(:,outidx) = [newx; newex];/* #ok */
182 
183  end
184  outidx = outidx+1;
185  end
186  oldx = newx;
187  oldex = newex;
188  end
189  }
213 };
214 }
215 
notify
Broadcast a notice that a specific event is occurring on a specified handle object or array of handle...
The base class for any KerMor detailed model.
Definition: BaseFullModel.m:18
logical RealTimeMode
Determines if the solver's StepPerformed event should be used upon solving instead of returning the f...
Definition: BaseSolver.m:85
models.BaseFirstOrderSystem System
The actual dynamical system used in the model.
Definition: BaseModel.m:102
BaseCustomSolver: Base class for all self-implemented solvers.
SemiImplicitEuler(models.BaseFullModel model)
logical TimeDependent
Flag that indicates time-dependency of the Mass Matrix.
Definition: AMassMatrix.m:42
Name
The solver's name.
Definition: BaseSolver.m:116
SemiImplicitEuler: Solves ODEs in KerMor using implicit euler for the linear part and explicit euler ...
solvers.SolverTypes SolverType
The type of the solver.
Definition: BaseSolver.m:130
dscomponents.AMassMatrix M
The mass matrix of the ODE .
Definition: BaseSolver.m:101
function matrix< double > x = customSolve(unused1,rowvec< double > t,colvec< double > x0,rowvec< integer > outputtimes)
Implements the actual semi-implicit solving of the given ODE system.