rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
rb_simulation_impl.m
1 function rb_sim_data = rb_simulation_impl(rmodel, reduced_data)
2 %function rb_sim_data = rb_simulation_impl(rmodel, reduced_data)
3 % function, which performs a reduced basis online simulation for
4 % the parameter vector `\mu \in {\cal P} \subset \mathbb{R}^p`, which is
5 % assumed to be set by IDetailedModel.set_mu()
6 %
7 % - allowed dependency of data: Nmax, Mmax, N, M, mu
8 % - not allowed dependency of data: H
9 % - allowed dependency of computation: Nmax, Mmax, N, M, mu
10 % - not allowed dependency of computation: H
11 % - Unknown at this stage: ---
12 %
13 % The behaviour of this simulation is controlled by the ModelDescr structure
14 % 'rmodel.descr'.
15 %
16 % Parameters:
17 % reduced_data: of type NonlinEvol.EiRbReducedDataNode
18 %
19 % Required fields of descr:
20 % mu_names : the cell array of names of mu-components and
21 % for each of these stringt, a corresponding
22 % field in model is expected.
23 % T : end-time of simulation
24 % nt : number of timesteps to compute
25 % L_E_local_name : name of the local space-discretization operator
26 % evaluation with syntax
27 % @code
28 % INC_local = L_local(U_local_ext, ind_local,
29 % grid_local_ext, model) @endcode
30 % where '*_local' indicates results on a set of
31 % elements, '*_local_ext' includes information including
32 % their neighbours, i.e. the grid must be known also for the
33 % neighbours, the values of the previous timstep must be
34 % known on the neighbours. The subset of elements, which are
35 % to be computed are given in ind_local and the values
36 % produced are 'INC_local'.
37 % Subsequent time-step operator would be defined
38 % as 'NU_local = U(ind_local) - dt * INC_local'
39 % rb_operators : function pointer to a method assembling the decomposed
40 % discretization operators
41 %
42 % optional fields of model:
43 % data_const_in_time : if this flag is set, then only operators
44 % for first time instance are computed
45 %
46 % generated fields of rb_sim_data:
47 % a : 'a(:,k)' is the coefficient vector of the reduced simulation at time
48 % `t^{k-1}`
49 %
50 
51 % Bernard Haasdonk 15.5.2007
52 
53 if ~(nargin == 2)
54  error('wrong number of arguments: should be 2');
55 end
56 
57 if rmodel.compute_conditions
58  LIconds = zeros(1, rmodel.descr.nt);
59  gradLIconds = [];
60 end
61 
62 %% compute a posteriori error estimator (c.f. diploma thesis Martin Drohmann
63 % p. 26ff.)
64 if ~rmodel.enable_error_estimator
65  rmodel.Mstrich = 0;
66 end
67 
68 if rmodel.verbose >= 10
69  disp(['performing simulation for mu = ',mat2str(get_mu(rmodel))]);
70 end;
71 
72 if ~isfield(rmodel, 'filecache_velocity_matrixfile_extract')
73  filecache_velocity_matrixfile_extract = 0;
74 else
75  filecache_velocity_matrixfile_extract = rmodel.filecache_velocity_matrixfile_extract;
76 end
77 
78 % set init data
79 rmodel.decomp_mode = 2;
80 
81 sa0 = rb_init_values(rmodel,[], 2);
82 
83 a0 = lincomb_sequence(reduced_data.a0, sa0);
84 
85 model = rmodel.descr;
86 
87 
88 % perform simulation loop in time
89 model.dt = model.T/model.nt;
90 a = zeros(rmodel.N, model.nt+1); % matrix of RB-coefficients
91 a(:,1) = a0;
92 
93 % in case of velocity-file access, the correct filename must be set here
94 % the following is only relevant in case of use of a
95 % model.use_velocitymatrix_file and filecaching mode 2
96 if filecache_velocity_matrixfile_extract == 2;
97  % change global velocity file to MMax velocity file generated in offline
98  rmodel.descr.velocity_matrixfile = ...
99  ['M',num2str(model.M(1)),'_','gridpart_Mmax',num2str(model.Mmax),'_',...
100  model.velocity_matrixfile];
101 end
102 
103 %disp('temporary true mass matrix is considered');
104 %M = reduced_data.M;
105 
106 if rmodel.enable_error_estimator
107  % Lipschitz constants
108  if ~isfield(model, 'C_E')
109  C_E = 1;
110  else
111  C_E = model.C_E;
112  end
113  if ~isfield(model, 'C_I')
114  C_I = 1;
115  else
116  C_I = model.C_I;
117  end
118  % initialize error estimator
119  Delta = 0;
120  % initialize error estimator log (strictly increasing)
121  Deltalog = zeros(1, model.nt-1);
122  % initialize log of residuum for each time step
123  reslog = zeros(1, model.nt-1);
124  % initialize part for ei estimation for each time step
125  eilog = zeros(1, model.nt-1);
126  % initialize part for newton error for each time step
127  newtonlog = zeros(1, model.nt);
128 end
129 
130 if isa(rmodel.M, 'DataTree.INode')
131  datanode_mode = true;
132 else
133  datanode_mode = false;
134 end
135 
136 Mstrich = rmodel.Mstrich;
137 M = get_current_M(rmodel);
138 % M plus Mstrich
139 MM = M + Mstrich;
140 
141 impl_tstop = 0;
142 expl_tstop = 0;
143 
144 % model for explicit part (has different affine decomposition)
145 emodel = model;
146 emodel.decomp_mode = 0;
147 
148 % loop over time steps: computation of a(t+1)==a^t
149 for t = 1:model.nt
150  model.t = (t-1)*model.dt;
151  emodel.t = model.t;
152  emodel.tstep = t;
153  if rmodel.verbose >= 10
154  disp(['entered time-loop step ',num2str(t)]);
155  end;
156 
157  % update reduced data for operators if necessary.
158  if t > expl_tstop
159  rmodel.t = emodel.t;
160  rmodel.tstep = emodel.tstep;
161  [expl_reduced_data, expl_tstop, Mexpl, Mred_expl]...
162  = get_reduced_data_for_operator('explicit', rmodel, reduced_data, datanode_mode);
163  rmodel.t = model.t;
164  rmodel.tstep = model.tstep;
165  end
166  if t >= impl_tstop
167  imodel = model;
168  imodel.tstep = t+1;
169  rmodel.t = imodel.t;
170  rmodel.tstep = imodel.tstep;
171  [impl_reduced_data, impl_tstop, Mimpl, Mred_impl]...
172  = get_reduced_data_for_operator('implicit', rmodel, reduced_data, datanode_mode);
173  rmodel.t = model.t;
174  rmodel.tstep = model.tstep;
175  end
176 
177  % asssemble affine parameter compositions of implicit parts
178  % only once, if data is const in time
179  if ~model.newton_solver && ((t==1) || (~model.data_const_in_time))
180  if model.implicit_nonlinear
181  tmpmodel = model;
182  tmpmodel.decomp_mode = 0;
184  [L_I_red, b_I_red] = ...
185  model.implicit_operators_algorithm(tmpmodel, impl_reduced_data,...
186  impl_reduced_data.TM_local); % tii
188 
189  LL_I_red = L_I_red * impl_reduced_data.RB_local_ext; % tii
190  LL_I = impl_reduced_data.CE(:,1:Mred_impl) * ... % tii
191  LL_I_red;
192 
193  bb_I = impl_reduced_data.CE(:,1:Mred_impl) * ...
194  b_I_red; %tii
195 
196  else
197  [sLL_I, sbb_I] = ...
198  NonlinEvol.ReducedData.rb_operators(rmodel,[], 2); % detailed_data omitted
199  if ~isempty(reduced_data.LL_I)
200  LL_I = lincomb_sequence(reduced_data.LL_I,sLL_I);
201  else
202  LL_I = sparse([],[],[],rmodel.N,rmodel.N);
203  end;
204  if ~isempty(reduced_data.bb_I)
205  bb_I = lincomb_sequence(reduced_data.bb_I, sbb_I);
206  else
207  bb_I = sparse([],[],[],rmodel.N,1);
208  end;
209  end;
210  end;
211 
212  % setup linear system A * a(:,t+1) = rhs
213  % with A = Id + dt * LL_I
214  % rhs = a(:,t) - dt * BB_I - dt * CE * ll_E(a(:,t))
215  % where ll_E is the local operator evaluation
216 
217  if ~model.newton_solver
218  A = LL_I * model.dt + speye(size(LL_I));
219  if rmodel.compute_conditions
220  LIconds(t) = condest(A);
221  end
222  else
223  A = 0;
224  bb_I = 0;
225  end
226 
227  % determine local values by reconstructing U values from reduced
228  % basis parts
229  U_local_ext = expl_reduced_data.RB_local_ext * a(:,t); % ti
230 
231  % the following performs
232  % U_local = L_local(U_local_ext, TM_local, [], ...
233  % reduced_data.grid_local_ext);
234  %
235  % note the use of emodel
236 
237  le_local_inc = emodel.L_E_local_ptr(emodel, expl_reduced_data, ...
238  U_local_ext, ...
239  expl_reduced_data.TM_local); % ti
240 % le_local_inc(U_local_ext(reduced_data.TM_local{crbInd_exp,tii}) + le_local_inc > 1) = 0;
241 
242  if model.newton_solver
243  nmax = -1;
244  updelta_a = zeros(rmodel.N, model.newton_steps+1);
245  updelta_a(:,1) = a(:,t);
246  n=0;
247 
248  for n=1:model.newton_steps
249  if rmodel.verbose > 10
250  disp(['Computing time step no. ', num2str(t), ...
251  ', Newton step no. ', num2str(n), ...
252  '... Residual norm: ']);
253  end
254  model.decomp_mode = 0;
255  updelta_rec = impl_reduced_data.RB_local_ext * updelta_a(:,n); % tii
256  if rmodel.debug && any(updelta_rec < -10*eps)
257  disp(num2str(min(updelta_rec)));
258  warning('RBMatlab:rb_simulation:runtime', ...
259  'reconstructed solutions at interpolation points is negative!');
260  end
261  model.t = model.t + model.dt;
262  % updelta_rec(updelta_rec < 0) = 0.001;
263  li_local_inc = model.L_I_local_ptr(model, impl_reduced_data, ...
264  updelta_rec, ...
265  impl_reduced_data.TM_local); % tii
266 
267  [gradL_I, gL_I_offset] = ...
268  model.implicit_gradient_operators_algorithm(model, impl_reduced_data, ...
269  updelta_rec,...
270  impl_reduced_data.TM_local(1:Mred_impl)); % tii
271  model.t = model.t - model.dt;
272  if any(gL_I_offset ~= 0)
273  warning('offset has non-zero entries!');
274  end
275 
276  gradL_I = impl_reduced_data.CE_red * gradL_I ...
277  * impl_reduced_data.RB_local_ext;
278 
279  gradL_I = gradL_I * model.dt + speye(size(gradL_I));
280 
281  opts.LT = true;
282 
283  if impl_reduced_data ~= expl_reduced_data
284  theta_update_expl = linsolve(expl_reduced_data.BM(1:MM,1:MM), ...
285  le_local_inc(1:MM), ...
286  opts);
287  theta_update_impl = linsolve(impl_reduced_data.BM(1:MM,1:MM), ...
288  li_local_inc(1:MM), ...
289  opts);
290 
291  arhs = expl_reduced_data.DE(:,1:Mred_expl) ...
292  * theta_update_expl(1:Mred_expl) ...
293  + impl_reduced_data.DE(:,1:Mred_impl) ...
294  * theta_update_impl(1:Mred_impl);
295  else
296  theta_update = linsolve(expl_reduced_data.BM(1:MM,1:MM), ...
297  le_local_inc(1:MM) + li_local_inc(1:MM), ...
298  opts);
299 
300  arhs = expl_reduced_data.DE(:,1:Mred_expl) ...
301  * theta_update(1:Mred_expl);
302  end
303 
304  full_rhs = - updelta_a(:,n) + a(:,t) - model.dt * arhs;
305 
306  delta_a = gradL_I \ full_rhs;
307 
308  if rmodel.compute_conditions
309  gradLIconds = [gradLIconds, condest(gradL_I)];
310  end
311 
312  updelta_a(:,n+1) = updelta_a(:,n) + delta_a;
313  nres_a = updelta_a(:,n+1) -a(:,t) + model.dt * arhs;
314  nres = sqrt(nres_a' * nres_a);
315  if model.verbose > 10
316  disp(num2str(nres));
317  end
318  if nres < model.newton_epsilon
319  nmax = max(nmax, n);
320  break;
321  end
322  end
323  a(:,t+1) = updelta_a(:,n+1);
324  else % no newton solver...
325  % compute coefficients of update in CRB Space `\W_{M+M'}`.
326  opts.LT = true;
327  theta_update_expl = linsolve(expl_reduced_data.BM(1:MM,1:MM), ...
328  le_local_inc, opts);
329  theta_update = theta_update_expl;
330 
331  rhs = a(:,t) - model.dt * bb_I ...
332  - model.dt * expl_reduced_data.DE(:,1:Mred_expl) ...
333  * theta_update_expl(1:Mred_expl);
334 
335  % check if an LES is to be solved, or problem is an explicit problem
336  if isequal(A, speye(size(A)))
337  a(:,t+1) = rhs;
338  else
339 % disp('check symmetry and choose solver accordingly!');
340 % keyboard;
341  % nonsymmetric solvers:
342  [a(:,t+1), flag, relres, iter] = bicgstab(A,rhs,1e-10,1000);
343  % [a(:,t+1), flag] = cgs(Li,rhs,[],1000);
344  % symmetric solver, non pd:
345  % see bug_symmlq for a very strange bug: cannot solve identity system!
346  % [a(:,t+1), flag] = symmlq(Li,rhs,[],1000);
347  % [a(:,t+1), flag] = minres(Li,rhs,[],1000);
348  % symmetric solver, pd:
349  %[a(:,t+1), flag] = bicgstab(A,rhs,[],1000);
350  if(t==1 && model.debug)
351  disp(cond(A));
352  disp(all(A'==A));
353  disp(eig(full(A)));
354  end
355  if(t==1) % && model.verbose > 10)
356  disp(['relres=', num2str(relres), ' iter=', num2str(iter)]);
357  end
358  % exact solver:
359  % a(:,t+1)=A \ rhs;
360  if flag>0
361  disp(['error in system solution, solver return flag = ', ...
362  num2str(flag)]);
363  keyboard;
364  end
365  end
366  end
367 
368  if rmodel.enable_error_estimator
369  if ~isinf(impl_tstop)
370  error('error estimator does not work with varying crbs for different time slices yet');
371  end
372  ainc = a(:,t) - a(:,t+1);
373 
374  if model.newton_solver
375  lipschitzConst = C_I^(model.nt - t + 2)*C_E^(model.nt - t + 1);
376  newtonlog(t) = nres + model.newton_epsilon;
377  else
378  lipschitzConst = C_E^(model.nt - t + 1);
379  newtonlog(t) = 0;
380  end
381  if impl_reduced_data == expl_reduced_data
382  % note that in case of one basis for both operators all values are the
383  % same for both operators, i.e. Mexpl == Mimpl, impl_tstop == expl_tstop,
384  % expl_reduced_data.Mmass === impl_reduced_data.Mmass
385  %
386  % compute the residuum `\delta t norm(R^k)`
387  % TODO revise the following
388  residuum = sqrt( abs( ainc' * ainc ...
389  - 2*model.dt * ainc' ...
390  * ( expl_reduced_data.DE(:,1:Mexpl) ...
391  * theta_update(1:Mexpl) ) ...
392  + model.dt^2 * theta_update(1:Mexpl)' ...
393  * expl_reduced_data.Mmass(1:Mexpl,1:Mexpl) ...
394  * theta_update(1:Mexpl)) );
395  else
396 % theta_update = theta_update_expl + theta_update_impl;
397  error('residuum can only be computed for the case when _one_ reduced basis space for both operators has been computed.');
398  end
399  reslog(t) = residuum;
400 
401  % compute the empirical interpolation error estimation
402  eilog(t) = model.dt*lipschitzConst ...
403  * sqrt(abs( ...
404  theta_update(M+1:MM)' ...
405  * impl_reduced_data.Mmass(M+1:MM,M+1:MM) ...
406  * theta_update(M+1:MM) ));
407 
408  Delta = Delta + eilog(t) ...
409  + lipschitzConst*newtonlog(t) ...
410  + lipschitzConst*residuum;
411  if ~isreal(Delta)
412  warning('RBMatlab:rb_simulation:runtime',...
413  'error estimator returned complex result');
414  Delta = real(Delta);
415  end
416  Deltalog(t) = Delta;
417  end
418 end; % timeloop
419 
420 if model.newton_solver && rmodel.verbose > 11
421  disp(['computation ready: We needed at most ', num2str(nmax), ' Newton steps']);
422 end
423 
424 if rmodel.enable_error_estimator
425  rb_sim_data.Delta = [0, Deltalog];
426  rb_sim_data.reslog = [0, reslog];
427  rb_sim_data.eilog = [0, eilog];
428 end
429 
430 % prepare return parameters
431 rb_sim_data.a = a;
432 
433 if rmodel.compute_conditions
434  rb_sim_data.conds.LI = LIconds;
435  rb_sim_data.conds.gradLI = gradLIconds;
436 end
437 
438 end
439 
440 function [reduced_data_op, tstop, Mop, Mred] = get_reduced_data_for_operator(id, rmodel, reduced_data, datanode_mode)
441 
442  if datanode_mode
443  % Mind = get_index(rmodel.M, id, model.t);
444  Mind = get_index(rmodel.M, id, get_mu(rmodel), rmodel.t);
445  M = get(rmodel.M, [Mind,1]);
446  else
447  M = rmodel.M;
448  end
449  MM = M + rmodel.Mstrich;
450 
451  %crbInd = get_index(reduced_data, id, rmodel);
452  crbInd = get_index(reduced_data, id, get_mu(rmodel), rmodel.t);
453  reduced_data_op = get(reduced_data, crbInd);
454  tstop = index_valid_till(reduced_data, crbInd);
455  Mop = MM;
456  assert(Mop <= length(reduced_data_op.TM_local));
457 
458  Mred = min(Mop, M);
459 
460  if isempty(reduced_data_op.CE) ...
461  || any(size(reduced_data_op.CE) ~= size(reduced_data_op.DE))
462  reduced_data_op.CE = reduced_data_op.DE / reduced_data_op.BM;
463  reduced_data_op.CE_red = reduced_data_op.DE(:,1:Mred) ...
464  / reduced_data_op.BM(1:Mred, 1:Mred);
465  end
466 end
467 
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
Reduced basis implementation for non-linear evolution equations.
function IDetailedModel this = set_mu(mu)
sets the active parameter vector
Struct with control fields for the analytical PDE functions, the discretization and the parametrizati...
Definition: dummyclasses.c:15
This is the interface for a detailed model providing methods to compute high dimensional simulation s...
Reduced data implementation for non-linear evolution problems with finite volume discretizations.
function [ descr , rdescr , dmodel , rmodel ] = newton(steps, combined, M_by_N_ratio, noof_ei_extensions, use_laplacian, model_size, random, num_cpus, Mstrich)
small script demonstrating a buckley leverett problem discretization and RB model reduction ...
Definition: newton.m:17
function clear_all_caches()
This function clears the caches generated for caching of gradient data in evolution schemes...