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
FullyImplEuler.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 {
39  private:
40 
41  model;
49  public:
50 
52  this.model= model;
53  /* "Disable" MaxStep DPCM warning as implicit solvers are stable */
54  this.MaxStep= [];
55  this.SolverType= solvers.SolverTypes.Implicit;
56  }
57 
58 
59  protected:
60 
61  function colvec<double>x = customSolve(odefun,double t,x0,outputtimes) {
62 
63  /* Checks */
64  steps = length(t);
65  dt = t(2)-t(1);
66  if any(t(2:end)-t(1:end-1) - dt > 100*eps)
67  error(" non-equidistant dt timesteps. ");
68  end
69 
70  /* Initializations */
71  rtm = this.RealTimeMode;
72  if rtm
73  ed = solvers.SolverEventData;
74  x = [];
75  else
76  x = [x0 zeros(size(x0,1),steps-1)];
77  end
78  s = this.model.System;
79 
80  /* Check if a mass matrix is present, otherwise assume identity matrix */
81  M = speye(length(x0));
82  mdep = false;
83  if ~isempty(s.M)
84  mdep = s.M.TimeDependent;
85  if ~mdep
86  M = s.M.evaluate(0);
87  end
88  end
89 
90  /* Solve for each time step */
91  oldx = x0;
92  for idx = 1:steps-1;
93  /* Case: time-dependent Mass Matrix */
94  if mdep
95  /* Question: choose t(idx) or t(idx+1)?
96  * Answer (Chris): t(idx+1), because this choice is independent of time-discr. of d/dt x !
97  * and for impl Euler the evaluation time is the "future"-timestep */
98  M = s.M.evaluate(t(idx+1));
99  end
100 
101  /* % Implementation part:
102  * principal equation: M(t)x'(t) = g(x(t),t)
103  * discretized M(t)x(t+) = M(t)x(t) + dt*g(x(t+),t+), t+ = t+\delta t */
104 
105  /* g is given by odefun handle: g(x(t),t) = odefun(<t>,<x>)
106  * \delta t is given by "dt" (above)
107  * \Nabla g is accessible via s.f.getStateJacobian(<x>,<t>,s.mu) */
108 
109  /* write result of newton iteration to "newx" */
110 
111  /* % Newton-Iteration 'by hand'
112  * max_newton_steps = 1000;
113  * min_rel_norm = 1e-5;
114  * actx = oldx;
115  * for newton_it = 1:max_newton_steps
116  * % computing increment
117  * SysMat = M - dt * s.f.getStateJacobian(actx, t(idx+1), s.mu);
118  * delta_x = SysMat \ (M*(oldx - actx) + dt*odefun(t(idx+1), actx));
119  * % updating current state
120  * stepsize = 0.15;
121  * actx = actx + stepsize*delta_x;
122  * % convergence check
123  * if (norm(delta_x)/norm(actx) < min_rel_norm)
124  * break;
125  * end
126  * end
127  * newton_it
128  * newx = actx;
129  *% Matlab fsolve
130  *dis = 'iter'; */
131  dis = " final-detailed ";
132  options_fsolve = optimset(" Display ", dis, " Jacobian ", " on ", ...
133  " MaxIter ", 2000, ...
134  " MaxFunEvals ", 10000, ...
135  " TolFun ", 1e-3);
136  options_fsolve = optimset(options_fsolve, ...
137  " DerivativeCheck ", " off ",...
138  " Diagnostics "," off ");
139  /* options_fsolve = optimset(options_fsolve, 'JacobPattern', s.f.JSparsityPattern); */
140 
141 /* nonlin_fun_h = @(x) deal(M * (x - oldx) - dt*odefun(t(idx+1), x),...
142  * M - dt * s.f.getStateJacobian(x, t(idx+1), s.mu));
143  * nonlin_fun_h = @(x)M * (x - oldx) - dt*odefun(t(idx+1), x); */
144  nonlin_fun_h = @nonlin_fun;
145  /* Nullstelle der schwachen Form finden
146  *[newx, fval, exitflag, output, J_check] = fsolve( nonlin_fun, oldx, options_fsolve ); */
147  newx = fsolve(nonlin_fun_h, oldx, options_fsolve );
148 
149  /* % Postprocessing
150  * Real time mode: Fire StepPerformed event */
151  if rtm
152  ed.Times= t(idx);
153  ed.States= newx;
154  this.notify(" StepPerformed ",ed);
155  /* Normal mode: Collect solution in result vector */
156  else
157  x(:,idx) = newx;/* #ok */
158 
159  end
160  oldx = newx;
161  end
162  function [dx, jac] = nonlin_fun(x)
163  dx = M * (x - oldx) - dt*odefun(t(idx+1), x);
164  jac = M - dt * s.f.getStateJacobian(x, t(idx+1));
165  end
166  }
167 
168 
169 
170 };
171 }
172 
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
BaseCustomSolver: Base class for all self-implemented solvers.
virtual function M = evaluate(double t,colvec< double > mu)
FullyImplSolver: Solver for fully nonlinear ODE's (using Newton iterations)
solvers.SolverTypes SolverType
The type of the solver.
Definition: BaseSolver.m:130
FullyImplEuler(models.BaseFullModel model)
double MaxStep
Maximum time step for solver.
Definition: BaseSolver.m:48
dscomponents.AMassMatrix M
The mass matrix of the ODE .
Definition: BaseSolver.m:101
function colvec< double > x = customSolve(odefun,double t, x0, outputtimes)