rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
EI.m
1 classdef EI < Greedy.Plugin.EICommon
2  % Plugin for the Greedy.Algorithm class generating a collateral reduced basis
3  % space plus interpolation DOFs and a local grid.
4  %
5  % This can be used for the empirical interpolation of parametrized functions
6  % or operator evaluations.
7 
8  properties (Hidden=true)
9  % temporary matrix generated by prepare_reduced_data()
10  A = [];
11  end
12 
13  properties (Constant)
14  generated_basis_type = 'ei';
15 
16  end
17  properties (Constant, Hidden=true)
18 
19  % cell array of field names that shall be copied to the generated
20  % Greedy.DataTree.Detailed.EILeafNode instance.
21  info_fields = { 'stop_Mmax', 'ei_target_error', 'noof_extensions', ...
22  'minimum_residual', 'enable_regularisation' };
23  end
24 
25  properties
26  % maximum number of generated collateral reduced basis vectors.
27  stop_Mmax = inf;
28 
29  % error mode for the empirical interpolation error
30  %
31  % This can be either 'interpol' or 'approx' for the true interpolation
32  % error or the projection error of the operator interpolation error in the
33  % collateral reduced basis space.
34  ei_target_error = 'approx';
35 
36  % boolean flag indicating that the error indicator which is assumed to be
37  % minimized is not equal to the ones returned by error_indicators()
38  %
39  % This is set to 'true' by the Greedy.Plugin.PODEI class.
40  target_error_external = false;
41 
42  % specifies how many collateral reduced basis functions shall be added in
43  % each extension step.
44  %
45  % This makes only sense to be set greater than '1' for trajectories, i.e.
46  % when more than one possible candidates for basis extension exist for one
47  % parameter.
48  noof_extensions = 1;
49 
50  % if the residual is below this barrier, the basis extension step is skipped.
51  %
52  % This option is only used in case of #target_error_external .
53  minimum_residual = 1e-6;
54 
55  % if this regularisation flag is set to true, the collateral reduced basis
56  % spaces are forced to have zero mean, enforcing global conservation in
57  % case of operator interpolation.
58  enable_regularisation = false;
59  end
60 
61  methods
62  function eide = EI(generator)
63  % constructor storing the snapshot generator
64  %
65  % Parameters:
66  % generator: snapshot generator of type SnapshotsGenerator.Cached.
67  eide = eide@Greedy.Plugin.EICommon(generator);
68  end
69 
70  function set.ei_target_error(this, value)
71 % if isequal(value, 'linfty-interpol')
72 % this.use_l2_error = 0;
73 % else
74 % this.use_l2_error = 1;
75 % end
76  this.ei_target_error = value;
77  end
78 
79  function detailed_data = init_basis(this, rmodel, model_data, M_train)
80  % function detailed_data = init_basis(this, rmodel, model_data, M_train)
81  % @copybrief .Greedy.Plugin.Interface.init_basis()
82  %
83  % @copydetails Greedy.Plugin.Interface.init_basis()
84  %
85  % Parameters:
86  % rmodel: of type .Greedy.User.IReducedModel
87  %
88  % Return values:
89  % detailed_data: of type .Greedy.DataTree.Detailed.EILeafNode
90  %
91  % This method initializes the detailed data node.
92  if isa(model_data, 'Greedy.DataTree.Detailed.INode')
93  detailed_data = model_data;
94  model_data = detailed_data.model_data;
95  else
96  detailed_data = Greedy.DataTree.Detailed.EILeafNode(this, model_data);
97  set_fields(detailed_data, this, Greedy.Plugin.EI.info_fields);
98  end
99  ophandle = this.generator.ophandle;
100  W = ophandle.inner_product_matrix(model_data);
101 
102  % determine initial size of vectors:
103  detailed_data.QM = zeros(size(W,1),0);
104  detailed_data.TM = zeros(0,1);
105  detailed_data.BM = zeros(0,0);
106 
107  end
108 
109  function prepare_reduced_data(this, rmodel, detailed_data)
110  % function prepare_reduced_data(this, rmodel, detailed_data)
111  % @copybrief GreedyPlugin::Interfaceprepare_reduced_data()
112  %
113  % @copydetails GreedyPlugin::Interfaceprepare_reduced_data()
114  %
115  % Parameters:
116  % rmodel: of type ::GreedyUser::IReducedModel
117  % detailed_data: of type ::GreedyDataTreeDetailed.EILeafNode
118  %
119  % This method pre-computes the normal solution matrix for
120  % `L^2`-approximation in the collateral reduced space, in case
121  % 'ei_target_error' is set to 'approx'.
122  ophandle = this.generator.ophandle;
123  if isequal(get_field(detailed_data, 'ei_target_error'), 'approx')
124  W = ophandle.inner_product_matrix(detailed_data.model_data);
125  QM = detailed_data.QM;
126  this.A = (QM' * W * QM)^(-1) * QM' * W;
127  else
128  this.A = [];
129  end
130  end
131 
132  function Uapprox = generate_reduced(this, rmodel, reduced_data, detailed_data, U)
133  % function Uapprox = generate_reduced(this, [], [], detailed_data, U)
134  % @copybrief GreedyPlugin::Interfacegenerate_reduced()
135  %
136  % @copydetails GreedyPlugin::Interfacegenerate_reduced()
137  %
138  % Parameters:
139  % rmodel: of type ::GreedyUser::IReducedModel
140  % detailed_data: of type ::GreedyUser::IDetailedData
141  % reduced_data: of type ::GreedyUser::IReducedData
142 
143  switch get_field(detailed_data, 'ei_target_error')
144  case 'approx'
145  P = this.A * U;
146  Uapprox = detailed_data.QM*P;
147  case {'interpol', 'linfty-interpol'}
148  coeff = detailed_data.BM \ U(detailed_data.TM,:);
149  Uapprox = detailed_data.QM * coeff;
150  otherwise
151  error('ei_target_error unknown!');
152  end
153  end
154 
155  function [breakloop, reason] = pre_check_for_end(this, rmodel, detailed_data)
156  % function [breakloop, reason] = pre_check_for_end(this, rmodel, detailed_data)
158  %
160  %
161  % Parameters:
162  % rmodel: of type .Greedy.User.IReducedModel
163  % detailed_data: of type .Greedy.DataTree.Detailed.EILeafNode
164  breakloop = false;
165  reason = '';
166  dd_leaf = get_active_leaf(detailed_data, rmodel);
167 
168  if length(detailed_data.TM) >= get_field(dd_leaf, 'stop_Mmax')
169  set_stop_flag(dd_leaf, 'stopped_on_max_basis_size');
170  breakloop = true;
171  reason = 'EI stopped on maximum basis size';
172  elseif stopped_on_any_child(dd_leaf, 'stopped_on_empty_extension')
173  breakloop = true;
174  reason = 'EI stopped on empty extension';
175  elseif stopped_on_all_leafs(dd_leaf, 'stopped_on_epsilon')
176  breakloop = true;
177  reason = 'EI stopped on epsilon';
178  else
179  max_errs = get_field(dd_leaf, 'max_err_sequence');
180  % check for monotonicity, but not in case of external error estimation,
181  % because this does not make any sense then.
182  if length(max_errs) > 1 && (max_errs(end)>max_errs(end-1)) ...
183  && isequal(get_field(dd_leaf, 'ei_target_error'), 'approx') ...
184  && ~this.target_error_external
185  set_stop_flag(dd_leaf, 'stopped_on_monotonicity');
186  breakloop = true;
187  reason = 'EI stopped on monotonicity';
188  end
189  end
190  end
191 
192  function detailed_data = basis_extension(this, rmodel, detailed_data, max_err_seq, mu)
193  % function detailed_data = basis_extension(this, rmodel, detailed_data, max_err_seq, mu)
194  % @copybrief GreedyPlugin::Interfacebasis_extension()
195  %
196  % @copydetails GreedyPlugin::Interfacebasis_extension()
197  %
198  % Parameters:
199  % rmodel: of type ::GreedyUser::IReducedModel
200  % detailed_data: of type ::GreedyDataTreeDetailed.EILeafNode
201  %
202  % Return values:
203  % detailed_data: of type ::GreedyDataTreeDetailed.EILeafNode
204  %
205  dmodel = rmodel.detailed_model;
206  set_mu(dmodel, mu);
207  LU = generate(this.generator, dmodel, detailed_data.model_data);
208 
209  for ext_num = 1:get_field(detailed_data, 'noof_extensions')
210  if ext_num >= 2
211  % recompute error
212  prepare_reduced_data(this, rmodel, detailed_data);
213  max_err_seq = compute_error(this, rmodel, [], detailed_data);
214  end
215 
216  [dummy, max_i] = max(max_err_seq);
217  zeta_M = LU(:,max_i(1));
218 
219  % residual
220  r_M = zeta_M;
221 
222  QM = detailed_data.QM;
223  TM = detailed_data.TM;
224  BM = detailed_data.BM;
225 
226  m = size(QM, 2);
227  %% compute interpolant
228  if (m > 0)
229 
230  % get target values in interpolation points
231  zeta_M_part = zeta_M(TM);
232 
233  % get interpolation coefficients
234  %sigma = bicgstab(BM,zeta_M_part,[],1000);
235  sigma = BM \ zeta_M_part;
236 
237  % compute residual
238  r_M = zeta_M - QM * sigma;
239  if rmodel.verbose > 1
240  disp(['positive minus negative contributions of residual (should be zero:)', num2str(sum(r_M))]);
241  disp(['positive minus negative contributions of zeta_M (should be zero:)', num2str(sum(zeta_M))]);
242  end
243 % if(sum(r_M) > 1e-4)
244 % keyboard;
245 % end
246  end;
247  max_r = max(abs(r_M));
248  if (this.target_error_external || ext_num >=2)...
249  && max_r < get_field(detailed_data, 'minimum_residual') * 10^(ext_num-1)
250 
251  disp(['skipping basis extension after ', num2str(ext_num), 'extension steps...']);
252  ext_num = ext_num - 1;
253  break;
254  end
255  t_M = find(abs(r_M) >= max_r - 1e-12, 1);
256 
257  if ~isempty(t_M)
258  if ~isempty(find(t_M(1)==TM, 1))
259  % if target error is external, this error is not immediately fatal!
260  if this.target_error_external
261  disp('skipping EIDetailed basis extension because a magic point is already selected');
262  disp('This might happen because of very bad parameter choice for ei extension.');
263  disp(['Error at twice selected point is: ', num2str(max_r)]);
264  disp('The error should be very low!');
265  ext_num = ext_num - 1;
266  break;
267  end
268  error('empirical interpolation selected magic point twice!!');
269  end
270 
271  q_M = r_M / r_M(t_M(1)); % then sign is respected short version
272  % (after verifying zero-1 structure...)
273  % BM = [BM, zeros(m-1,1) ; ...
274  % QM(t_M,:), 1 ]; % interpolation matrix mit BM(i,j) = q_j(t_i)
275  % TM = [TM; t_M]; % new vector of interpolation DOFs
276  % QM = [QM, q_M]; % new matrix of basis functions
277  if rmodel.verbose > 1
278  disp(['positive minus negative contributions of new basis function (should be zero:)', num2str(sum(q_M))]);
279  end
280  if abs(sum(q_M)) > 1e-12 && get_field(detailed_data, 'enable_regularisation')
281  subset = abs(q_M) > 1e-8;
282  if length(subset) > 10
283  q_M(subset) = q_M(subset) - sum(q_M)/length(q_M(subset));
284  end
285  if rmodel.verbose > 1
286  disp('WARNING: applied regularisation!');
287  disp(['positive minus negative contributions of new basis function (should be zero:)', num2str(sum(q_M))]);
288  end
289  end
290 
291 
292  BM = [BM, q_M(TM) ; ...
293  QM(t_M,:), q_M(t_M) ]; % interpolation matrix mit BM(i,j) = q_j(t_i)
294  TM = [TM; t_M]; % new vector of interpolation DOFs
295  QM = [QM, q_M]; % new matrix of basis functions
296 
297  detailed_data.BM = BM;
298  detailed_data.TM = TM;
299  detailed_data.QM = QM;
300 
301 
302  else
303  set_stop_flag(detailed_data, 'stopped_on_empty_extension');
304  break;
305  end
306  end
307 
308  if ext_num > 0
309  append_field(detailed_data, 'ei_ext_count', ext_num);
310  end
311 
312  end
313 
314  function cop = copy(this)
315  % function cop = copy(this)
316  % deep copy of Greedy.Plugin.EI object
317  %
318  % Return values:
319  % cop: copied object of type Greedy.Plugin.EI
320  cop = EI(this.generator);
321 
322  fnames = fieldnames(this);
323  for i=1:length(fnames)
324  cop.(fnames{i}) = this.(fnames{i});
325  end
326  end
327 
328  end
329 end
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
virtual function [ breakloop , reason ] = pre_check_for_end(Greedy.User.IReducedModel rmodel,Greedy.User.IDetailedData detailed_data)
checks whether the basis generation process has come to an end.
Interface class for extension algorithms which define the basis extension routines used by the abstra...
Definition: Interface.m:19
Greedy.Plugin.Interface implementation that extends in each basis extension step, the reduced basis space and/or the collateral reduced basis space(s).
Definition: PODEI.m:19
Interface for the storage and generation of detailed data that can be used to build reduced basis fun...
Definition: Cached.m:18
default greedy basis generation class
Definition: Algorithm.m:18
virtual function Greedy.DataTree.Detailed.INode detailed_data = init_basis(Greedy.User.IReducedModel rmodel,ModelData model_data,ParameterSampling.Interface M_train)
creates an initial detailed data node storing an initial reduced basis
Specialization plugins for the greedy algorithm.
Definition: Default.m:2
Cacheable generators of detailed data snapshots.
Definition: Cached.m:1
interface for Greedy.Plugin.Interface implementations generating an empirical interpolation basis ...
Definition: EICommon.m:19
This is the interface for a reduced model providing methods to compute low dimensional reduced simula...
Definition: IReducedModel.m:17
Plugin for the Greedy.Algorithm class generating a collateral reduced basis space plus interpolation ...
Definition: EI.m:19
Customizable implementation of an abstract greedy algorithm.
Definition: DuneRBLeafNode.m:1
Interface class for the generation and storage of offline matrices and vectors as described in Module...
Definition: IReducedData.m:17
Interface class for the generation and storage of reduced basis spaces as described in Module (M2)...
Definition: IDetailedData.m:17