1 function scm_example_script(step)
3 %scm_example_script(step)
6 % Attention: In some of the steps precomputed scm_offline_data can be loaded!
8 % step 1: generates scm_offline_data (stored in reduced_data) and saves them. Shows the typical approach.
9 % step 2: loads scm_offline_data generated with step 1 and does some tests (
scm_lower_bound =< real constant =< scm_upper_bound for random mus and
11 % step 3: test for scm_offline_data computet with step 1. Compares error estimators computed in the rb_simulation using scm and not using it.
12 % step 4: test for the small
thermal_block (B1 = 2, B2 = 1). One shall see, that the scm for alpha and for beta produce the same upper and lower bounds.
16 % - the fields that can be changed are always marked with 'choose', 'specify' or 'insert'
18 % - regarding step 1: See 'Additional information on the functionality of the SCM' on which models are supported yet.
20 % in the basis generation (while gen_detailed_data). Other models might do so, which would result in the yet
21 % unsolved problem of generating scm_offline_data in each basis generation step.
22 % - regarding step 2: Due to the limited amounts of supportet models of step 1 the exact constants in this step are computed rather direct and
23 % expensive (huge 'lin_evol' problems may cause RAM issues here)
24 % - regarding step 3: If this step shall work for a 'lin_evol' model in the current version (24.09 2012) one has to choos model.error_norm = 'energy' and
26 % - regarding step 4: In the end is a display showing the maximum error of any of the computet lower bounds to the respective exact constant. By
27 % this one can see how exact the scm is.
28 % This step can easily be expanded to support other models.
30 %% Additional information on the functionality of the SCM:
31 % - the SCM for coercive 'lin_stat' problems works fine
32 % - the SCM for coercive 'lin_evol' problems hasn't been tested yet
33 % - the SCM for small inf-sup 'lin_stat' problems works fine (see
scm_demo.m and step 4)
34 % - the SCM for small inf-sup 'lin_evol' problems hasn't been tested yet
36 % Huge (in the sense of Q and therefore Q^2 being quite large) inf-sup
39 % the bounding box allowed many components to be negativ, which should be
40 % fine, but in the upcoming online-phase it seemed impossible to guarantee
41 % a positiv lower bound. This problem could not be solved in time and will
42 % have to be tackled in the future. One posibility might be to severely
43 % increase the size of C (500 and more) via model.scm_size_C.
45 %% todo: die standard scm values müssen doch ins default model, geht nicht in scm offline -> da dann checks, falls n feld fehlt warning + keyboard oder so
52 model.
verbose = 21; % choose verbosity level (there will be no output in case of model.verbose =< 20)
53 % specifying SCM parameters (optional - see
scm_offline.m for a detailed description)
54 model.scm_M_alpha = 70;
55 model.scm_M_plus = 300;
56 model.scm_eps_tol = 1e-5;
57 model.scm_size_C = 200;
58 % necessary to choose either coercive or inf-sup stable SCM
59 model.scm_desired_constant = 1; %1 = alpha (coercive), 2 = beta (inf-sup stable)
60 % don't change the rest
62 model_data = gen_model_data(model);
63 detailed_data = gen_detailed_data(model, model_data);
64 reduced_data = gen_reduced_data(model, detailed_data); %
scm_offline.m is included here
65 save('step1_data.mat')
69 load('step1_data.mat') % computet with step 1. Contains model, model_data, detailed_data and reduced_data(including reduced_data.scm_offline_data)
70 number_of_test_mus = 50; % choose number of random mus for the test (but 50 should be fine) - nothing else to choose in this step
71 K = model.get_inner_product_matrix(model_data);
72 if isfield(model_data,'df_info') % in FEM-cases cut out dirgid-values, since they can bias the upcoming eigenvalueproblems
73 K(:,model_data.df_info.dirichlet_gids) = [];
74 K(model_data.df_info.dirichlet_gids,:) = [];
76 % generate a set M_test with the desired number of random mus
77 build1 = zeros(size(model.mu_ranges,2),1);
78 build2 = zeros(size(model.mu_ranges,2),1);
79 for i = 1:size(model.mu_ranges,2)
80 build1(i,1) = model.mu_ranges{i}(1);
81 build2(i,1) = model.mu_ranges{i}(2);
83 M_test = unifrnd(repmat(build1,1,number_of_test_mus),repmat(build2,1,number_of_test_mus));
84 %% first test:
scm_lower_bound =< real constant =< scm_upper_bound
for mu in M_test
86 gather_LB_random_mu = zeros(number_of_test_mus,1);
87 gather_UB_random_mu = zeros(number_of_test_mus,1);
88 gather_constant_random_mu = zeros(number_of_test_mus,1);
89 % compute the components (for the computation of the exact constant)
90 model.decomp_mode = 1;
91 if strcmp(model.rb_problem_type, 'lin_stat') == 1
92 A_comp = model.operators(model, model_data);
93 M = 1; % only 1 timestep;
94 H_total = size(K,1)*M; % total size of the system
95 elseif strcmp(model.rb_problem_type, 'lin_evol') == 1
96 [L_I_comp,L_E_comp,~] = model.operators_ptr(model, model_data);
97 M = model.nt + 1; % number of timesteps
98 H_total = size(K,1)*M; % total size of the system
100 warningstate_error = warning('error','MATLAB:eigs:NoEigsConverged'); % sets the state of this warning to error. This way you can tackle it with a try catch block and adjust the problem.
101 for i = 1:number_of_test_mus
103 model = set_mu(model, M_test(:,i));
104 % compute the lower and upper bound
105 [gather_LB_random_mu(i),gather_UB_random_mu(i)] =
scm_lower_bound(model, reduced_data);
106 % compute the exact constant
107 model.decomp_mode = 2;
108 if strcmp(model.rb_problem_type, 'lin_stat') == 1
109 A_coeff = model.operators(model, model_data);
110 A = lincomb_sequence(A_comp, A_coeff);
111 if isfield(model_data,'df_info') % again cut out dirgid values in FEM case
112 A(:,model_data.df_info.dirichlet_gids) = [];
113 A(model_data.df_info.dirichlet_gids,:) = [];
115 elseif strcmp(model.rb_problem_type, 'lin_evol') == 1
116 [L_I_coeff,L_E_coeff,~] = model.operators_ptr(model, model_data);
117 L_I = lincomb_sequence(L_I_comp, L_I_coeff);
118 L_E = lincomb_sequence(L_E_comp, L_E_coeff);
119 % build Petrov-Galerkin-BLF-matrix
120 kron_1 = sparse(diag([1;zeros(model.nt,1)]));
121 kron_2 = sparse(diag([0;ones(model.nt,1)]));
122 kron_3 = sparse(diag(-ones(model.nt,1),-1));
123 A = kron(kron_1, K) + kron(kron_2, L_I'*K) + kron(kron_3, L_E'*K);
125 if model.scm_desired_constant == 1
126 try % solve the EWP in a try catch block that prevents covergence issues and other problems with eigs
127 LM_alpha = eigs(0.5*(A+A'),kron(speye(M),K),1,'LM'); %first try to solve the EWP with default options
129 if (strcmp(err.identifier,'MATLAB:eigs:ARPACKroutineErrorMinus14')) || (strcmp(err.identifier,'MATLAB:eigs:NoEigsConverged'))...
130 || (strcmp(err.message,'Error with ARPACK routine dnaupd: info = -8'))
131 % in these cases (convergence problems or heavy clustering of eigenvalues) change the options and try again. Can be timeconsuming.
132 if H_total < 600 % opts.p has to be smaller than H_total
133 opts.p = ceil(H_total/2);
141 disp('There was no solution to an eigenvalueproblem. I changed the options.');
143 LM_alpha = eigs(0.5*(A+A'),kron(speye(M),K),1,'LM',opts);
144 no_solution = 0; %end when there is no error
145 catch err2 %when it still fails change the options and try again!
147 if (strcmp(err2.identifier,'MATLAB:eigs:ARPACKroutineErrorMinus14')) || (strcmp(err2.identifier,'MATLAB:eigs:NoEigsConverged'))...
148 || (strcmp(err2.message,'Error with ARPACK routine dnaupd: info = -8'))
149 opts.tol = 100 * opts.tol;
150 if H_total < 600 % opts.p has to be smaller than H_total
151 opts.p = opts.p + ceil(H_total/50);
155 opts.maxit = opts.maxit + 100;
157 if opts.tol > 1e-3 %if the options have changed several times and there is still no solution produce an error.
158 error(['I changed the options of an eigenvalueproblem up to opts.tol = ' mat2str(opts.tol) ', opts.p = ' mat2str(opts.p) ' and opts.maxit = ' mat2str(opts.maxit) ' but I still could not find a solution. Reconsider your problem']);
162 else %if there is another error rethrow
168 try % solve the EWP in a try catch block that prevents covergence issues and other problems with eigs
169 gather_constant_random_mu(i) = eigs(0.5*(A+A') - (LM_alpha+1e-10)*kron(speye(M),K),kron(speye(M),K),1,'LM') + (LM_alpha+1e-10); %first try to solve the EWP with default options
171 if (strcmp(err.identifier,'MATLAB:eigs:ARPACKroutineErrorMinus14')) || (strcmp(err.identifier,'MATLAB:eigs:NoEigsConverged'))...
172 || (strcmp(err.message,'Error with ARPACK routine dnaupd: info = -8'))
173 % in these cases (convergence problems or heavy clustering of eigenvalues) change the options and try again. Can be timeconsuming.
174 if H_total < 600 % opts.p has to be smaller than H_total
175 opts.p = ceil(H_total/2);
183 disp('There was no solution to an eigenvalueproblem. I changed the options.');
185 gather_constant_random_mu(i) = eigs(0.5*(A+A') - (LM_alpha+1e-10)*kron(speye(M),K),kron(speye(M),K),1,'LM',opts) + (LM_alpha+1e-10);
186 no_solution = 0; %end when there is no error
187 catch err2 %when it still fails change the options and try again!
189 if (strcmp(err2.identifier,'MATLAB:eigs:ARPACKroutineErrorMinus14')) || (strcmp(err2.identifier,'MATLAB:eigs:NoEigsConverged'))...
190 || (strcmp(err2.message,'Error with ARPACK routine dnaupd: info = -8'))
191 opts.tol = 100 * opts.tol;
192 if H_total < 600 % opts.p has to be smaller than H_total
193 opts.p = opts.p + ceil(H_total/50);
197 opts.maxit = opts.maxit + 100;
199 if opts.tol > 1e-3 %if the options have changed several times and there is still no solution produce an error.
200 error(['I changed the options of an eigenvalueproblem up to opts.tol = ' mat2str(opts.tol) ', opts.p = ' mat2str(opts.p) ' and opts.maxit = ' mat2str(opts.maxit) ' but I still could not find a solution. Reconsider your problem']);
204 else %if there is another error rethrow
209 gather_constant_random_mu(i) = LM_alpha;
211 elseif model.scm_desired_constant == 2
212 try % solve the EWP in a try catch block that prevents covergence issues and other problems with eigs
213 LM_beta = sqrt(eigs(A*kron(speye(M),inv(K))*A',kron(speye(M),K),1,'LM')); %first try to solve the EWP with default options
215 if (strcmp(err.identifier,'MATLAB:eigs:ARPACKroutineErrorMinus14')) || (strcmp(err.identifier,'MATLAB:eigs:NoEigsConverged'))...
216 || (strcmp(err.message,'Error with ARPACK routine dnaupd: info = -8'))
217 % in these cases (convergence problems or heavy clustering of eigenvalues) change the options and try again. Can be timeconsuming.
218 if H_total < 600 % opts.p has to be smaller than H_total
219 opts.p = ceil(H_total/2);
227 disp('There was no solution to an eigenvalueproblem. I changed the options.');
229 LM_beta = sqrt(eigs(A*kron(speye(M),inv(K))*A',kron(speye(M),K),1,'LM',opts));
230 no_solution = 0; %end when there is no error
231 catch err2 %when it still fails change the options and try again!
233 if (strcmp(err2.identifier,'MATLAB:eigs:ARPACKroutineErrorMinus14')) || (strcmp(err2.identifier,'MATLAB:eigs:NoEigsConverged'))...
234 || (strcmp(err2.message,'Error with ARPACK routine dnaupd: info = -8'))
235 opts.tol = 100 * opts.tol;
236 if H_total < 600 % opts.p has to be smaller than H_total
237 opts.p = opts.p + ceil(H_total/50);
241 opts.maxit = opts.maxit + 100;
243 if opts.tol > 1e-3 %if the options have changed several times and there is still no solution produce an error.
244 error(['I changed the options of an eigenvalueproblem up to opts.tol = ' mat2str(opts.tol) ', opts.p = ' mat2str(opts.p) ' and opts.maxit = ' mat2str(opts.maxit) ' but I still could not find a solution. Reconsider your problem']);
248 else %if there is another error rethrow
253 try % solve the EWP in a try catch block that prevents covergence issues and other problems with eigs
254 gather_constant_random_mu(i) = sqrt(eigs(A*kron(speye(M),inv(K))*A' - (LM_beta+1e-10)*kron(speye(M),K),kron(speye(M),K),1,'LM') + (LM_beta+1e-10)); %first try to solve the EWP with default options
256 if (strcmp(err.identifier,'MATLAB:eigs:ARPACKroutineErrorMinus14')) || (strcmp(err.identifier,'MATLAB:eigs:NoEigsConverged'))...
257 || (strcmp(err.message,'Error with ARPACK routine dnaupd: info = -8'))
258 % in these cases (convergence problems or heavy clustering of eigenvalues) change the options and try again. Can be timeconsuming.
259 if H_total < 600 % opts.p has to be smaller than H_total
260 opts.p = ceil(H_total/2);
268 disp('There was no solution to an eigenvalueproblem. I changed the options.');
270 gather_constant_random_mu(i) = sqrt(eigs(A*kron(speye(M),inv(K))*A' - (LM_beta+1e-10)*kron(speye(M),K),kron(speye(M),K),1,'LM',opts) + (LM_beta+1e-10));
271 no_solution = 0; %end when there is no error
272 catch err2 %when it still fails change the options and try again!
274 if (strcmp(err2.identifier,'MATLAB:eigs:ARPACKroutineErrorMinus14')) || (strcmp(err2.identifier,'MATLAB:eigs:NoEigsConverged'))...
275 || (strcmp(err2.message,'Error with ARPACK routine dnaupd: info = -8'))
276 opts.tol = 100 * opts.tol;
277 if H_total < 600 % opts.p has to be smaller than H_total
278 opts.p = opts.p + ceil(H_total/50);
282 opts.maxit = opts.maxit + 100;
284 if opts.tol > 1e-3 %if the options have changed several times and there is still no solution produce an error.
285 error(['I changed the options of an eigenvalueproblem up to opts.tol = ' mat2str(opts.tol) ', opts.p = ' mat2str(opts.p) ' and opts.maxit = ' mat2str(opts.maxit) ' but I still could not find a solution. Reconsider your problem']);
289 else %if there is another error rethrow
294 gather_constant_random_mu(i) = LM_beta;
298 warning(warningstate_error) % return the state of the warning to 'on' instead of 'error'
301 %% second test:
scm_lower_bound = real constant = scm_upper_bound for mu in C
303 size_of_C = size(reduced_data.scm_offline_data.C,2);
304 gather_LB_mu_in_C = zeros(size_of_C,1);
305 gather_UB_mu_in_C = zeros(size_of_C,1);
306 gather_constant_mu_in_C = reduced_data.scm_offline_data.alpha_C; % they were already computed in the offline-phase
307 % compute the lower and upper bounds
310 model = set_mu(model, reduced_data.scm_offline_data.C(:,j));
311 [gather_LB_mu_in_C(j),gather_UB_mu_in_C(j)] =
scm_lower_bound(model, reduced_data);
319 plot(1:number_of_test_mus, gather_LB_random_mu, 'r:', 1:number_of_test_mus, gather_constant_random_mu, 'b', 1:number_of_test_mus, gather_UB_random_mu, 'g--')
320 title('results of the first test, i.e. using the set of random \mu')
321 xlabel('number of test \mu')
323 leg = legend('scm lower bound','exact constant','scm upper bound');
324 set(leg,'Location','Best')
326 plot(1:size_of_C, gather_LB_mu_in_C, 'r:', 1:size_of_C, gather_constant_mu_in_C, 'b', 1:size_of_C, gather_UB_mu_in_C, 'g--')
327 title('results of the second tests, i.e. using the set C')
328 xlabel('number of \mu in C')
330 leg = legend('scm lower bound','exact constant','scm upper bound');
331 set(leg,'Location','Best')
332 set(gcf,'Color','white')
333 % additional output information
334 disp(['maximum distance between scm lower bound and exact constant for random mu is ' mat2str(max(abs(gather_constant_random_mu - gather_LB_random_mu)))])
335 disp(['maximum distance between scm upper bound and exact constant for random mu is ' mat2str(max(abs(gather_constant_random_mu - gather_UB_random_mu)))])
336 disp(['maximum distance between scm lower bound and exact constant for mu in C is ' mat2str(max(abs(gather_constant_mu_in_C - gather_LB_mu_in_C)))])
337 disp(['maximum distance between scm upper bound and exact constant for mu in C is ' mat2str(max(abs(gather_constant_mu_in_C - gather_UB_mu_in_C)))])
341 load('step1_data.mat') % load offline_data computet with step 1 - includes model, model_data, detailed_data and reduced_data
342 number_of_tests = 100; % choose the size of the random mu set
343 gather_scm_estimators = zeros(number_of_tests,1);
344 gather_non_scm_estimators = zeros(number_of_tests,1);
345 % build the random mu set
346 build1 = zeros(size(model.mu_ranges,2),1);
347 build2 = zeros(size(model.mu_ranges,2),1);
348 for i = 1:size(model.mu_ranges,2)
349 build1(i,1) = model.mu_ranges{i}(1);
350 build2(i,1) = model.mu_ranges{i}(2);
352 M_test = unifrnd(repmat(build1,1,number_of_tests),repmat(build2,1,number_of_tests));
353 for i = 1:number_of_tests
355 model = set_mu(model, M_test(:,i));
356 % first
do rb_simulation (error estimator computation) without scm
358 rb_sim_data = rb_simulation(model, reduced_data);
359 gather_non_scm_estimators(i) = rb_sim_data.Delta;
362 rb_sim_data = rb_simulation(model, reduced_data);
363 gather_scm_estimators(i) = rb_sim_data.Delta;
366 % compare results with plot
369 plot(1:number_of_tests, gather_non_scm_estimators, 'r:', 1:number_of_tests, gather_scm_estimators, 'g--')
370 xlabel('number of test \mu')
371 leg = legend('estimator without scm','estimator with scm');
372 set(leg,'Location','Best')
373 set(gcf,'Color','white')
374 % additional output information
375 disp(['maximum error bestween an estimator with and without scm is ' mat2str(max(abs(gather_non_scm_estimators - gather_scm_estimators)))])
379 mode = 2; % choose to either load precomputed scm_offline_data of the small
thermal_block (params.B1 = 2, params.B2 = 1) for the coercive and inf-sup stable case (mode = 1),
380 % or produce the data here (mode = 2)
382 load('step1_data_for_small_coercive_TB.mat')
384 %reduced_data1 = reduced_data;
386 reduced_data1.scm_offline_data = scm_offline_data;
387 load('step1_data_for_small_infup_stable_TB.mat')
389 %reduced_data2 = reduced_data;
391 reduced_data2.scm_offline_data = scm_offline_data;
397 % choose to have output (=< 20) or to have output (>20) from the upcoming offline phase
399 model_2.verbose = 21;
400 % make sure to use the scm
403 % configuration fields of the scm
404 model_1.scm_M_alpha = 70;
405 model_2.scm_M_alpha = 70;
406 model_1.scm_M_plus = 200;
407 model_2.scm_M_plus = 200;
408 model_1.scm_eps_tol = 1e-14;
409 model_2.scm_eps_tol = 1e-14;
410 model_1.scm_size_C = 50;
411 model_2.scm_size_C = 50;
412 model_1.scm_desired_constant = 1; % for the coercive scm
413 model_2.scm_desired_constant = 2; % for the inf-sup stable scm
414 % for the other optional scm-parameters the standard values are sufficient
415 % model and detailed_data are the sam in both cases
416 model_data = gen_model_data(model_1);
417 model_1.RB_mu_list = {[0.1,1],[1,0.1]}; % required so gen_detailed_data works
418 detailed_data = gen_detailed_data(model_1, model_data);
419 reduced_data1 = gen_reduced_data(model_1, detailed_data);
420 reduced_data2 = gen_reduced_data(model_2, detailed_data);
423 number_of_tests = 100; % choose the size of the random mu
set
424 gather_lower_bounds_1 = zeros(size(number_of_tests,2));
425 gather_upper_bounds_1 = zeros(size(number_of_tests,2));
426 gather_lower_bounds_2 = zeros(size(number_of_tests,2));
427 gather_upper_bounds_2 = zeros(size(number_of_tests,2));
428 gather_constant = zeros(size(number_of_tests,2));
429 % build the random mu
set
430 build1 = zeros(size(model_1.mu_ranges,2),1);
431 build2 = zeros(size(model_1.mu_ranges,2),1);
432 for i = 1:size(model_1.mu_ranges,2)
433 build1(i,1) = model_1.mu_ranges{i}(1);
434 build2(i,1) = model_1.mu_ranges{i}(2);
436 M_test = unifrnd(repmat(build1,1,number_of_tests),repmat(build2,1,number_of_tests));
437 % collect the exact constant and the various upper and lower bounds
438 %
for every mu in the
set
439 for i = 1:number_of_tests
441 model_1 = set_mu(model_1, M_test(:,i));
442 [gather_lower_bounds_1(i), gather_upper_bounds_1(i)] =
scm_lower_bound(model_1, reduced_data1);
443 model_2 = set_mu(model_2, M_test(:,i));
444 [gather_lower_bounds_2(i), gather_upper_bounds_2(i)] =
scm_lower_bound(model_2, reduced_data2);
445 gather_constant(i) = min(M_test(:,i)); %
for the thermal block
this is known to always be the exact constant
448 % plot the upper and lower bounds
452 plot(1:number_of_tests, gather_lower_bounds_1, 'r:', 1:number_of_tests, gather_lower_bounds_2, 'g--')
453 xlabel('number of test \mu')
454 leg = legend('\alpha_{scm,LB}
','\beta_{scm,LB}
');
455 set(leg,'Location
','Best
')
457 plot(1:number_of_tests, gather_upper_bounds_1, 'r:
', 1:number_of_tests, gather_upper_bounds_2, 'g--')
458 xlabel('number of test \mu')
459 leg = legend('\alpha_{scm,UB}
','\beta_{scm,UB}
');
460 set(leg,'Location
','Best
')
461 set(gcf,'Color
','white
')
462 % error result (how exact is the lower bound to the exact constant)
463 disp(['maximal error of a lower bound to the exact constant is
' mat2str(max(abs(gather_lower_bounds_1 - gather_constant)))])
467 error('step number unknown!
')