rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
dictionary_rb_simulation.m
Go to the documentation of this file.
1 function rb_sim_data = dictionary_rb_simulation(model, ...
2  reduced_data);
3 %function rb_sim_data = dictionary_rb_simulation(model, ...
4 % reduced_data);
5 % Online rb simulation by online greedy minimizing redidual norm
6 % over dictionary, or normal RB simulation:
7 %
8 % model.rb_online_mode: 0 standard rb, no adaptivity
9 % model.rb_online_mode: 1 Delta-extended indicator for online extension
10 %
11 % B. Haasdonk 5.3.2015
12 
13 % prepare mu-dependent quantities
14 
15 rb_sim_data =[];
16 
17 old_mode = model.decomp_mode;
18 model.decomp_mode = 2; % coefficients
19 
20 tic; % measure linear combination time
21 
22 [a_coeff,f_coeff] = ...
23  model.operators(model,[]);
24 
25 AN = lincomb_sequence(reduced_data.AN_comp, a_coeff);
26 fN = lincomb_sequence(reduced_data.fN_comp, f_coeff);
27 Qf = length(f_coeff);
28 Qa = length(a_coeff);
29 N = reduced_data.N;
30 
31 % transform G matrix, such that later simple mult:
32 % G_mu matrix has <vf,vf>, <vf,va_phi_1(mu)> , <vf,va_phi_N>
33 % as first row and column, and <va_phi_i,va_phi_j(mu)> as
34 % remaining entries
35 % the following is the correct code, if lin_stat_reduced_data is
36 % passed as argument.
37 %if ~isfield(reduced_data,'used_dictionary_gen_reduced_data');
38 % Saa = kron(speye(N),sparse(1:Qa,1,a_coeff(:),Qa,1));
39 % S = [f_coeff(:), sparse([],[],[],Qf, N); ...
40 % sparse([],[],[], Qa * N, 1), Saa];
41 % G = S' * reduced_data.G * S;
42 %else
43 Hff = f_coeff' * reduced_data.bar_Hff * f_coeff;
44 af_coeff = a_coeff * f_coeff';
45 Haf = reduced_data.bar_Haf * af_coeff(:);
46 aa_coeff = a_coeff * a_coeff';
47 Haa_vec = reduced_data.bar_Haa * aa_coeff(:);
48 Haa = reshape(Haa_vec,[N,N]);
49 G = [Hff,Haf'; Haf,Haa];
50 %end;
51 G = 0.5*(G+G'); % G is positive definite.
52 diag_G = diag(G);
53 
54 t_lincomb = toc;
55 
56 %if 0
57 % disp('check, whether G has correct entries');
58 % % get full operators
59 % model.decomp_mode = 0; % complete
60 % [A ,f] = ...
61 % model.operators(model,reduced_data);
62 % K = model.get_inner_product_matrix(reduced_data);
63 % vf = K\f;
64 % G(1,1)
65 % vf'*K * vf
66 % va_phi1 = K\(A*reduced_data.RB(:,1));
67 % G(2,1)
68 % vf'*K*va_phi1
69 % G(2,2)
70 % va_phi1'*K*va_phi1
71 % keyboard;
72 %end;
73 
74 tic;
75 
76 if model.rb_online_mode == 0
77  % standard rb simulation, no online enrichment
78  uN = AN\fN;
79  % the following works with standard lin_stat_gen_reduced_data:
80  % Q_r = size(reduced_data.G,1);
81  % neg_auN_coeff = -A_coeff * uN';
82  % res_coeff = [f_coeff; neg_auN_coeff(:)];
83  % res_norm_sqr = res_coeff' * reduced_data.G * res_coeff;
84  % this is required for dictionary_gen_reduced_data:
85  res_coeff = [1;-uN];
86  res_norm_sqr = res_coeff' * G * res_coeff;
87  res_norm_sqr = max(res_norm_sqr,0);
88  res_norm = sqrt(res_norm_sqr);
89  rb_sim_data.Delta = ...
90  res_norm/model.coercivity_alpha(model);
91 
92 elseif model.rb_online_mode == 1
93  % online enrichment by eta(v) = - Delta_N(v; Phi \cup v)
94  diag_AN = diag(AN);
95 
96  %uN = ones(size(AN,1),1);
97 
98  % run iterative loop of online_greedy by minimum residual
99 
100  eps_sequence = [];
101  current_eps = 1e10; % do at least one extension
102  basis_indices = [];
103  non_basis_indices = 1:N;
104  iter = 0;
105  ANinv = [];
106  UN = zeros(0,N);
107  uN = zeros(0,1);
108 
109  % if model.RB_online_stop_Nmax == 2
110  % keyboard;
111  % end;
112 
113  if N<model.RB_online_stop_Nmax
114  model.RB_online_stop_Nmax = N;
115  disp(['warning: dictionary too small, Now decreasing RB_online_stop_Nmax']);
116  end;
117 
118  while (current_eps > model.RB_stop_epsilon) && (iter < model.RB_online_stop_Nmax)
119  % compute all new uN vectors at once:
120  a = diag_AN(non_basis_indices)';
121  bar_a = AN(basis_indices,non_basis_indices);
122  bar_bar_a = AN(non_basis_indices,basis_indices)';
123  % tilde_f = fN(non_basis_indices)' - sum(bar_bar_a.*UN,1);
124  tilde_f = fN(non_basis_indices)' - uN' * bar_bar_a;
125  ANinv_bar_a = (ANinv*bar_a);
126  tilde_a = a - sum(bar_bar_a .* ANinv_bar_a,1);
127  % UN_old = UN;
128  UN = uN * ones(1,length(non_basis_indices));
129  uN_old = uN;
130  n = length(tilde_f);
131  UN = [UN; zeros(1,length(non_basis_indices))] ...
132  + [-ANinv_bar_a;ones(1,length(non_basis_indices))] * ...
133  sparse(1:n,1:n,tilde_f./tilde_a,n,n);
134 % spdiag((tilde_f./tilde_a),length(tilde_f));
135  UN_new = UN;
136  % compute all residualnormssquare at once:
137  G11 = G([1,1+basis_indices],[1,1+basis_indices]);
138  UN1 = [ones(1,length(non_basis_indices)); - UN(1:end-1,:)];
139  UN2 = -UN(end,:);
140  G12 = G([1,1+basis_indices],1+non_basis_indices);
141  n = length(UN2);
142  % g = [G11 * UN1 + G12*spdiag(UN2(:),length(UN2)); ...
143  g = [G11 * UN1 + G12*sparse(1:n,1:n,UN2,n,n); ...
144  sum(G12 .* UN1,1) + diag_G(1+non_basis_indices)'.*UN2];
145  resnormsqr = sum([ones(1,length(non_basis_indices)); - UN] .* g,1);
146  if min(resnormsqr<-1e-2)
147  disp('error: negative residual, inspect workspace!');
148  % test for first vector:
149  keyboard;
150  end;
151  % if resnormsqr(3)>1e-10
152  % disp('error: residual for func 3 should be 0!!!');
153  % plot(resnormsqr);
154  % title('residual norms');
155  % % the following test was successful
156  % % G1 = [G11, G12(:,1); G12(:,1)', diag_G(1+1)];
157  % % g1 = G1 * [1; -UN(:,1)]
158  % % g(:,1)
159  % % resnormsqr1 = [1; -UN(:,1)]' * G1 * [1; -UN(:,1)]
160  % % resnormsqr(1)
161  % % G3 = [G11, G12(:,3); G12(:,3)', diag_G(1+3)];
162  % % resnormsqr3 = [1; -UN(:,3)]' * G3 * [1; -UN(:,3)]
163  % resnormsqr(3)
164  % keyboard;
165  % end;
166  % end;
167  % set NaN values to very high, in order not set to 0 by clipping:
168  p = find(isnan(resnormsqr));
169  resnormsqr(p) = 1e10;
170  % take positive part to avoid numerical instabilities
171  resnormsqr = max(resnormsqr,0);
172  % search maximum
173  [minresnormsqr, new_index] = min(resnormsqr);
174  % select one if multiple minima
175  current_eps = sqrt(minresnormsqr(1));
176  eps_sequence = [eps_sequence, current_eps];
177  new_index = new_index(1);
178  % remove new basis vector from search set
179  basis_indices = [basis_indices, non_basis_indices(new_index)];
180  non_basis_indices = [non_basis_indices(1:new_index-1),...
181  non_basis_indices(new_index+1:end)];
182  ANinv = inv(AN(basis_indices,basis_indices));
183  uN = UN(:,new_index);
184  UN = [UN(:,1:new_index-1),UN(:,new_index+1:end)];
185  iter = iter + 1;
186  if iter > 100
187  disp('investigate iteration')
188  % true reduced solution with selected basis vectors of previous
189  % step:
190  detailed_data = reduced_data;
191  detailed_data.RB = detailed_data.RB(:,basis_indices(1:end-1));
192  reduced_data_tmp = gen_reduced_data(model,detailed_data);
193  rb_sim_data_tmp = rb_simulation(model,reduced_data_tmp);
194  disp('correct UN old:')
195  rb_sim_data_tmp.uN
196  disp('current UN_old:')
197  uN_old
198  % UN_new(:,new_index)
199 
200  % true reduced solution with selected basis vectors:
201  detailed_data = reduced_data;
202  detailed_data.RB = detailed_data.RB(:,basis_indices);
203  reduced_data_tmp = gen_reduced_data(model,detailed_data);
204  rb_sim_data_tmp = rb_simulation(model,reduced_data_tmp);
205  disp('correct UN:')
206  rb_sim_data_tmp.uN
207  disp('current UN:')
208  uN
209  % UN_new(:,new_index)
210 
211  % recompute by hand:
212  %disp('recomputed current uN')
213  %uN_new = [uN_old; 0] + tilde_f(new_index)/tilde_a(new_index)*[-ANinv_bar_a(:,new_index);1]
214 
215  keyboard;
216  end;
217  % keyboard;
218  end;
219 
220  % return outputs
221 
222  rb_sim_data.eps_sequence = eps_sequence;
223  rb_sim_data.basis_indices = basis_indices;
224  rb_sim_data.iter = iter;
225  rb_sim_data.current_eps = current_eps;
226  rb_sim_data.Delta = ...
227  current_eps/model.coercivity_alpha(model);
228 end; % rb_online_mode
229 
230 t_solution = toc;
231 
232 rb_sim_data.uN = uN;
233 rb_sim_data.t_lincomb = t_lincomb;
234 rb_sim_data.t_solution = t_solution;
235 
236 model.decomp_mode = old_mode;
237 
function rb_sim_data = dictionary_rb_simulation(model, reduced_data)
Online rb simulation by online greedy minimizing redidual norm over dictionary, or normal RB simulati...