rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
POD.m
1 classdef POD < Greedy.Plugin.PODCommon
2  % extension class implementing the POD-greedy algorithm extension routines
3  %
4 
5  properties(Constant)
6  % cell array of field names which shall be copied to the detailed data node
7  % structure on creation in init_basis() method.
8  info_fields = {'stop_Nmax', 'noof_pca_modes'};
9  end
10 
11  properties
12  % maximum number of generated reduced basis vectors.
13  stop_Nmax = inf;
14 
15  % number of most significant POD modes to be added to the reduced basis in
16  % each extension step.
17  %
18  % See also: basis_extension() for more information.
19  noof_pca_modes = 1;
20  end
21 
22  properties(Constant)
23  % @copybrief ::GreedyInterfacegenerated_basis_type
24  %
25  % @copydetails ::GreedyInterfacegenerated_basis_type
26  %
27  generated_basis_type = 'rb';
28  end
29 
30  methods
31 
32  function rbpcafe = POD(generator, id)
33  % function rbpcafe = POD(generator)
34  % constructor for the POD-greedy extension algorithms.
35  %
36  % Parameters:
37  % generator: object of type SnapshotsGenerator.Trajectories generating
38  % the (high dimensional) basis functions, i.e. solutions of
39  % the numerical scheme for the parametrized partial
40  % differential equation.
41 
42  rbpcafe = rbpcafe@Greedy.Plugin.PODCommon(generator);
43  end
44 
45  function detailed_data = init_basis(this, rmodel, model_data, M_train)
46  % function detailed_data = init_basis(this, rmodel, model_data, M_train)
47  % @copybrief ::GreedyPlugin::Interfaceinit_basis()
48  %
49  % @copydetails GreedyPlugin::Interfaceinit_basis()
50  %
51  % Parameters:
52  % rmodel: of type ::GreedyUser::IReducedModel
53  %
54  % Return values:
55  % detailed_data: of type ::GreedyDataTreeDetailed.RBLeafNode
56  %
57  % Computes the initial data functions for all parameters from the
58  % training set 'M_train' and initializes the reduced basis with an
59  % orthonormalization of these DOF vectors. The result is stored in a
60  % detailed data tree leaf node object.
61  if isa(model_data, 'Greedy.DataTree.Detailed.INode')
62  model_data = model_data.model_data;
63  end
64  dmodel = rmodel.detailed_model;
65  nmus = size(M_train, 1);
66  RBinit = zeros(model_data.grid.nelements, nmus);
67  for i = 1:nmus
68  dmodel = set_mu(dmodel, M_train(i,:));
69  dmodel.decomp_mode = 0;
70 
71  U0 = init_values_algorithm(dmodel, model_data);
72  RBinit(:,i) = U0;
73  end
74 
75  RBinit = orthonormalize(dmodel, model_data, RBinit);
76 
77  if size(RBinit, 2) == 0
78  RBinit = ones(size(RBinit,1),1);
79  end
80  if isstruct(model_data)
81  detailed_data = Greedy.DataTree.Detailed.RBLeafNode(model_data, this.id);
82  set_fields(detailed_data, this, Greedy.Plugin.POD.info_fields);
83  end
84  detailed_data.RB = RBinit;
85  disp(['found ',num2str(size(RBinit,2)),' basis functions for',...
86  ' init data variation.']);
87  end
88 
89  function prepare_reduced_data(this, rmodel, detailed_data)
90  % function prepare_reduced_data(this, rmodel, detailed_data)
91  % @copybrief GreedyPlugin::Interfaceprepare_reduced_data()
92  %
93  % @copydetails GreedyPlugin::Interfaceprepare_reduced_data()
94  %
95  % Parameters:
96  % rmodel: of type ::GreedyUser::IReducedModel
97  % detailed_data: of type ::GreedyDataTreeDetailedRBLeafNode
98 
99 % if isempty(this.last_detailed_data_handle_for_prepare_reduced) ...
100 % || this.last_detailed_data_handle_for_prepare_reduced ~= detailed_data
101  this.reduced_data = gen_reduced_data(rmodel, detailed_data);
102 % this.last_detailed_data_handle_for_prepare_reduced = detailed_data;
103 % end
104  end
105 
106  function Uapprox = generate_reduced(this, rmodel, reduced_data, detailed_data, U)
107  % function Uapprox = generate_reduced(this, rmodel, reduced_data, detailed_data, U)
108  % @copybrief GreedyPlugin::Interfacegenerate_reduced()
109  %
110  % @copydetails GreedyPlugin::Interfacegenerate_reduced()
111  %
112  % Parameters:
113  % rmodel: of type ::GreedyUser::IReducedModel
114  % detailed_data: of type ::GreedyUser::IDetailedData
115  % reduced_data: of type ::GreedyUser::IReducedData
116  if isempty(reduced_data)
117  error('prepare_reduced_data() may need to be executed before generate_reduced()!');
118  end
119  rmodel.N = get_rb_size(detailed_data);
120  rmodel.M = get_ei_size(detailed_data) - rmodel.Mstrich;
121 
122  rb_sim_data = rb_simulation(rmodel, reduced_data);
123  rb_sim_data = rb_reconstruction(rmodel, detailed_data, rb_sim_data);
124  Uapprox = rmodel.get_dofs_from_sim_data(rb_sim_data);
125  end
126 
127  function [max_errs, max_err_sequence, max_mu_index] = ...
128  error_estimators(this, rmodel, detailed_data, M_train)
129  % function [max_errs, max_err_sequence, max_mu_index] = error_estimators(this, rmodel, detailed_data, M_train)
130  % @copybrief GreedyPlugin::Defaulterror_estimators()
131  %
132  % @copydetails GreedyPlugin::Defaulterror_estimators()
133  %
134  % Parameters:
135  % rmodel: of type ::GreedyUser::IReducedModel
136  % detailed_data: of type ::GreedyUser::IDetailedData
137  %
138  % The estimator `\eta_{N,M,M'}` used here is described in @ref DHO11
139  % "[DHO11], Chapter 5".
140  %
141  nmus = size(M_train, 1);
142 
143  tmp_max_errs = cell(nmus, 1);
144  tmp_max_err = zeros(nmus, 1);
145 
146  reduced_data = this.reduced_data;
147  if rmodel.crb_enabled
148  if isa(reduced_data.M, 'DataTree.INode')
149  rmodel.M = create_scalar_tree(reduced_data.M, @(x) get(x,1) - rmodel.Mstrich);
150  else
151  rmodel.M = reduced_data.M - rmodel.Mstrich;
152  end
153  end
154 
155  if ~FakeMPI.MPI_IsActive
156  ME.message = '';
157  parfor i = 1:nmus
158  %for i = 1:nmus
159  trmodel = rmodel;
160  if trmodel.verbose >= 5
161  fprintf('.');
162  end
163  set_mu(trmodel, M_train(i,:));
164  try
165  sim_data = rb_simulation(trmodel, reduced_data);
166  tmp_max_errs{i} = trmodel.get_estimators_from_sim_data(sim_data);
167  tmp_max_err(i) = max(tmp_max_errs{i});
168  catch ME
169  tME = ME;
170  warning('RBmatlab:simulation_error', ...
171  ['Method rb_simulation threw an error: ', tME.message]);
172  tmp_max_errs{i} = NaN;
173  tmp_max_err(i) = NaN;
174  end
175  end
176  fprintf('\n');
177  else
178  buf.reduced_data = reduced_data;
179  buf.rmodel = rmodel;
180  buf.M_train = M_train;
181  FakeMPI.MPI_Deploy(buf);
182  buf = [];
183 
184  min_mu = 0;
185  nnodes = min(FakeMPI.MPI_Size, nmus-min_mu);
186  width = max((nmus-min_mu)/(2*nnodes),1);
187 
188  ids = 1:nnodes;
189  bufs = cell(1,nnodes);
190  for id=1:nnodes
191  bufs{id}.st = round((id-1)*width)+1+min_mu;
192  bufs{id}.en = min(round(id*width)+min_mu, nmus);
193 % disp(['Send: id = ', num2str(id), ' st = ', num2str(buf.st), ' en = ', num2str(buf.en)]);
194  end
195  FakeMPI.MPI_Send(ids, bufs);
196  min_mu = bufs{end}.en;
197 
198  running=true(1,nnodes);
199  countdown = 0;
200 
201  pause(0.5);
202 
203  while (any(running))
204  probed_ids = FakeMPI.MPI_Probe('*');
205  id_mask = find(running);
206  for id=intersect(probed_ids, id_mask)
207  ret_struct = FakeMPI.MPI_Recv(id);
208  try
209  st = ret_struct.st;
210  en = ret_struct.en;
211  assert(bufs{id}.st == st)
212  assert(bufs{id}.en == en)
213  tmp_max_errs(st:en) = ret_struct.tmp_max_errs(:);
214  tmp_max_err(st:en) = ret_struct.tmp_max_err(:);
215  catch exception
216  disp('received corrupt data');
217  disp(exception.message);
218  disp('resend this job');
219  FakeMPI.MPI_ReDeploy(id);
220  FakeMPI.MPI_Send(id, bufs{id});
221  pause(0.05);
222  continue;
223  end
224  if min_mu < nmus
225  if countdown == 0
226  width = max((nmus-min_mu)/(2*nnodes), 1);
227  countdown = nnodes;
228  end
229  buf.st = min_mu + 1;
230  buf.en = min(min_mu + round(width), nmus);
231  bufs{id} = buf;
232 % disp(['Send: id = ', num2str(id), ' st = ', num2str(buf.st), ' en = ', num2str(buf.en)]);
233  FakeMPI.MPI_ReDeploy(id);
234  FakeMPI.MPI_Send(id, buf);
235  pause(0.05);
236  min_mu = buf.en;
237  countdown = countdown - 1;
238  else
239  running(id) = 0;
240  disp(['stopped parCompErrs #', num2str(id)]);
241  end
242  end
243  pause(0.05);
244  end
245  if getenv('PBS_JOBID')
246  pause(0.5);
247  end
248 
249  end
250 
251  [dummy, max_mu_index] = max(tmp_max_err);
252  max_errs = tmp_max_err;
253  max_err_sequence = tmp_max_errs{max_mu_index};
254  end
255 
256  function [breakloop, reason] = pre_check_for_end(this, rmodel, detailed_data)
257  % function [breakloop, reason] = pre_check_for_end(this, rmodel, detailed_data)
258  % @copybrief Greedy.Plugin.Interface.pre_check_for_end()
259  %
260  % @copydetails Greedy.Plugin.Interface.pre_check_for_end()
261  %
262  % Parameters:
263  % rmodel: of type .Greedy.User.IReducedModel
264  % detailed_data: of type .Greedy.DataTree.Detailed.RBLeafNode
265 
266  dd_leaf = get_active_leaf(detailed_data, rmodel);
267  reason = '';
268  breakloop = false;
269  if stopped_on_active_child(detailed_data, 'stopped_on_empty_extension', rmodel)
270  breakloop = true;
271  reason = 'RB extension stopped on empty extension';
272  elseif size(detailed_data.RB, 2) >= get_field(dd_leaf, 'stop_Nmax')
273  set_stop_flag(dd_leaf, 'stopped_on_max_basis_size');
274  breakloop = true;
275  reason = 'RB extension reached maximum basis size';
276  end
277  end
278 
279 
280 % breakloop = post_check_for_end(this, detailed_data);
281 
282  function ret_detailed_data = basis_extension(this, rmodel, detailed_data, max_err_seq, mu)
283  % function ret_detailed_data = basis_extension(this, rmodel, detailed_data, max_err_seq, mu)
284  % @copybrief Greedy.Plugin.Interface.basis_extension()
285  %
286  % @copydetails Greedy.Plugin.Interface.basis_extension()
287  %
288  % Parameters:
289  % rmodel: of type .Greedy.User.IReducedModel
290  % detailed_data: of type .Greedy.DataTree.Detailed.RBLeafNode
291  %
292  % Return values:
293  % detailed_data: of type .Greedy.DataTree.Detailed.RBLeafNode
294  %
295  % Implementation details:
296  %
297  % - This method computes first POD modes of this sequence of discrete
298  % functions and adds them to the reduced basis space.
299  % - The number of POD modes used can be specified by the #noof_pca_modes
300  % property.
301  % - The POD is computed by the PCA_fixspace() function.
302 
303  % extend rb basis if you receive rbeidetailedata
304  if isa(detailed_data, 'Greedy.DataTree.Detailed.PODEILeafNode')
305  ret_detailed_data = detailed_data;
306  detailed_data = ret_detailed_data.rb;
307  else
308  ret_detailed_data = detailed_data;
309  end
310  model_data = detailed_data.model_data;
311  max_err = max(max_err_seq);
312  disp(['Detected maximum error prediction ',num2str(max_err),...
313  ' for mu=[',...
314  num2str(mu),']']);
315 
316  dmodel = rmodel.detailed_model;
317  set_mu(dmodel, mu);
318  U = generate(this.generator, dmodel, model_data);
319 
320  cur_stop_Nmax = get_field(detailed_data, 'stop_Nmax');
321  cur_noof_pca_modes = get_field(detailed_data, 'noof_pca_modes');
322  pca_modes = min(cur_noof_pca_modes, cur_stop_Nmax - size(detailed_data.RB,2));
323  W = dmodel.get_inner_product_matrix(model_data);
324  RBext = PCA_fixspace(U, detailed_data.RB,...
325  W, pca_modes);
326  if ~isempty(RBext)
327  RB = [detailed_data.RB, RBext];
328  % RBo = model_orthonormalize_qr( dmodel.descr, model_data, RB, eps );
329  % K = inner_product(dmodel, model_data, RBo, RB);
330  % [dummy,i] = max(abs(K));
331  % RB = RBo(:,i);
332  % if model.debug
333  % K = rb_engine.inner_product(model,detailed_data, RB, RB);
334  % if max(max(abs(K-eye(size(K)))))>1e-10
335  % error('error in orthonormal basis extension!');
336  % end
337  % end
338  detailed_data.RB = RB;
339  N = size(detailed_data.RB, 2);
340  disp(['Extended RB to length ', num2str(N)]);
341  else
342  set_stop_flag(detailed_data, 'stopped_on_empty_extension');
343  %! \todo Remember to catch this one in the container above when
344  % combining eidetailed and pod-greedy!!!!
345  end
346  end
347  end
348 end
349 
Interface class for extension algorithms which define the basis extension routines used by the abstra...
Definition: Interface.m:19
DataTree implementation for generated detailed and reduced data
Definition: DuneRBLeafNode.m:2
tree node implementation for a detailed data structure holding a reduced basis and a collateral reduc...
Definition: PODEILeafNode.m:20
Interface for a node in a DataTree.
Definition: INode.m:18
DataTree specialization for detailed data generated by a Greedy algorithm instance.
Definition: DuneRBLeafNode.m:3
extension class implementing the POD-greedy algorithm extension routines
Definition: POD.m:19
Definition: leaf.m:17
Specialization plugins for the greedy algorithm.
Definition: Default.m:2
Cacheable generators of detailed data snapshots.
Definition: Cached.m:1
This is the interface for a reduced model providing methods to compute low dimensional reduced simula...
Definition: IReducedModel.m:17
Default implementation of a Greedy.Plugin.Interface interface class.
Definition: Default.m:19
Customizable implementation of an abstract greedy algorithm.
Definition: DuneRBLeafNode.m:1
interface for Greedy.Plugin.Interface implementations generating an reduced basis space for parametri...
Definition: PODCommon.m:19
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