rbmatlab  1.13.10
 All Classes Namespaces Files Functions Variables Groups Pages
EiReducedDataNode.m
1 classdef EiReducedDataNode < Greedy.User.IReducedDataNode
2  % Implementation of a Greedy.User.IReducedDataNode storing reduced data
3  % depending on collateral reduced basis space information only (e.g.
4  % interpolation DOFs and a local grid).
5 
6  properties
8  %
10  BM;
11 
13  %
15  grid_local_ext;
16 
18  %
20  TM_local;
21 
23  %
25  TM_global;
26 
28  %
30  Mmass;
31 
33  %
35  Mstrich = 0;
36 
37  factor = 0;
38  end
39 
40  properties (SetAccess = private, Dependent)
42  %
44  M;
45 
47  %
49  grid;
50  end
51 
52  methods
53  function rd = EiReducedDataNode(rmodel, detailed_data)
54  % function rd = EiReducedDataNode(rmodel, detailed_data)
55  % constructor for the generation of the reduced data.
56  %
57  % Parameters:
58  % rmodel: of type NonlinEvol.ReducedModel
59  % detailed_data: of type IDetailedData
60  %
61  % Alternative synopsis:
62  % @code EiReducedDataNode(rmodel, ei_reduced_data_node) @endcode copying
63  % a reduced data node and (optionally) extracting smaller matrices.
64  if nargin == 0
65  error('NonlinEvol.EiReducedDataNode constructor needs an argument');
66  elseif nargin == 2 && isa(rmodel, 'IReducedModel') ...
67  && isa(detailed_data, 'NonlinEvol.EiReducedDataNode')
68  copy = detailed_data;
69  copy_extract(rd, copy, rmodel);
70  elseif nargin == 2
71  fill_fields(rd, rmodel, detailed_data);
72  else
73  error('Did not find constructor for your arguments');
74  end
75  end
76 
77  function conds = get_conds(this)
78  if ~isempty(this.Mmass)
79  conds.Mmass = condest(this.Mmass);
80  end
81  if ~isempty(this.BM)
82  conds.BM = condest(this.BM);
83  end
84  end
85  function grid = get.grid(this)
86  grid = this.grid_local_ext;
87  end
88 
89  function M = get.M(this)
90  M = size(this.BM, 2) - this.Mstrich;
91  end
92 
93  function yesno = needs_subset_copy(this, rmodel)
94  % function yesno = needs_subset_copy(this, rmodel)
95  % @copybrief .Greedy.User.IReducedDataNode.needs_subset_copy()
96  %
97  % @copydetails .Greedy.User.IReducedDataNode.needs_subset_copy()
98  %
99  % Parameters:
100  % rmodel: of type NonlinEvol.ReducedModel
101  yesno = this.M ~= rmodel.M || this.Mstrich ~= rmodel.Mstrich;
102  end
103 
104  end
105  methods(Access=private)
106 
107  function fill_fields(this, rmodel, detailed_data)
108  model_data = detailed_data.model_data;
109  A = model_data.W;
110  grid = model_data.grid;
111 
112  this.BM = detailed_data.BM;
113  if rmodel.verbose > 11
114  disp(['stencil mode: ' , rmodel.stencil_mode]);
115  disp(['stencil size: ' , num2str(rmodel.local_stencil_size)]);
116  end
117 
118  eind = compute_TM_global(this, grid, detailed_data.TM, rmodel);
119 
120  this.TM_global = eind;
121 
122  if isa(grid,'rectgrid') || isa(grid,'triagrid') || isa(grid,'onedgrid')
123  this.grid_local_ext = gridpart(grid,eind);
124  % else % e.g. struct, or not required local grid:
125  % disp('please gen nice grid class for 1d grid...')
126  % reduced_ei_data.grid_local_ext{oi} = onedgrid_gridpart(grid,eind);
127  % keyboard;
128  end
129  glob2loc = zeros(grid.nelements,1);
130  glob2loc(eind) = 1:length(eind);
131  this.TM_local = glob2loc(detailed_data.TM);
132 
133  this.Mmass = detailed_data.QM' * A * detailed_data.QM;
134  end
135 
136  function copy_extract(this, reduced_data, rmodel)
137  MM = rmodel.M + rmodel.Mstrich;
138  if MM > reduced_data.M + reduced_data.Mstrich
139  error('M and M'' too large for current size of reduced basis!');
140  end
141 
142  grid = reduced_data.grid_local_ext;
143 
144  % new version with external routine index_ext:
145  eind = compute_TM_global(this, grid, reduced_data.TM_local(1:MM), rmodel);
146  this.TM_global = eind;
147  this.grid_local_ext = gridpart(grid,eind);
148 
149  glob2loc = zeros(grid.nelements,1);
150  glob2loc(eind) = 1:length(eind);
151  this.TM_local = glob2loc(reduced_data.TM_local(1:MM));
152  this.BM = reduced_data.BM(1:MM,1:MM);
153  this.Mmass = reduced_data.Mmass(1:MM,1:MM);
154 
155  % get Q^t W Q for M to M+M'
156  if rmodel.Mstrich > 0
157  QWQ = this.Mmass(rmodel.M+1:end,MM);
158  this.factor = norm(QWQ);
159  else
160  this.factor = NaN;
161  end
162  end
163  end
164 
165  methods (Access = public)
166  function eind = compute_TM_global(this, grid, TM, rmodel)
167  if isequal(rmodel.stencil_mode, 'vertex')
168  mask = zeros(1, grid.nelements);
169  nbi = grid.NBI(TM,:);
170  i = find(nbi > 0);
171  % get indices of TM's neighbour-neighbours
172  nnbi = grid.NBI(unique(nbi(i)),:);
173  ni = find(nnbi > 0);
174  [nnbuniq,tally] = unique(sort(nnbi(ni)),'first');
175  tally = [tally(2:end);length(nnbi(ni))+1] - tally;
176  mask(nnbuniq) = tally;
177  mask(nbi(i)) = 5;
178  mask(TM) = 6;
179  mask(mask < 2) = 0; % skip the elements which have no vertex with the
180  % given elements in TM in common
181  eind = find(mask);
182  else
183  eind = index_ext(grid, TM, rmodel.local_stencil_size);
184  end
185 
186  end
187  end
188 end