rbmatlab  1.13.10
 All Classes Namespaces Files Functions Variables Groups Pages
nonlin_evol_gen_detailed_data.m
Go to the documentation of this file.
1 function detailed_data = nonlin_evol_gen_detailed_data(model, model_data)
2 %function detailed_data = nonlin_evol_gen_detailed_data(model, model_data)
3 % prepares detailed_data structure with high dimensional like reduced basis
4 % functions.
5 %
6 % method, which prepares 'detailed_data', which is meant as data, that may be
7 % dependent on `H`, and is not required during the online-simulation, but it
8 % may be used for reconstruction purposes or computation of online_quantities.
9 % i.e. reduced basis vectors, colateral reduced basis spaces, grid, etc. can be
10 % stored here.
11 %
12 % The grid, the collateral basis for the explicit nonlinearity and the reduced
13 % basis are generated in this order.
14 %
15 % \note The reduced basis generation is delegated to the function
17 %
18 % - allowed dependency of data: `H`
19 % - allowed dependency of computation: `H`
20 % - unknown at this stage: `\mu, N_{\max}, M_{\max}, N, M`
21 %
22 % Required fields of model:
23 % Nmax : maximum number of reduced basis vectors to generate
24 % Mmax : maximum number of collateral reduced basis vectors to
25 % generate
26 % Mstrich : number of collateral reduced basis function used for
27 % a posteriori error estimation.
28 % ei_numintervals : (only used in 'param-time-space-grid' mode) the finite
29 % parameter set for which the empirical interpolation is trained, is given
30 % by through a uniform distribution of parameters in the bounds given by
31 % 'model.mu_ranges'. This field specifies the number of parameters in each
32 % component direction.
33 % ei_space_operators : a cell array of function pointers to the localized
34 % operators for which a collateral reduced basis space shall be created.
35 % CRB_generation_mode : a string which is either
36 % - 'file_load' : simple loading of collateral reduced basis from a file
37 % - 'param-time-space-grid' : search for CRB vectors in a discrete subspace
38 % of the space of all operator evaluations on solutions for parameters in
39 % the 'model.mu_range' boundaries and all timesteps.
40 % CRB_basis_filename : (only used in 'file_load' mode) name of file, that
41 % contains precomputed collateral reduced basis 'QM'.
42 % separate_CRBs : boolean flag, indicating whether, the operator
43 % evaluations shall be stored in different directories for the later
44 % computation of separate collateral reduced basis spaces for each
45 % operator, or combined a single directory.
46 %
47 % Optional fields of model:
48 % adaptive_time_split_mode : boolean flag indicating whether the time slices
49 % shall be computed adaptively. (default == false)
50 % time_split_Mmax : when collateral reduced basis reaches this
51 % size, the current time slice is split in 'adaptive_time_split_mode'
52 % (default = 'model.ei_Mmax')
53 % minimum_time_slice : when time slice contains only this many number of
54 % time steps, adaptation is stopped in 'adaptive_time_split_mode'.
55 % (default = 1)
56 % ei_stop_epsilon : interpolation error limit stopping the basis
57 % extension when reached. This needs to be strictly positive in
58 % 'adaptive_time_split_mode'. (default = 0 respectively 1e-6 in
59 % 'adaptive_time_split_mode')
60 % ei_time_splits : number of time slices the discrete time
61 % interval shall (initially) be splitted into. (default = 1)
62 %
63 % generated fields of detailed_data:
64 % grid : grid to be used in the subsequent stages, copied from 'model_data'
65 % QM : a matrix of columnwise DOF-vectors `q_j` for interpolation
66 % to be used as the colateral basis
67 % TM : a vector for the set of 'magic points' by containing the index
68 % numbers of the corresponding DOF-nodes (In case of piecewise
69 % constant or linear basis-functions, the maxima `x_i` always can be
70 % found in a cell centroid (deg=0) or a node (deg=1).
71 % BM : the corresponding interpolation-matrix of dimension 'Mmax x Mmax',
72 % i.e. interpolation can be done by solving the equation system `B
73 % \sigma = \left(\zeta(x_1), \ldots, \zeta(x_M)\right)` then `Q
74 % \sigma` is the empirical interpolation. Note, that this
75 % reconstruction may not be done in the online phase!
76 % ei_info: details on the empirical interpolation procedure as produced
77 % by ei_detailed() plus the field 'extension_mus'
78 % ei_info.extension_mus: a matrix whose column vectors hold the parameter
79 % vectors corresponding to the solution trajectory serving as a basis
80 % extension function.
81 % RB : matrix with 'Nmax' columns holding the reduced basis vectors
82 %
83 % Return values:
84 % detailed_data : structure containing all the reduced basis data and
85 % information about the generation process.
86 
87 % Bernard Haasdonk 15.5.2007
88 
89 detailed_data = [];
90 detailed_data = structcpy(detailed_data, model_data);
91 params = [];
92 
93 if ~isfield(model, 'adaptive_time_split_mode')
94  model.adaptive_time_split_mode = false;
95 end
96 
97 if ~isfield(model, 'ei_stop_epsilon')
98  if model.adaptive_time_split_mode
99  model.ei_stop_epsilon = 1e-6;
100  else
101  model.ei_stop_epsilon = 0;
102  end
103 end
104 
105 if ~isfield(model, 'ei_time_splits')
106  model.ei_time_splits = 1;
107 end
108 
109 if ~isfield(model, 'extend_crb')
110  model.extend_crb = false;
111 end
112 
113 if ~isfield(model, 'minimum_time_slice')
114  model.minimum_time_slice = 1;
115 end
116 
117 if ~isfield(model, 'time_split_Mmax')
118  model.time_split_Mmax = model.Mmax;
119 end
120 
121 if isa(model.ei_space_operators, 'function_handle')
122  params.ei_space_operators = { model.ei_space_operators };
123 
124 %if ~isfield(model, 'ei_space_operators')
125 % params.ei_space_operators = { model.L_E_local_ptr };
126 % detailed_data.explicit_crb_index = 1;
127 % detailed_data.implicit_crb_index = -1;
128 %else
129 else
130  params.ei_space_operators = model.ei_space_operators;
131 end
132  if model.separate_CRBs
133  detailed_data.implicit_crb_index = 2;
134  detailed_data.explicit_crb_index = 1;
135  else
136  detailed_data.implicit_crb_index = 1;
137  detailed_data.explicit_crb_index = 1;
138  end
139 %end
140 
141 if ~isfield(model, 'ei_time_splits')
142  model.ei_time_splits = 1;
143 end
144 
145 % empirical interpolation of nonlinearity must be performed before
146 % basis-construction, as basis construction needs availability of
147 % reduced simulation.
148 
149 par.range = model.mu_ranges;
150 
151 switch model.CRB_generation_mode
152 
153  % choose the following number of setting, that the time-snapshots
154  % for the parameter ranges fit into memory:
155  % 5x5x5 times 5 timesnapshots of size 8000 = 1250 x 8000 should be fine.
156  % single nonlin simulation of 99 sec extrapolates to 3.5 hours for
157  % 125 detailed simulations!
158 
159  case 'param-time-space-grid'
160 
161  disp('computing param-time-space-grid for empirical interpolation');
162  par.numintervals = model.ei_numintervals;
163  % if ei_operator_collect_tmp is used, set the following params!!
164  %par.numintervals = [1,1,1];
165  M = cubegrid(par);
166  Mtrain = transpose(M.vertex);
167 
168  % initially set-up model.ei_time_splits time slices.
169  detailed_data.time_split_map = [ (1:model.nt+1)', ...
170  (ceil((1:model.nt+1)' / (model.nt+1)* (model.ei_time_splits-0.01))) ];
171 
172  % collect the operator evaluations
173  LU_fnames = ei_operator_collect_files(model, detailed_data, Mtrain, ...
174  params);
175 
176  ei_detailed_data = detailed_data;
177  for lsi = 1:size(LU_fnames,1)
178  params.ei_Mmax = model.Mmax;
179  if model.separate_CRBs
180  disp(['computing CRB for local operator ', ...
181  func2str(params.ei_space_operators{lsi})]);
182  params.ei_Mmax = model.sMmax{lsi};
183  else
184  disp(cell2mat(['computing CRB for local operators: ', ...
185  cellfun(@(X)([func2str(X),' ']), params.ei_space_operators, ...
186  'UniformOutput',false)]));
187  end
188  params.index = lsi;
189  if model.adaptive_time_split_mode
190  max_time_splits = model.ei_time_splits;
191  ti = 1;
192  while ti <= max_time_splits;
193  params.time_index = ti;
194  something_todo = true;
195  params.ei_Mmax = model.time_split_Mmax;
196  params.ei_stop_epsilon = model.ei_stop_epsilon;
197  while something_todo
198  ei_detailed_data = ei_detailed(model, ei_detailed_data, ...
199  LU_fnames(lsi,:), params);
200 
201  tei_info = ei_detailed_data.ei_info{lsi,ti};
202  if tei_info.stopped_on_epsilon % goto next time slice
203  ti = ti + 1; something_todo = false;
204  if model.verbose > 11
205  slice_size = sum(ei_detailed_data.time_split_map(:,2) == ti);
206  disp(['Reached epsilon for time slice ', num2str(ti), ...
207  ' consisting of ' slice_size ' time steps.']);
208  end
209  elseif tei_info.stopped_on_Mmax % Have we reached Mmax?
210  % yes, we reached the time_split_Mmax
211  tmap = ei_detailed_data.time_split_map(:,2);
212  slice_size = sum(tmap == ti);
213  % do we have minimum slice size reached?
214  if floor(slice_size/2) <= model.minimum_time_slice ...
215  || tei_info.max_err_sequence(end) < model.ei_stop_epsilon_first % or first epsilon is reached
216  if model.verbose > 11
217  disp(['Reached minimum size for time slice ', num2str(ti), ...
218  ' consisting of ', num2str(slice_size), ' time steps.']);
219  end
220  % add further basis vectors, if requested...
221  if model.time_split_Mmax ~= model.Mmax
222  params.ei_Mmax = model.Mmax;
223  ei_detailed_data = ei_detailed(model, ei_detailed_data, ...
224  LU_fnames(lsi,:), params);
225  end
226  % go to next time slice
227  ti = ti + 1; something_todo = false;
228 
229  else
230  % split the time slice!
231  old_ti_indices = find(tmap == ti);
232  minold = min(old_ti_indices);
233  maxold = max(old_ti_indices);
234  new_tmap = tmap;
235 
236  slmiddle = max(floor(median(tei_info.extension_filepos)), model.minimum_time_slice);
237  slmiddle = min(slmiddle, slice_size-model.minimum_time_slice);
238  %slmiddle = floor(slice_size/2);
239 
240  if model.verbose > 11
241  disp(['Split time slice no. ', num2str(ti), ' at midpoint = ', ...
242  num2str(slmiddle) , '/', num2str(slice_size) ]);
243  end
244 
245 
246  new_tmap(minold:minold+slmiddle-1) = ti;
247  new_tmap(minold+slmiddle:maxold) = ti+1;
248  new_tmap(maxold+1:end) = tmap(maxold+1:end)+1;
249 
250  ei_detailed_data.time_split_map = [ (1:model.nt+1)', new_tmap ];
251 
252  disp(['new time split map: ', num2str(ei_detailed_data.time_split_map(:,2)')]);
253 
254  % find basis functions in first half and second half
255  fh = tei_info.extension_filepos <= slmiddle;
256  sh = ~fh;
257  if model.extend_crb
258  splitdd.QM = { ei_detailed_data.QM{lsi, ti}(:,fh), ...
259  ei_detailed_data.QM{lsi, ti}(:,sh) };
260  splitdd.TM = { ei_detailed_data.TM{lsi, ti}(fh), ...
261  ei_detailed_data.TM{lsi, ti}(sh) };
262  splitdd.BM = { ei_detailed_data.BM{lsi, ti}(fh,fh), ...
263  ei_detailed_data.BM{lsi, ti}(sh,sh) };
264  splitdd.ei_info = cell(1,2);
265  splitdd.ei_info{1,1}.max_err_sequence = [tei_info.max_err_sequence(fh);Inf];
266  splitdd.ei_info{1,2}.max_err_sequence = [tei_info.max_err_sequence(sh);Inf];
267  splitdd.ei_info{1,1}.extension_filenum = tei_info.extension_filenum(fh);
268  splitdd.ei_info{1,2}.extension_filenum = tei_info.extension_filenum(sh);
269  splitdd.ei_info{1,1}.extension_filepos = tei_info.extension_filepos(fh);
270  splitdd.ei_info{1,2}.extension_filepos = tei_info.extension_filepos(sh)-slmiddle;
271  params.skip_search = true;
272  else
273  splitdd.QM = cell(1,2);
274  splitdd.TM = cell(1,2);
275  splitdd.BM = cell(1,2);
276  splitdd.ei_info = cell(1,2);
277  splitdd.ei_info{1,1}.max_err_sequence = [];
278  splitdd.ei_info{1,2}.max_err_sequence = [];
279  splitdd.ei_info{1,1}.extension_filenum = [];
280  splitdd.ei_info{1,2}.extension_filenum = [];
281  splitdd.ei_info{1,1}.extension_filepos = [];
282  splitdd.ei_info{1,2}.extension_filepos = [];
283  end
284 
285  newQMsize = size(ei_detailed_data.QM,2) + 1;
286  ei_detailed_data.QM{lsi, newQMsize} = [];
287  ei_detailed_data.BM{lsi, newQMsize} = [];
288  ei_detailed_data.TM{lsi, newQMsize} = [];
289  ei_detailed_data.ei_info{lsi, newQMsize} = [];
290 
291  ei_detailed_data.QM(lsi, ti:end) = ...
292  {splitdd.QM{:}, ei_detailed_data.QM{lsi,ti+1:end-1}};
293  ei_detailed_data.BM(lsi, ti:end) = ...
294  {splitdd.BM{:}, ei_detailed_data.BM{lsi,ti+1:end-1}};
295  ei_detailed_data.TM(lsi, ti:end) = ...
296  {splitdd.TM{:}, ei_detailed_data.TM{lsi,ti+1:end-1}};
297  ei_detailed_data.ei_info(lsi, ti:end) = ...
298  {splitdd.ei_info{:}, ei_detailed_data.ei_info{lsi,ti+1:end-1}};
299 
300  max_time_splits = max_time_splits + 1;
301  end
302 
303  else
304  error('Generation of collateral reduced space stopped after not converging in a time slice');
305  end
306  end
307 
308  % translate file-indices of snapshots into parameter vectors:
309  ei_detailed_data.ei_info{lsi,ti-1}.extension_mus = ...
310  Mtrain( : , ...
311  mod(ei_detailed_data.ei_info{lsi,ti-1}.extension_filenum-1, ...
312  length(Mtrain) )...
313  + 1 );
314  end
315  else % no adaptation
316  params.ei_stop_epsilon = model.ei_stop_epsilon;
317  for ti = 1:model.ei_time_splits
318  params.time_index = ti;
319  ei_detailed_data = ei_detailed(model, ei_detailed_data, ...
320  LU_fnames(lsi,:), params);
321  % translate file-indices of snapshots into parameter vectors:
322  ei_detailed_data.ei_info{lsi,ti}.extension_mus = ...
323  Mtrain( : , ...
324  mod(ei_detailed_data.ei_info{lsi,ti}.extension_filenum-1, ...
325  length(Mtrain) )...
326  + 1 );
327  end
328  end
329 
330  end
331 
332 
333  case 'file_load'
334  disp('loading CRB from file for empirical interpolation');
335  tmp = load(model.CRB_basis_filename);
336  ei_detailed_data.QM = tmp.detailed_data.QM(:,1:model.Mmax);
337  ei_detailed_data.BM = tmp.detailed_data.BM(:,1:model.Mmax);
338  ei_detailed_data.TM = tmp.detailed_data.TM(1:model.Mmax);
339  ei_detailed_data.ei_info = tmp.detailed_data.ei_info;
340  if (model.Mmax~=size(tmp.detailed_data.QM,2))
341  disp(['Only extracted ',num2str(model.Mmax),' CRB-vectors from'...
342  num2str(size(tmp.detailed_data.QM,2))]);
343  end;
344  clear('tmp');
345 
346  otherwise
347  error('ei-generation mode unknown');
348 end;
349 
350 detailed_data.BM = ei_detailed_data.BM;
351 detailed_data.TM = ei_detailed_data.TM;
352 detailed_data.QM = ei_detailed_data.QM;
353 detailed_data.ei_info = ei_detailed_data.ei_info;
354 detailed_data.time_split_map = ei_detailed_data.time_split_map;
355 
356 % test Mmax on consistency, otherwise there may be problems afterwards
357 if ~isequal(model.Mmax, size(detailed_data.BM{1},2))
358  disp(['warning: Mmax in params is not the current number of generated', ...
359  ' basis vectors. Please adjust model.Mmax!']);
360 end;
361 
362 
363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
364 % simply generate reduced basis as in lin-evol case
365 
366 if model.Mstrich > 0
367  model.M = cellfun(@(x)(size(x,2) - model.Mstrich), detailed_data.BM, 'UniformOutput', true);
368 end
369 
370 detailed_data = rb_basis_generation(model,detailed_data);
371