rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
detailed_simulation.m
1 function [sim_data, fl] = detailed_simulation(dmodel, model_data)
2 % function sim_data = detailed_simulation(dmodel, model_data)
3 % executes a detailed simulation for a given parameter
4 %
5 % required fields of model:
6 % T : final time
7 % nt : number of time-steps
8 % `0 = t_0 \leq t_1 \leq \cdots \leq t^K+1 = T`, i.e. `K+1`.
9 % init_values_algorithm : function pointer for computing the initvalues-DOF
10 % with arguments '(model, model_data)'
11 % - example: fv_init_values()
12 % .
13 % L_E_local_ptr : function pointer to the local space-discretization
14 % operator evaluation with syntax
15 % @code
16 % INC_local = L_local(U_local_ext, ind_local, grid_local_ext)
17 % @endcode
18 % where '*_local' indicates results on a set of elements,
19 % '*_local_ext' includes information including their
20 % neighbours, i.e. the grid must be known also for the
21 % neighbours, the values of the previous timstep must be known
22 % on the neighbours. The subset of elements, which are to be
23 % computed are given in ind_local and the values produced are
24 % 'INC_local'.
25 % A time-step can then be realized by
26 % @code
27 % NU_local = U_local_ext(ind_local) - dt * INC_local
28 % @endcode
29 % - example: fv_conv_explicit_space()
30 % .
31 %
32 % optional fields of model:
33 % data_const_in_time : if this optional field is 1, the time
34 % evolution is performed with constant operators,
35 % i.e. only the initial-time-operators are computed
36 % and used throughout the time simulation.
37 %
38 % Return values:
39 % sim_data: structure holding the `H`-dimensional simulation data.
40 % fl: debug output holding the flux evaluations returned by the
41 % 'L_E_local_ptr' operator.
42 %
43 % Generated fields of sim_data:
44 % U: matrix of size `H \times K+1` holding for each time step the solution
45 % dof vector.
46 % Unewton: matrix of size `H \times K+1+\sum_{k=0}^K n_{\text{Newton}}(k)`
47 % holding for each time step and each Newton iteration the
48 % intermediate solution dof vectors.
49 %
50 
51 
52 % Martin Drohmann 9.12.2007 based on detailed_nonlin_evol_simulation.m by
53 % Bernard Haasdonk
54 
55 if nargin ~= 2
56  error('wrong number of parameters!');
57 end;
58 
59 if dmodel.verbose >= 9
60  disp('entered detailed simulation ');
61 end;
62 
63 if isempty(model_data)
64  model_data = gen_model_data(dmodel);
65 end;
66 
67 % for a detailed simulation we do not need the affine parameter
68 % decomposition
69 dmodel.decomp_mode = 0;
70 
71 model = dmodel.descr;
72 
73 if dmodel.compute_conditions
74  compute_conditions = true;
75  LIconds = zeros(1, model.nt);
76  gradLIconds = [];
77 else
78  compute_conditions = false;
79 end
80 
81 % initial values by midpoint evaluation
82 U0 = model.init_values_algorithm(model,model_data);
83 
84 U = zeros(length(U0(:)),model.nt+1);
85 U(:,1) = U0(:);
86 
87 if ~isfield(model,'data_const_in_time')
88  model.data_const_in_time = 0;
89 end
90 
91 if ~isfield(model, 'newton_regularisation')
92  model.newton_regularisation = 0;
93 end
94 
95 fl = cell(model.nt, 1);
96 % loop over fv-steps
97 if model.fv_impl_diff_weight ~= 0 && ~model.newton_solver
98  % diffusive part is computed implicitly.
100  [L_diff_I, const_diff_I] = model.implicit_operators_algorithm(model, model_data, []);
101  clear_all_caches;
102 end
103 
104 model.dt = model.T / model.nt;
105 
106 nmax = 0;
107 nlast = 1;
108 Unewton = U0;
109 for t = 1:model.nt
110  model.t = (t-1)*model.dt;
111  model.tstep = t;
112  if model.verbose > 19
113  disp(['entered time-loop step ',num2str(t), ' for non linear evolution equation']);
114  elseif model.verbose > 9
115  fprintf('.');
116  end;
117 
118  [inc, fluxes] = model.L_E_local_ptr(model, model_data, U(:,t), []);
119 
120  if model.debug == 1
121  fl{t} = fluxes;
122  end
123  if all([model.fv_impl_conv_weight, model.fv_impl_diff_weight, ...
124  model.fv_impl_react_weight] == [0, 0, 0])
125  % purely explicit scheme
126  U(:,t+1) = U(:,t) - model.dt * inc;
127  elseif model.newton_solver
128  V = zeros(length(U0(:)),model.newton_steps+1);
129  exprhs = model.dt * inc;
130  V(:,1) = U(:,t) - exprhs;
131  n=0;
132  residual=inf;
133 % while true
134 % n=n+1;
135  for n=1:model.newton_steps;
136  if model.verbose > 10
137  disp(['Computing time step no. ', num2str(t), ...
138  ', Newton step no. ', num2str(n), ...
139  '... Residual norm: ']);
140  end
141  model.t = model.t + model.dt;
142  Urhs = model.L_I_local_ptr(model, model_data, V(:,n), []);
143  [gradL_I, gL_I_offset] = ...
144  model.implicit_gradient_operators_algorithm(model, model_data, ...
145  V(:,n),[]);
146  if compute_conditions
147  gradLIconds = [gradLIconds, condest(gradL_I)];
148  end
149  model.t = model.t - model.dt;
150  gradL_I = gradL_I * model.dt + speye(size(gradL_I));
151  rhs = - V(:,n) + U(:,t) - exprhs - model.dt * Urhs;
152  VU = gradL_I \ rhs;
153  residual = sqrt(model.inner_product(model, model_data, VU, VU));
154  Vnew = V(:,n) + VU;
155  if model.newton_regularisation
156  [i] = find(Vnew < 0);
157  if(~isempty(i))
158 % epsilon = 0.99*min(-V(i,n)./VU(i));
159 % % epsilon = 1;
160  disp(' == regularisation == ');
161  Vnew(i) = 0.000;
162  %Vnew = V(:,n) + epsilon * VU;
163  end
164  end
165  V(:,n+1) = Vnew;
166  nres = Vnew - U(:,t) + exprhs + model.dt * Urhs;
167  nres = sqrt(model.inner_product(model, model_data, nres, nres));
168  if model.verbose > 10
169  disp([num2str(residual), ' newton residual: ', num2str(nres)]);
170  end
171  if nres < model.newton_epsilon
172  nmax = max(nmax, n);
173  break;
174  end
175  end
176  U(:,t+1) = V(:,n+1);
177  Unewton = [Unewton, V(:,1:n+1)];
178  nlast = nlast + n + 2;
179  else % scheme with implicit parts, but without newton_scheme
180  if ~model.data_const_in_time
182  model.t=model.t+model.dt;
183  [L_diff_I, const_diff_I] = model.implicit_operators_algorithm(model, model_data, []);
184  model.t=model.t-model.dt;
186  end
187  inc = inc - const_diff_I;
188  L_I = L_diff_I;
189  L_I = L_I * model.dt + speye(size(L_I));
190  if compute_conditions
191  LIconds(t) = condest(L_I);
192  end
193 % L_I = speye(size(L_diff_I));
194 % keyboard;
195 
196  rhs = U(:,t) - model.dt * inc; % + model.dt * L_diff_I * U(:,t);
197 % U(:,t+1) = rhs;
198  U(:,t+1) = L_I \ rhs;
199 % [U(:,t+1), flag] = bicgstab(L_I, rhs, 10e-5, 1000);
200  if flag>0
201  disp(['error in system solution, solver return flag = ', ...
202  num2str(flag)]);
203  keyboard;
204  end;
205  end
206 end
207 
208 if model.newton_solver && model.verbose > 0
209  disp(['computation ready: We needed at most ', num2str(nmax), ' Newton steps']);
210 end
211 
212 sim_data.U = U;
213 
214 if compute_conditions
215  sim_data.conds.LI = LIconds;
216  sim_data.conds.gradLI = gradLIconds;
217 end
218 
219 if model.newton_solver
220  sim_data.Unewton = Unewton;
221 end
222 
223 if model.verbose > 9
224  fprintf('\n');
225 end;
226 
function r = verbose(level, message, messageId)
This function displays messages depending on a message-id and/or a level. Aditionally you can set/res...
Definition: verbose.m:17
function clear_all_caches()
This function clears the caches generated for caching of gradient data in evolution schemes...