rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
riccati_gen_detailed_data.m
1 function detailed_data = riccati_gen_detailed_data(model, model_data)
2 %function detailed_data = riccati_gen_detailed_data(model, model_data)
3 %
4 % function generates the reduced basis
5 % the result is stored in the detailed_data
6 %
7 % This function generates the following data structure:
8 % detailed_data.
9 % RB The reduced basis
10 % RB_info Information about the basis
11 %
12 % Andreas Schmidt, 2015
13 %
14 snapshots = [];
15 training_mus = {};
16 chosen_mu = [];
17 
18 if ~isfield(model, 'RB_generation_mode')
19  error(['Please specify model.RB_generation_mode '])
20 end
21 
22 mode = model.RB_generation_mode;
23 dsim_mode = 'riccati';
24 
25 switch mode
26  case 'greedy_uniform_fixed'
27  if ~isfield(model, 'RB_numintervals')
28  error('Please specify model.RB_numintervals')
29  end
30  mu_ranges = model.mu_ranges;
31  par.numintervals = model.RB_numintervals*ones(length(mu_ranges),1);
32  par.range = model.mu_ranges;
33  MMesh0 = cubegrid(par);
34  training_mus = get(MMesh0, 'vertex');
35  algorithm = @greedy;
36  case 'greedy_fixed'
37  if ~isfield(model, 'training')
38  error('Please specify model.training')
39  end
40  training_mus = model.training;
41  algorithm = @greedy;
42  case 'greedy_rand'
43  training_mus = rand_uniform(model.RB_samplepoints, model.mu_ranges)';
44  algorithm = @greedy;
45  case 'greedy_rand_log'
46  training_mus = rand_log(model.RB_samplepoints, model.mu_ranges)';
47  algorithm = @greedy;
48  case 'pod'
49  algorithm = @greedy;
50  dsim_mode = 'pod';
51  training_mus = rand_uniform(model.RB_samplepoints, model.mu_ranges)';
52 
53  otherwise
54  error('Basis generation mode unknown')
55 end
56 detailed_data = algorithm(model, model_data, training_mus, dsim_mode);
57 
58 end
59 
60 
61 
62 %% First version: Greedy for detailed system
63 function detailed_data = greedy(model, model_data, training_mus, varargin)
64 % Implementation of the greedy algorithm
65  RB_info.M_train = training_mus;
66 
67  bgenStart = tic;
68  % Outer tolerance
69  o_tol = 10e-6;
70  if isfield(model, 'RB_o_tol')
71  o_tol = model.RB_o_tol;
72  end
73  RB_info.o_tol = o_tol;
74 
75  % Errors (dummy values set for initial calculation)
76  errors = ones(size(training_mus, 1), 1);
77 
78  % The reduced basis will be stored here:
79  RB = [];
80 
81  % History of the error decay over the whole parameter domain:
82  error_history = {};
83  chosen_mu = [];
84 
85  % Maximum error decay:
86  error_decay = [Inf];
87 
88  % The sizes of the low rank factors
89  Z_sizes = [];
90 
91  % Number of inner iterations
92  inner_elements_added = [];
93 
94  i = 1;
95  z0 = 0;
96  Z = cell(size(training_mus,1));
97 
98  % For the detailed simulation time
99  dsim_times = [];
100 
101  mode = 'riccati';
102  if nargin > 3
103  mode = varargin{1};
104  end
105 
106  % Adaptive algorithm or fixed-1 ?
107  basis_extension_mode = model.RB_extension_mode;
108  addmultiple = false;
109  if strcmp(basis_extension_mode, 'addmultiple')
110  addmultiple = true;
111  i_tol = 0.8;
112  if isfield(model, 'RB_i_tol')
113  i_tol = model.RB_i_tol;
114  end
115  maxperstep = model.RB_extension_max_per_step;
116  RB_info.i_tol = i_tol;
117  end
118  RB_info.addmultiple = addmultiple;
119  [E,~,~,~] = riccati_assemble_system_matrices(model,model_data);
120 
121  while max(errors) > o_tol
122  display(['LRFG, Iteration ', num2str(i)])
123 
124  if isempty(RB)
125  % Use the first element in the training set for the
126  % initalization of the basis
127  theta = 1;
128  maxErr = Inf;
129  else
130  % Select the worst approximated element
131  [maxErr, theta] = max(errors);
132  end
133 
134  display([' - Element ', num2str(theta), ' with error ', num2str(maxErr)])
135 
136  % Save the error decay
137  chosen_mu = [chosen_mu theta];
138 
139  % Copy the model temporarily and perform a detailed simulation to
140  % get the new Low Rank factor Z and cache it in the cell Z
141  display(' - Getting detailed simulation')
142  if isempty(Z{theta})
143  mu = training_mus(theta,:);
144  tmpModel = set_mu(model, mu);
145 
146  tStart = tic;
147  if strcmp(mode, 'riccati')
148  dsim = detailed_simulation(tmpModel, model_data);
149  elseif strcmp(mode, 'pod')
150  snapshots = [];
151  [E,A,~,C] = riccati_assemble_system_matrices(tmpModel, model_data);
152  parfor l = 1:size(C,1)
153  c = C(l,:)';
154  options = odeset('Jacobian', A, 'Mass', E');
155  [T,Y] = ode23s( @(t,x) (A'*x), [0,5], E\c, options);
156  snapshots = [snapshots Y'];
157  end
158  dsim.Z = snapshots;
159  else
160  error('Detailed data generation mode not known')
161  end
162  dsim_times = [dsim_times toc(tStart)];
163 
164  Z{theta} = dsim.Z;
165  end
166  thisZ = Z{theta};
167 
168  Z_sizes = [Z_sizes size(thisZ,2)];
169  display([' - Low rank factor has ', num2str(size(thisZ,2)), ' elements'])
170  if z0 == 0
171  z0 = norm(thisZ(:,1));
172  end
173 
174  % Extend the basis, i.e. run the inner greedy loop
175  %[RB,c,ierror,newZ] = riccati_greedy_extend_basis(RB,thisZ,itol,z0);
176  if length(RB) > 0
177  thisZ = thisZ - RB*(RB'*thisZ);
178  end
179 
180  if ~addmultiple
181  [Vextend,S,~] = svds(thisZ,1);
182  else
183  [Vextend,S,~] = svd(thisZ,'econ');
184  S = diag(S).^2;
185  sumS = sum(S);
186 
187  for i = 1:length(diag(S))
188  E = 1 - sum(S(1:i))/sumS;
189  if E < i_tol || i == maxperstep
190  break
191  end
192  end
193  Vextend = Vextend(:, 1:i);
194  end
195 
196  c = size(Vextend, 2);
197  ierror = max(diag(S));
198 
199  % Just make sure the basis is orthogonal in cases where numerical
200  % errors occur:
201  RB = orthonormalize_gram_schmidt([RB Vextend]);
202 
203  inner_elements_added = [inner_elements_added c];
204 
205  display([' - Added ', num2str(c), ' new basis vectors']);
206  display([' - New basis size: ', num2str(size(RB,2))]);
207 
208  % Only recalculate if elements have been added
209  % If no elements were added the same error bound can be used again
210  if c>0
211  display(' - Recalculating errors')
212  errors = greedy_calc_errors(model, RB, training_mus);
213  end
214 
215  last_error = error_decay(end);
216  error_decay = [error_decay max(errors)];
217  error_history{i} = errors;
218 
219  i = i + 1;
220  end
221  RB_info.basisgen_runtime = toc(bgenStart);
222 
223  detailed_data.RB = RB;
224 
225  % Start gamma procedure:
226  gamma_mode = model.RB_gamma_mode;
227  gamma.mode = gamma_mode;
228  gamma_timer = tic;
229  % Check the mode for gamma:
230  if strcmp(gamma_mode, 'max')
231  error('To implement')
232  elseif strcmp(gamma_mode, 'kernel_interpolation')
233  greedy_interpol_count = 100;
234  if isfield(model, 'RB_gamma_samplesize')
235  greedy_interpol_count = model.RB_gamma_samplesize;
236  end
237  mus = rand_uniform(greedy_interpol_count, model.mu_ranges)';
238  greedy_gammas = zeros(greedy_interpol_count, 1);
239  runtimes = zeros(greedy_interpol_count,1);
240  parfor_progress(size(mus,1));
241  parfor i = 1:size(mus, 1)
242  mu = mus(i,:);
243  tmpModel = set_mu(model, mu);
244  dsim = detailed_simulation(tmpModel, model_data);
245  gamma_timing = tic;
246  greedy_gammas(i) = riccati_gamma(tmpModel, model_data, dsim);
247  runtimes(i) = toc(gamma_timing);
248  parfor_progress
249  end
250 
251  gamma.interpol_mus = mus;
252  gamma.interpol_gammas = greedy_gammas;
253  gamma.kernel = 'gauss';
254  gamma.runtimes = runtimes;
255  elseif strcmp(gamma_mode, 'interpol')
256  detailed_data.gamma_mode = 'interpol';
257  display('Starting calculation of gamma values')
258 
259  % Build the mu-grid:
260  Nmu = 6;
261  ranges = model.mu_ranges;
262 
263  mug = cell(1,length(ranges));
264  for j = 1:length(ranges)
265  mug{j} = linspace(ranges{j}(1), ranges{j}(2), Nmu);
266  end
267  mu_grid = cell(1,numel(mug));
268 
269  [mu_grid{:}] = ndgrid(mug{:});
270  gamma_values = zeros(size(mu_grid{1}));
271  parfor_progress(numel(mu_grid{1}));
272  reduced_data = gen_reduced_data(model, detailed_data);
273 
274  parfor k = 1:numel(mu_grid{1})
275  mu = zeros(length(ranges),1);
276  for j = 1:length(ranges)
277  mu(j) = mu_grid{j}(k);
278  end
279 
280  tmpModel = set_mu(model, mu);
281  sim = rb_reconstruction(tmpModel, detailed_data, rb_simulation(tmpModel, reduced_data));
282  gamma_values(k) = riccati_gamma(tmpModel, model_data, sim);
283 
285  end
286  parfor_progress(0);
287 
288  gamma.values = gamma_values;
289  gamma.mu_grid = mu_grid;
290  gamma.interpolant = griddedInterpolant( mu_grid{:}, gamma_values, 'linear' );
291  end
292  detailed_data.gamma = gamma;
293  RB_info.gamma_runtime = toc(gamma_timer);
294 
295  % Fill the structure with all information from the basis building
296  % process.
297  inner.Z_sizes = Z_sizes;
298  inner.iterations = inner_elements_added;
299  RB_info.inner = inner;
300 
301  outer.error_decay = error_decay;
302  outer.chosen_mu = chosen_mu;
303  outer.tol = o_tol;
304  outer.dsim_timings = dsim_times;
305  RB_info.outer = outer;
306 
307  detailed_data.RB_info = RB_info;
308 end
309 
310 % Calculate the errors for the basis stored in the matrix RB
311 function [errs, avg_time] = greedy_calc_errors(model, RB, training_mus)
312  errs = zeros(size(training_mus,1),1);
313  dd.RB = RB;
314  dd.tol = 10e-12;
315  rd = gen_reduced_data(model, dd);
316  t = tic;
317  parfor i = 1:size(training_mus,1)
318  tmpModel = model;
319  tmpModel = set_mu(tmpModel, training_mus(i, :));
320 
321  rsim = rb_simulation(tmpModel, rd);
322  errs(i) = rsim.P_residual_normalized;
323  end
324  avg_time = toc(t);
325 end
A hierarchical cubegrid of arbitrary dimension.
Definition: cubegrid.m:17
function [ E , A , B , C , x0 ] = riccati_assemble_system_matrices(model, model_data)
model_data)
function percent = parfor_progress(N)
PARFOR_PROGRESS Progress monitor (progress bar) that works with parfor. PARFOR_PROGRESS works by crea...
function gamma = riccati_gamma(model, model_data, sim)
This function calculates gamma. Simdata must be a high dimensional solution.
Definition: riccati_gamma.m:17
Customizable implementation of an abstract greedy algorithm.
Definition: DuneRBLeafNode.m:1