2 % Thermal Block example similar as described in the book of
3 % A.T. patera and G. Rozza (just one parameter more)
6 % - div ( a(x) grad u(x)) = q(x) on Omega
7 % u(x)) = g_D(x) on Gamma_D
8 % a(x) (grad u(x)) n) = g_N(x) on Gamma_N
9 % s = l(u) linear output functional
11 % where Omega = [0,1]^2 is divided into B1 * B2 blocks
12 % QA := B1*B2. The heat conductivities are given by mu_i:
14 % -------------------------
15 % | ... | ..... | mu_QA |
16 % -------------------------
17 % | .... | ... | ..... |
18 % -------------------------
19 % | mu_1 | ... | mu_B1 |
20 % -------------------------
22 % `Gamma_D =` upper edge
23 % `Gamma_N = boundary(Omega)\Gamma_D`
25 % `a(x) = mu_i(x) if x\in B_i`
28 % `g_N = 1` on lower edge, 0 otherwise
29 % `l(u)` = average over lower edge
31 % S. Langhof and B. Haasdonk 26.2.2011
35 %model = lin_stat_model_default;
39 % MD: Mein Vorschlag für simple Basis-Generierungsalgorithmen, verwendet
41 % Funktionspointers spezifizieren kann. Genauso könnte man Simple* Klassen
42 % für die anderen Interfaces, also DetailedModel, ReducedModel und
43 % ReducedData implementieren. Das fände ich aber ehrlich gesagt unschön...
44 % Die Basisgenerierung kann so simpel sein, dass es vielleicht Sinn macht,
45 % die in eine kleine Funktion auszulagern, aber die anderen Klassen haben
46 % meistens komplexere Datenstrukturen oder mehr Methoden, so dass die
47 % "Description" Klasse wieder sehr unübersichtlich und intransparent wird,
48 % wenn man das alles hier hinein packt...
51 model.RB_customized_basis_generation_ptr = @my_RB_basisgen;
52 model.RB_train_rand_seed = 100;
53 model.RB_train_size = 1000;
54 model.RB_stop_epsilon = 1e-3;
55 model.RB_stop_Nmax = 100;
57 if nargin == 0 || ~isfield(params, 'B1')
60 % model.default = '3x3 demo version';
62 % number of blocks in X and Y direction
65 model.number_of_blocks = params.B1*params.B2;
67 % each block has a different heat conductivity
68 % upper left has conductivity 1
71 if ~isfield(params,
'mu_range')
72 params.mu_range = [0.1,10];
74 mu_range = params.mu_range;
75 for p = 1:model.number_of_blocks
76 mu_names = [mu_names,{[
'mu',num2str(p)]}];
77 mu_ranges = [mu_ranges,{mu_range}];
79 model.mu_names = mu_names;
80 model.mu_ranges = mu_ranges;
82 %
default values 1 everywhere
83 model.mus = ones(model.number_of_blocks,1);
84 model.get_mu = @(model) model.mus(:);
85 model.set_mu = @thermalblock_set_mu;
87 % simple snapshots without orthogonalization
88 %model.RB_generation_mode =
'lagrangian';
89 %model.RB_mu_list = {[0.1,1,1,1,1,1,1,1,1],...
90 % [1,0.1,1,1,1,1,1,1,1],...
91 % [1,1,0.1,1,1,1,1,1,1],...
92 % [1,1,1,0.1,1,1,1,1,1],...
93 % [1,1,1,1,0.1,1,1,1,1],...
94 % [1,1,1,1,1,0.1,1,1,1],...
95 % [1,1,1,1,1,1,0.1,1,1],...
96 % [1,1,1,1,1,1,1,0.1,1],...
97 % [1,1,1,1,1,1,1,1,0.1]};
99 %model.RB_generation_mode =
'model_RB_basisgen';
103 %%%%%%%%% set data functions
104 model.has_diffusivity = 1;
105 model.has_output_functional = 1;
106 model.has_dirichlet_values = 1;
107 model.has_neumann_values = 1;
109 % zero dirichlet values, i.e. 1 component, Q_dir = 1
110 dirichlet_values_coefficients = @(dummy,params) [0];
111 dirichlet_values_components = @(glob,params) {zeros(size(glob,1),1)};
112 model.dirichlet_values = @(glob,params) ...
113 eval_affine_decomp_general(dirichlet_values_components, ...
114 dirichlet_values_coefficients,glob,params);
116 % 1/0 neumann values depending on edge, non parametric, i.e Q_neu = 1;
117 neumann_values_coefficients = @(dummy,params) 1; % single component
118 model.neumann_values = @(glob,params) ...
119 eval_affine_decomp_general(@thermalblock_neumann_values_components, ...
120 neumann_values_coefficients, glob, params);
122 % diffusion tensor: each row four entries a11,a_21,a_12,a_22.
123 % a11(x)=a22(x) = mu_i
if x in block i, a12=a21 = 0.
124 diffusivity_tensor_coefficients = @(dummy,params) ...
126 model.diffusivity_tensor = @(glob,params) ...
127 eval_affine_decomp_general(...
128 @thermalblock_diffusivity_tensor_components, ...
129 diffusivity_tensor_coefficients, glob,params);
131 % only useful
for detailed simulation or nonlinear outputs:
132 %model.output_functional = @output_functional_boundary_integral;
134 model.operators_output = @fem_operators_output_boundary_integral;
135 % output weight
function: simply 1 on lower edge, 0
else => Ql = 1 component
136 output_function_components = @(glob,model) {1.0*(glob(:,2)<eps)};
137 output_function_coefficients = @(glob,model) 1;
138 model.output_function = @(glob,params) ...
139 eval_affine_decomp_general(...
140 output_function_components,...
141 output_function_coefficients, glob,params);
143 model.output_integral_qdeg = 2; %
145 %%%%%%%%%% discretization settings
147 if ~isfield(params,
'numintervals_per_block')
148 params.numintervals_per_block = 5;
152 model.xnumintervals = params.numintervals_per_block*params.B1;
153 model.ynumintervals = params.numintervals_per_block*params.B2;
154 model.xrange = [0,1];
155 model.yrange = [0,1];
157 if ~isfield(params,'pdeg')
161 if ~isfield(params,'qdeg')
166 model.pdeg = params.pdeg; % degree of polynomial functions
167 model.qdeg = params.qdeg; % quadrature degree
168 model.dimrange = 1; % scalar solution
170 model.boundary_type = @thermalblock_boundary_type;
171 %model.normals = @my_normals;
173 % new plot routine, additional block boundaries are plotted
175 model.compute_output_functional = 1;
176 model.yscale_uicontrols = 0.2;
178 % for error estimation:
179 model.coercivity_alpha = @(model) min(model.mus(:));
180 model.continuity_gamma = @(model) max(model.mus(:));
181 model.enable_error_estimator = 1;
183 % for making work with current dmodel/rmodel/descr decomposition
184 model.descr = []; % model is its own description
185 model.crb_enabled = 0;
187 % local data functions:
190 %%%%%%% auxiliary functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
192 function res = thermalblock_boundary_type(glob,params)
193 % returns the boundary type
194 res = zeros(size(glob,1),1);
195 i = find(glob(:,1)<=1e-10);
197 i = find(glob(:,1)>=1-1e-10);
199 i = find(glob(:,2)<=1e-10);
201 i = find(glob(:,2)>=1-1e-10);
204 function model = thermalblock_set_mu(model,mu)
205 if length(mu)~=model.number_of_blocks
206 error('length of mu does not fit to number of blocks!');
210 function comp = thermalblock_neumann_values_components(glob,params)
211 % Neumann values component function
212 res = zeros(size(glob,1),1);
213 i = find(glob(:,2)<eps);
217 function res = thermalblock_diffusivity_tensor_components(glob,params)
218 % diffusivity tensor component
function
220 %
for each point in glob find global block number
221 % xi: range 0 ... B1-1
222 xi = floor(glob(:,1)*params.B1);
223 i = find(xi>=params.B1);
227 % xi: range 0 ... B1-1
228 yi = floor(glob(:,2)*params.B2);
229 i = find(yi>=params.B2);
233 block_index = yi*params.B1+xi+1;
234 zeroblock = zeros(size(glob,1),4);
235 res = cell(1,params.number_of_blocks);
236 for q = 1:params.number_of_blocks;
238 i = find(block_index==q);
247 %
for q=1:params.number_of_blocks;
248 % block = block + res{q};
250 %disp(
'check diffusivity matrix!')
253 function alpha = thermalblock_coercivity_alpha(model)
254 alpha = min(model.get_mu(model))
256 %function [RBinit] = my_init_data_basis(model, ...
259 function RB = my_RB_basisgen(rmodel,detailed_data)
262 disp('entered my_RB_basisgen');
264 sim_data = detailed_simulation(rmodel, detailed_data.model_data);
265 n = fem_h10_norm(sim_data.uh);
266 detailed_data.RB = sim_data.uh.dofs / n;
267 reduced_data = gen_reduced_data(rmodel, detailed_data);
268 h10_matrix = sim_data.uh.df_info.h10_inner_product_matrix;
270 % Kommentar MD: Alle Description Felder, die mit RB_ beginnen, werden von
272 % (bg_descr.x == descr.RB_x)
273 bg_descr = rmodel.bg_descr;
275 mus = rand_uniform(bg_descr.train_size,rmodel.mu_ranges);
278 while( max_err_est> bg_descr.stop_epsilon) && ...
279 (size(detailed_data.RB,2)< bg_descr.stop_Nmax)
282 for i = 1:size(mus,2);
283 set_mu(rmodel, mus(:,i));
284 rb_sim_data = rb_simulation(rmodel,reduced_data);
285 if rb_sim_data.Delta > max_err_est
287 max_err_est = rb_sim_data.Delta;
290 disp(['max error estimator: ',num2str(max_err_est),...
291 ' for mu = ',num2str(mu_max')]);
292 set_mu(rmodel,mu_max);
293 sim_data = detailed_simulation(rmodel,detailed_data.model_data);
294 pr = sim_data.uh.dofs - ...
295 detailed_data.RB * (detailed_data.RB' * h10_matrix * ...
297 n = sqrt(max(pr'*h10_matrix*pr,0));
298 detailed_data.RB = [detailed_data.RB,pr/n];
299 reduced_data = gen_reduced_data(rmodel,detailed_data);
300 disp(['new basis size: ',num2str(size(detailed_data.RB,2))]);
303 RB = detailed_data.RB;
305 function p = thermalblock_plot_sim_data(model,detailed_data,sim_data, ...
310 %if ~isfield(plot_params,'no_lines')
311 plot_params.no_lines = 1;
313 p = lin_stat_plot_sim_data(model,detailed_data,sim_data,plot_params);
315 if ~isfield(plot_params,'plot_blocks')
316 plot_params.plot_blocks = 1;
318 if plot_params.plot_blocks
319 X = [0:1/model.B1:1];
320 Y = [0:1/model.B2:1];
322 [zeros(1,model.B1+1);...
323 ones(1,model.B1+1)]);
324 set(l1,'color',[0,0,0],'linestyle','-.');
326 l2 = line([zeros(1,model.B2+1);...
327 ones(1,model.B2+1)],...
329 set(l2,'color',[0,0,0],'linestyle','-.');
330 p = [p(:);l1(:);l2(:)];
Reduced basis implementation for linear stationary PDEs.
function ModelDescr descr = descr_default()
This function initializes the default settings for the ARE model.
A triangular conforming grid in two dimensions.
a very simple detailed data implementation gathering several detailed snapshots spanning the reduced ...
function local_model = elliptic_discrete_model(model)
function creating a model with local functions out of a model with global functions. See detailed description for explanation.
function rmodel = gen_reduced_model(dmodel,BasisGenDescr bg_descr)
generates an IReducedModel instance from a description structure.
function p = plot_sim_data(model, model_data, sim_data, plot_params)
function performing the plot of the simulation results as specified in model.
function model = thermalblock_model(params)
Thermal Block example similar as described in the book of A.T. patera and G. Rozza (just one paramete...
function res = thermalblock(step, params)
thermalblock example