1 % script generating figures of the paper
"An Iterative Domain
2 % Decomposition Procedure for The Reduced Basis Method"
11 disp(
'Script generating the figures of the paper');
12 disp(
'==========================================');
13 disp([
'"An Iterative Domain Decomposition Procedure for The Reduced' ...
15 disp([
'============================================================' ...
22 disp(
'--------------------------------------------------------');
23 fprintf(
'Initialization ...');
26 params.numintervals = 84;
27 params.RB_numintervals = 4;
28 params.detailed_train_savepath =
'detailed_train_84_rb4';
31 base_model.compute_output_functional = 0;
36 model_data = gen_model_data(model);
37 mu_test = rand_uniform(100, model.mu_ranges)
';
40 input_string_filter = {'y
', 'n
'};
45 % display discretization settings:
46 disp('Finite Element discretization:
');
47 disp(['mesh size:
', ...
48 num2str(model_data.base_model_data.df_info.grid.hmin)]);
49 disp(['number of dofs:
', ...
50 num2str(model_data.base_model_data.df_info.ndofs)]);
51 disp(['polynomial degree:
', num2str(base_model.pdeg)]);
55 % visualize source function
57 while ~any(strcmp(input_string, input_string_filter))
58 input_string = input('-> Visualize source
function? (y/n)
', 's
');
61 if strcmp(input_string, 'y
')
62 source = femdiscfunc([], model_data.base_model_data.df_info);
63 source_mu_list = {[0.1 0.1 0.1 0.35], [0.1 0.1 0.1 1]};
66 base_model = set_mu(base_model, source_mu_list{i});
67 source = fem_interpol_local(base_model.source, source, base_model);
69 disp(['plot
', num2str(i), ': mu4 =
', ...
70 num2str(source_mu_list{i}(4))]);
77 set(gca, 'FontSize
', 15);
82 clear('source_mu_list
');
89 disp('BASIS GENERATION
');
90 disp('--------------------------------------------------------
');
92 % display basis generation settings:
93 disp('Basis generation settings:
');
94 disp(['size of training set:
', ...
95 num2str(model.RB_numintervals(1)+1), '^
', ...
96 num2str(length(model.RB_numintervals))]);
97 disp(['error tolerance:
', num2str(model.RB_greedy_tolerance)]);
98 disp(['maximal total basis size: {
', num2str(model.N_max{1}), ...
99 ',
', num2str(model.N_max{2}), '}
']);
102 method_strings = {'A-SEQ
', 'B-SEQ
', 'A-NSEQ
', 'B-NSEQ
'};
106 while ~any(strcmp(input_string, input_string_filter))
107 input_string = input('-> Generate bases? (unrecommended)(y/n)
', 's
');
110 if strcmp(input_string, 'y
')
112 input_string_filter = {'A
', 'B
'};
113 while ~any(strcmp(input_string, input_string_filter))
114 input_string = input('Extension method? (A/B)
', 's
');
117 model.RB_extension_method = input_string;
119 input_string_filter = {'y
', 'n
'};
120 while ~any(strcmp(input_string, input_string_filter))
121 input_string = input('Sequence mode? (y/n)
', 's
');
124 model.RB_sequence_mode = strcmp(input_string, 'y
');
126 method_index = 1 + strcmp(model.RB_extension_method, 'B
') + ...
127 2 * (1 - model.RB_sequence_mode);
129 bases_filename = ['dom_dec_bases_
', ...
130 method_strings{method_index}, '.mat
'];
132 fprintf('\nstart basis generation ...\n\n
');
135 detailed_data = gen_detailed_data(model, model_data);
136 reduced_data = gen_reduced_data(model, detailed_data);
137 basis_gen_time = toc;
139 detailed_data = rmfield(detailed_data, 'reduced_data
');
141 disp(['save data in file
"',bases_filename,'"']);
142 save(bases_filename, 'detailed_data
', 'reduced_data
', ...
145 fprintf('\nbasis generation done!\n
');
147 clear('input_string
');
148 clear('input_string_filter
');
149 clear('method_index
');
150 clear('method_strings
');
151 clear('bases_filename
');
159 % compare generation methods
160 % Figure 6.3, Figure 6.4
162 while ~any(strcmp(input_string, input_string_filter))
163 input_string = input('-> Compare basis generation methods? (y/n)
', ...
167 if strcmp(input_string, 'y
')
169 bases_data = cell(4,1);
171 bases_data{i} = load(['dom_dec_bases_
',method_strings{i},'.mat
']);
174 % display computation times
176 minutes = zeros(4,1);
177 seconds = zeros(4,1);
179 hours(i) = floor(bases_data{i}.basis_gen_time / 3600);
180 minutes(i) = floor((bases_data{i}.basis_gen_time - ...
181 hours(i) * 3600) / 60);
182 seconds(i) = round(bases_data{i}.basis_gen_time - ...
183 hours(i) * 3600 - minutes(i) * 60);
185 disp('Computation times:
');
187 disp(['method
', method_strings{i}, ':
', ...
188 num2str(hours(i)), 'h
', num2str(minutes(i)), ...
189 'm
', num2str(seconds(i)), 's
']);
193 % compare error decay
196 while ~any(strcmp(input_string, input_string_filter))
197 input_string = input('--> Compare error decays? (y/n)
', 's
');
200 if strcmp(input_string, 'y
')
203 bases_data{1}.detailed_data.RB_info.max_errs, ...
204 'k
', 'LineWidth
', 2);
207 bases_data{2}.detailed_data.RB_info.max_errs, ...
208 'r
', 'LineWidth
', 2);
210 bases_data{3}.detailed_data.RB_info.max_errs, ...
211 '--k
', 'LineWidth
', 2);
213 bases_data{4}.detailed_data.RB_info.max_errs, ...
214 '--r
', 'LineWidth
', 2);
217 set(gca, 'FontSize
', 14);
218 legend([obj1 obj2 obj3 obj4], ...
219 'method A-SEQ
', 'method B-SEQ
', ...
220 'method A-NSEQ
', 'method B-NSEQ
');
221 xlabel('greedy-step
');
222 ylabel('maximal error estimate
');
226 % compare final bases sizes
229 while ~any(strcmp(input_string, input_string_filter))
230 input_string = input('--> Compare
final bases sizes? (y/n)
', 's
');
233 if strcmp(input_string, 'y
')
234 final_bases_sizes = zeros(4,1);
236 final_bases_sizes(i) = bases_data{i}.reduced_data.N{1} + ...
237 bases_data{i}.reduced_data.N{2};
241 bar(final_bases_sizes);
243 set(gca, 'FontSize
', 14);
244 set(gca, 'xTickLabel
', method_strings);
246 ylabel('final total basis size
');
250 % compare condition numbers
253 while ~any(strcmp(input_string, input_string_filter))
254 input_string = input(['--> Compare condition numbers of
', ...
255 'Neumann-side system matrices? (y/n)
'], 's
');
258 if strcmp(input_string, 'y
')
259 old_decomp_mode = model.decomp_mode;
260 model.decomp_mode = 2;
262 dir = model.dirichlet_side;
263 no_dir = mod(dir,2)+1;
265 final_min_mean_max_cond = zeros(4,3);
266 max_cond = cell(4,1);
270 zeros(size(mu_test, 1), ...
271 bases_data{i}.detailed_data.RB_info.steps);
273 for mu_ind = 1:size(mu_test, 1)
274 model = set_mu(model, mu_test(mu_ind, :));
276 [A_coeff, dummy1, dummy2, dummy3] = ...
277 model.operators(model, []);
278 A = lincomb_sequence(...
279 bases_data{i}.reduced_data.AN_comp{no_dir}, ...
282 for j = 1:size(all_cond, 2)
284 [bases_data{i}.reduced_data.I_0{no_dir}(...
285 1:bases_data{i}.detailed_data.RB_info ...
286 .bases_sizes.N0{no_dir}(j)) ...
287 bases_data{i}.reduced_data.I_G{no_dir}(...
288 1:bases_data{i}.detailed_data.RB_info ...
289 .bases_sizes.NG{no_dir}(j))];
291 all_cond(mu_ind, j) = cond(A(indices, indices));
294 max_cond{i} = max(all_cond);
298 final_min_mean_max_cond(i,1) = min(all_cond(:, end));
299 final_min_mean_max_cond(i,2) = mean(all_cond(:, end));
300 final_min_mean_max_cond(i,3) = max(all_cond(:, end));
304 model.decomp_mode = old_decomp_mode;
308 bar(final_min_mean_max_cond);
310 set(gca, 'yScale
', 'log
');
311 set(gca, 'FontSize
', 14);
312 set(gca, 'xTickLabel
', method_strings);
314 ylabel('cond(A_{N,2}(mu))
');
318 obj1 = semilogy(max_cond{1}, 'k
', 'LineWidth
', 2);
320 obj2 = semilogy(max_cond{2}, 'r
', 'LineWidth
', 2);
321 obj3 = semilogy(max_cond{3}, '--k
', 'LineWidth
', 2);
322 obj4 = semilogy(max_cond{4}, '--r
', 'LineWidth
', 2);
325 set(gca, 'FontSize
', 14);
326 legend([obj1 obj2 obj3 obj4], ...
327 'method A-SEQ
', 'method B-SEQ
', ...
328 'method A-NSEQ
', 'method B-NSEQ
', ...
329 'Location
', 'SouthEast
');
330 xlabel('greedy-step
');
331 ylabel('max_mu cond(A_{N,2}(mu))
');
340 disp('REDUCED SIMULATION
');
341 disp('--------------------------------------------------------
');
343 % settings for simulations
344 model.det_sim_tol = 1e-10;
345 model.RB_sim_tol = 1e-10;
346 model.RB_approximate_thetaN = 0;
348 % display simulation settings:
349 disp('Settings
for the detailed simulations:
');
350 disp(['tolerance:
', num2str(model.det_sim_tol)]);
351 disp(['maximal iteration-number:
', num2str(model.maxiter)]);
352 disp('Settings
for the reduced simulations:
');
353 disp(['tolerance:
', num2str(model.RB_sim_tol)]);
354 disp(['maximal iteration-number:
', ...
355 num2str(model.RB_maxiterN)]);
359 % visualize reduced iteration
360 % Figure 6.5, Figure 6.6 left
362 while ~any(strcmp(input_string, input_string_filter))
363 input_string = input('-> Visualize reduced iteration? (y/n)
', 's
');
366 if strcmp(input_string, 'y
')
367 load('dom_dec_bases_B-NSEQ.mat
');
369 model = set_mu(model, [1.3 2.6 2.4 0.56]);
371 sim_data = detailed_simulation(model, model_data);
372 sim_data = model.compute_error(model, model_data, sim_data);
374 rb_sim_data = rb_simulation(model, reduced_data);
375 rb_sim_data = rb_reconstruction(model, detailed_data, ...
377 rb_sim_data = model.compute_error(model, detailed_data, ...
380 plot_params.clim = [0 0.02];
381 iteration_indices = [1 5 rb_sim_data.numiter];
384 for i = 1:length(iteration_indices)
386 rb_sim_data.uh{j}.dofs = ...
387 rb_sim_data.all_dofs{j}(:, iteration_indices(i));
390 if (iteration_indices(i) == rb_sim_data.numiter)
391 disp(['plot
', num2str(i), ': n = n_N(mu) =
', ...
392 num2str(iteration_indices(i))]);
394 disp(['plot
', num2str(i), ': n =
', ...
395 num2str(iteration_indices(i))]);
397 plot_sim_data(model, detailed_data, rb_sim_data, plot_params);
402 set(gca, 'FontSize
', 15);
407 disp(['plot
', num2str(i+1), ...
408 ': comparison with detailed iteration
']);
410 obj1 = semilogy(sim_data.X_err, 'b
', 'LineWidth
', 2);
412 obj2 = semilogy(1:2:rb_sim_data.numiter, ...
413 rb_sim_data.X_err(1:2:end), 'bo
', 'LineWidth
', 2);
414 obj3 = semilogy(1:2:rb_sim_data.numiter, ...
415 rb_sim_data.Delta(1:2:end), 'b.
', 'LineWidth
', 2);
418 set(gca, 'FontSize
', 13);
419 legend([obj1 obj2 obj3], 'error in detailed simulation
', ...
420 'error in reduced simulation
', ...
421 'error estimate in reduced simulation
');
422 xlabel('iteration number
');
429 % investigate effectivity of error estimator
432 while ~any(strcmp(input_string, input_string_filter))
433 input_string = input(['-> Investigate effectivity
', ...
434 'of error estimator? (y/n)
'], 's
');
437 if strcmp(input_string, 'y
')
438 load('dom_dec_bases_B-NSEQ.mat
');
439 model.RB_sim_tol = 1e-06;
440 eff = zeros(size(mu_test, 1), 1);
442 fprintf(['Start reduced simulations of
', ...
443 num2str(size(mu_test, 1)), ' test parameters
']);
445 for mu_ind = 1:size(mu_test, 1)
446 model = set_mu(model, mu_test(mu_ind, :));
448 rb_sim_data = rb_simulation(model, reduced_data);
449 rb_sim_data = rb_reconstruction(model, detailed_data, ...
451 rb_sim_data = model.compute_error(model, detailed_data, ...
454 eff(mu_ind) = rb_sim_data.Delta(end) / rb_sim_data.X_err(end);
464 set(gca, 'FontSize
', 13);
465 xlabel('effectivity of error estimate
');
473 % compare simulation times
475 while ~any(strcmp(input_string, input_string_filter))
476 input_string = input(['-> Compare simulation time
', ...
477 'of detailed and reduced simulations? (y/n)
'], 's
');
480 if strcmp(input_string, 'y
')
481 load('dom_dec_bases_B-NSEQ.mat
');
483 det_sim_times = zeros(size(mu_test, 1), 1);
484 rb_sim_times = zeros(size(mu_test, 1), 1);
486 for mu_ind = 1:size(mu_test, 1)
487 model = set_mu(model, mu_test(mu_ind, :));
490 sim_data = detailed_simulation(model, model_data);
491 det_sim_times(mu_ind) = toc;
494 rb_sim_data = rb_simulation(model, reduced_data);
495 rb_sim_data = rb_reconstruction(model, detailed_data, ...
497 rb_sim_times(mu_ind) = toc;
501 disp(['Detailed simulation times range from
', ...
502 num2str(min(det_sim_times)), 's to
', ...
503 num2str(max(det_sim_times)), 's.
']);
504 disp(['Reduced simulation times range from
', ...
505 num2str(min(rb_sim_times)), 's to
', ...
506 num2str(max(rb_sim_times)), 's.
']);
507 disp(['Mean speed up factor:
', ...
508 num2str(mean(det_sim_times./rb_sim_times))]);
function model = thermalblock_dd_model(params)
Custom thermalblock model used for domain decomposition.
function model = dom_dec_model(base_model, params)
function creating a domain-decomposition-model with an arbitrary model and optional params...