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)
4 % Function performing a detailed simulation and calculating the derivative
5 % solution with respect to all parameters.
6 % required fields of model:
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
23 % compute_derivative_info: flag
if derivative information shall be
26 %
return fields of sim_data:
27 % U : sequence of DOF vectors
28 % y : sequence of output functional values (
if activated)
30 % Markus Dihlmann 15.10.10
33 disp(
'entered detailed simulation ');
36 if isempty(model_data)
37 model_data = gen_model_data(model);
40 if ~isfield(model,'compute_derivative_info')
41 model.compute_derivative_info = 0;
45 model.decomp_mode = 1; % == components;
49 if ~isfield(model,'optimization')
50 disp('Model has no field optimization.')
51 model.optimization =[];
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
58 indx_mu_i = 1:length(get_mu(model));
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
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;
70 save_time_index = ones(1,model.nt+1);
71 save_time_indices = 1:(model.nt+1);
74 % initial values by midpoint evaluation
75 U0_comp = model.init_values_algorithm(model,model_data);
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);
83 %assembling initial values true solution
84 Ut = lincomb_sequence(U0_comp,U0_coeff);
86 %assembling initial values derivative solution
87 if model.compute_derivative_info
88 Ut_der = zeros(length(Ut),nr_indx_mu_i);
90 Ut_der(:,i) = lincomb_sequence(U0_comp, U0_der_coeff(indx_mu_i(i),:)');
93 U_der=cell(nr_indx_mu_i,1);
95 U_der{i} = sparse(length(Ut), length(save_time_indices));
102 U = sparse(length(Ut),length(save_time_indices));
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;
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;
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
126 if save_time_index(t_ind+1)
128 if model.compute_derivative_info
130 U_der{i}(:,t_column) = Ut_der(:,i);
133 time_indices(t_column) = t_ind;
135 t_column = t_column + 1;
138 if ~isfield(model,
'compute_output_functional')
139 model.compute_output_functional = 0;
142 %model.plot(U0,model_data.grid,params);
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);
150 for t_ind = 1:model.nt
151 t = (t_ind-1)*model.dt;
153 disp(['entered time-loop step ',num2str(t_ind)]);
158 % get matrices and bias-vector
160 if (t_ind==1)||(~model.data_const_in_time)%operators_required
164 % new assembly in every iteration
165 if ~model.affinely_decomposed
166 [L_I, L_E, b] = model.operators_ptr(model, model_data);
168 % or simple assembly based on affine parameter decomposition
169 % => turns out to be slower for few components
171 % test affine decomposition
173 disp('test affine decomposition of operators')
174 test_affine_decomp(model.operators_ptr,3,1,model,model_data);
177 model.decomp_mode = 2;
178 [L_I_coeff, L_E_coeff, b_coeff] = model.operators_ptr(model, ...
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);
186 %if model.data_const_in_time
187 % operators_required = 0;
190 if model.compute_derivative_info
191 % Get Operators for derivative information:
192 [sLi,sLe,sb] = model.rb_derivative_operators_coefficients_ptr(model);
195 if ~isempty(L_I_comp) %only do the linear combination if the coefficients sLi are not empty
197 L_I_derived{i}=sparse(size(L_I_comp{1},1),size(L_I_comp{1},2));
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);
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)));
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),:));
221 rhs = (speye(size(L_E)) + model.dt*L_E) * Ut + model.dt*b;
224 if isempty(find(L_I, 1))%isequal(L_I, speye(size(L_I)))
227 % solve linear system
228 % disp(
'check symmetry and choose solver accordingly!');
230 % nonsymmetric solvers:
231 % [U(:,t+1), flag] = bicgstab(L_I,rhs,[],1000);
232 % [U(:,t+1), flag] = cgs(L_I,rhs,[],1000);
234 % symmetric solver, non pd:
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);
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);
248 % disp([
'error in system solution, solver return flag = ', ...
256 if save_time_index(t_ind)
258 time_indices(t_column) = t_ind;
260 t_column = t_column + 1;
263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
264 %calculation derivative solution
265 if model.compute_derivative_info
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;
272 Ut_der(:,i) = (speye(size(L_I))+ model.dt*L_I)\rhs_der;
274 if save_time_index(t_ind)
275 U_der{i}(:,t_column-1) = Ut_der(:,i);
284 if model.verbose == 9
290 if model.compute_derivative_info
291 sim_data.U_der = U_der;
294 sim_data.time = time;
295 sim_data.time_indices = time_indices;
297 if model.compute_output_functional
300 v = model.operators_output(model,model_data);
301 sim_data.y = (v{1}
') * U;
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};
function r = verbose(level, message, messageId)
This function displays messages depending on a message-id and/or a level. Aditionally you can set/res...