rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
lin_evol_opt_detailed_der_simulation.m
1 function sim_data = lin_evol_opt_detailed_der_simulation(model,model_data)
2 %function sim_data = lin_evol_opt_detailed_der_simulation(model,model_data)
3 %
4 % Function performing a detailed simulation and calculating the derivative
5 % solution with respect to all parameters.
6 % required fields of model:
7 % T : final time
8 % nt : number of time-intervals until T, i.e. nt+1
9 % solution slices are computed
10 % init_values_algorithm: name of function for computing the
11 % initvalues-DOF with arguments (grid, params)
12 % example: init_values_cog
13 % operators_algorithm: name of function for computing the
14 % L_E,L_I,b-operators with arguments (grid, params)
15 % example operators_conv_diff
16 % data_const_in_time : if this optional field is 1, the time
17 % evolution is performed with constant operators,
18 % i.e. only the initial-time-operators are computed
19 % and used throughout the time simulation.
20 % compute_output_functional: flag indicating, whether output
21 % functional is to be computed
22 %
23 % compute_derivative_info: flag if derivative information shall be
24 % calculated or not
25 %
26 % return fields of sim_data:
27 % U : sequence of DOF vectors
28 % y : sequence of output functional values (if activated)
29 %
30 % Markus Dihlmann 15.10.10
31 
32 if model.verbose >= 9
33  disp('entered detailed simulation ');
34 end;
35 
36 if isempty(model_data)
37  model_data = gen_model_data(model);
38 end;
39 
40 if ~isfield(model,'compute_derivative_info')
41  model.compute_derivative_info = 0;
42 end
43 
44 
45 model.decomp_mode = 1; % == components;
46 model.t = 0;
47 
48 
49 if ~isfield(model,'optimization')
50  disp('Model has no field optimization.')
51  model.optimization =[];
52 end
53 
54 
55 if isfield(model.optimization,'params_to_optimize')
56  indx_mu_i = find(model.optimization.params_to_optimize); %indexes i of \mu_i for which derivative information is needed
57 else
58  indx_mu_i = 1:length(get_mu(model));
59 end
60 nr_indx_mu_i= length(indx_mu_i); %nr of parameters to be optimized
61 %nr_derivatives = size(model.optimization.params_to_optimize,2); %total nr of parameters in the model
62 
63 
64 
65 if isfield(model,'save_time_indices')
66  save_time_index = zeros(1,model.nt+1);
67  save_time_index(model.save_time_indices(:)+1) = 1;
68  save_time_indices = find(save_time_index==1)-1;
69 else
70  save_time_index = ones(1,model.nt+1);
71  save_time_indices = 1:(model.nt+1);
72 end;
73 
74 % initial values by midpoint evaluation
75 U0_comp = model.init_values_algorithm(model,model_data);
76 
77 model.decomp_mode=2; %==> coefficients
78 U0_coeff = model.init_values_algorithm(model, model_data);
79 if model.compute_derivative_info
80  U0_der_coeff = model.rb_derivative_init_values_coefficients(model);
81 end
82 
83 %assembling initial values true solution
84 Ut = lincomb_sequence(U0_comp,U0_coeff);
85 
86 %assembling initial values derivative solution
87 if model.compute_derivative_info
88 Ut_der = zeros(length(Ut),nr_indx_mu_i);
89 for i=1:nr_indx_mu_i
90  Ut_der(:,i) = lincomb_sequence(U0_comp, U0_der_coeff(indx_mu_i(i),:)');
91 end
92 
93 U_der=cell(nr_indx_mu_i,1);
94 for i=1:nr_indx_mu_i
95  U_der{i} = sparse(length(Ut), length(save_time_indices));
96 end
97 
98 
99 end
100 
101 
102 U = sparse(length(Ut),length(save_time_indices));
103 
104 
105 time_indices = zeros(1,length(save_time_indices));
106 time = zeros(1,length(save_time_indices));
107 model.dt = model.T/model.nt;
108 %operators_required = 1;
109 if ~isfield(model,'data_const_in_time')
110  model.data_const_in_time = 0;
111 end,
112 
113 % get operator components
114 if model.affinely_decomposed
115  old_decomp_mode = model.decomp_mode;
116  model.decomp_mode = 1;
117  [L_I_comp, L_E_comp, b_comp] = model.operators_ptr(model, model_data);
118  model.decomp_mode = old_decomp_mode;
119 end;
120 
121 t_column = 1; % next column index to be filled in output
122 t_ind = 0; % t_ind between 0 and nt
123 t = 0; % absolute time between 0 and T
124 
125 % store init data
126 if save_time_index(t_ind+1)
127  U(:,t_column) = Ut;
128  if model.compute_derivative_info
129  for i=1:nr_indx_mu_i
130  U_der{i}(:,t_column) = Ut_der(:,i);
131  end
132  end
133  time_indices(t_column) = t_ind;
134  time(t_column) = t;
135  t_column = t_column + 1;
136 end;
137 
138 if ~isfield(model,'compute_output_functional')
139  model.compute_output_functional = 0;
140 end,
141 
142 %model.plot(U0,model_data.grid,params);
143 
144 %allocate memory for derivation matrices:
145 L_E_derived = cell(nr_indx_mu_i,1);
146 L_I_derived = cell(nr_indx_mu_i,1);
147 b_derived = cell(nr_indx_mu_i,1);
148 
149 % loop over fv-steps
150 for t_ind = 1:model.nt
151  t = (t_ind-1)*model.dt;
152  if model.verbose >= 10
153  disp(['entered time-loop step ',num2str(t_ind)]);
154  end;
155  if model.verbose == 9
156  fprintf('.');
157  end;
158  % get matrices and bias-vector
159 
160  if (t_ind==1)||(~model.data_const_in_time)%operators_required
161 
162  model.t = t;
163 
164  % new assembly in every iteration
165  if ~model.affinely_decomposed
166  [L_I, L_E, b] = model.operators_ptr(model, model_data);
167  else
168  % or simple assembly based on affine parameter decomposition
169  % => turns out to be slower for few components
170 
171  % test affine decomposition
172  if model.debug
173  disp('test affine decomposition of operators')
174  test_affine_decomp(model.operators_ptr,3,1,model,model_data);
175  disp('OK')
176  end;
177  model.decomp_mode = 2;
178  [L_I_coeff, L_E_coeff, b_coeff] = model.operators_ptr(model, ...
179  model_data);
180  model.decomp_mode = old_decomp_mode;
181  L_I = lincomb_sequence(L_I_comp, L_I_coeff);
182  L_E = lincomb_sequence(L_E_comp, L_E_coeff);
183  b = lincomb_sequence(b_comp, b_coeff);
184  end;
185 
186  %if model.data_const_in_time
187  % operators_required = 0;
188  %end;
189 
190  if model.compute_derivative_info
191  % Get Operators for derivative information:
192  [sLi,sLe,sb] = model.rb_derivative_operators_coefficients_ptr(model);
193  %sLe=-sLe;
194 
195  if ~isempty(L_I_comp) %only do the linear combination if the coefficients sLi are not empty
196  for i=1:nr_indx_mu_i
197  L_I_derived{i}=sparse(size(L_I_comp{1},1),size(L_I_comp{1},2));
198  end
199  end
200 
201  for i=1:nr_indx_mu_i
202  L_E_derived{i} = sparse(size(L_E_comp{1},1),size(L_E_comp{1},2));
203  b_derived{i} = sparse(length(b_comp{1}),1);
204  end
205 
206 
207  for i=1:nr_indx_mu_i
208  if ~isequal(sLi,[]) %only do the linear combination if the coefficients sLi are not empty
209  L_I_derived{i} = lincomb_sequence(L_I_comp,sLi(indx_mu_i(i)));
210  else
211  L_I_derived{i}=0;
212  end
213  L_E_derived{i} = lincomb_sequence(L_E_comp,sLe(indx_mu_i(i),:));
214  b_derived{i} = lincomb_sequence(b_comp,sb(indx_mu_i(i),:));
215  end
216  end
217 
218  end;
219 
220  %rhs = L_E * Ut + b;
221  rhs = (speye(size(L_E)) + model.dt*L_E) * Ut + model.dt*b;
222  Ut_old=Ut;
223 
224  if isempty(find(L_I, 1))%isequal(L_I, speye(size(L_I)))
225  Ut = rhs;
226  else
227  % solve linear system
228  % disp('check symmetry and choose solver accordingly!');
229  % keyboard;
230  % nonsymmetric solvers:
231  % [U(:,t+1), flag] = bicgstab(L_I,rhs,[],1000);
232  % [U(:,t+1), flag] = cgs(L_I,rhs,[],1000);
233  %
234  % symmetric solver, non pd:
235  % omit symmlq:
236  % see bug_symmlq.mat for a very strange bug: cannot solve identity system!
237  % reported to matlab central, but no solution up to now.
238  % [U(:,t+1), flag] = symmlq(L_I,rhs,[],1000);
239  %
240  % [U(:,t+1), flag] = minres(L_I,rhs,[],1000);
241  % symmetric solver, pd:
242  %[U(:,t+1), flag] = pcg(L_I,rhs,[],1000);
243  % bicgstab works also quite well:
244  %[U(:,t+1), flag] = bicgstab(L_I,rhs,[],1000);
245  Ut = (speye(size(L_I))+model.dt*L_I)\rhs;%Ut + model.dt*(L_I \ rhs);
246 
247  % if flag>0
248  % disp(['error in system solution, solver return flag = ', ...
249  % num2str(flag)]);
250  % keyboard;
251  % end;
252 
253  end;
254 
255 
256  if save_time_index(t_ind)
257  U(:,t_column) = Ut;
258  time_indices(t_column) = t_ind;
259  time(t_column) = t;
260  t_column = t_column + 1;
261  end;
262 
263  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
264  %calculation derivative solution
265  if model.compute_derivative_info
266  for i=1:nr_indx_mu_i
267  rhs_der = (speye(size(L_E)) + model.dt*L_E) * Ut_der(:,i) +...
268  model.dt*L_E_derived{i} * Ut_old + model.dt*L_I_derived{i}*Ut + model.dt*b_derived{i};
269  if isequal(L_I,zeros(size(L_I)))
270  Ut_der(:,i) = rhs_der;
271  else
272  Ut_der(:,i) = (speye(size(L_I))+ model.dt*L_I)\rhs_der;
273  end
274  if save_time_index(t_ind)
275  U_der{i}(:,t_column-1) = Ut_der(:,i);
276  end;
277 
278  end
279  end
280 
281 end;
282 
283 
284 if model.verbose == 9
285  fprintf('\n');
286 end;
287 
288 
289 sim_data.U = U;
290 if model.compute_derivative_info
291 sim_data.U_der = U_der;
292 end
293 
294 sim_data.time = time;
295 sim_data.time_indices = time_indices;
296 
297 if model.compute_output_functional
298  % get operators
299  model.decomp_mode=1;
300  v = model.operators_output(model,model_data);
301  sim_data.y = (v{1}') * U;
302  sim_data.y_der=[];
303  if model.compute_derivative_info
304  for i = 1:nr_indx_mu_i
305  sim_data.y_der(i,:) = (v{1}')*U_der{i};
306  end
307  end
308 end;
309 
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