rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
thermalblock_model.m
Go to the documentation of this file.
1 function model = thermalblock_model(params)
2 % Thermal Block example similar as described in the book of
3 % A.T. patera and G. Rozza (just one parameter more)
4 %
5 % i.e.
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
10 %
11 % where Omega = [0,1]^2 is divided into B1 * B2 blocks
12 % QA := B1*B2. The heat conductivities are given by mu_i:
13 %
14 % -------------------------
15 % | ... | ..... | mu_QA |
16 % -------------------------
17 % | .... | ... | ..... |
18 % -------------------------
19 % | mu_1 | ... | mu_B1 |
20 % -------------------------
21 %
22 % `Gamma_D =` upper edge
23 % `Gamma_N = boundary(Omega)\Gamma_D`
24 %
25 % `a(x) = mu_i(x) if x\in B_i`
26 % `q(x) = 0`
27 % `g_D = 0` on top
28 % `g_N = 1` on lower edge, 0 otherwise
29 % `l(u)` = average over lower edge
30 
31 % S. Langhof and B. Haasdonk 26.2.2011
32 % I. Maier 26.04.2011
33 
34 model = LinStat.descr_default;
35 %model = lin_stat_model_default;
36 model.name = 'thermalblock';
37 model.dmodel_constructor = @ThermalBlock.DetailedModel;
38 
39 % MD: Mein Vorschlag für simple Basis-Generierungsalgorithmen, verwendet
40 % die Klasse SimpleDetailedData für die man den Konstruktor mittels eines
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...
49 %model.detailed_data_constructor = @SimpleDetailedData;
50 
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;
56 
57 if nargin == 0 || ~isfield(params, 'B1')
58  params.B1=3;
59  params.B2=3;
60 % model.default = '3x3 demo version';
61 end
62 % number of blocks in X and Y direction
63 model.B1 = params.B1;
64 model.B2 = params.B2;
65 model.number_of_blocks = params.B1*params.B2;
66 
67 % each block has a different heat conductivity
68 % upper left has conductivity 1
69 mu_names = {};
70 mu_ranges = {};
71 if ~isfield(params,'mu_range')
72  params.mu_range = [0.1,10];
73 end;
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}];
78 end;
79 model.mu_names = mu_names;
80 model.mu_ranges = mu_ranges;
81 
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;
86 
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]};
98 
99 %model.RB_generation_mode = 'model_RB_basisgen';
100 
101 
102 
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;
108 
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);
115 
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);
121 
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) ...
125  params.mus(:);
126 model.diffusivity_tensor = @(glob,params) ...
127  eval_affine_decomp_general(...
128  @thermalblock_diffusivity_tensor_components, ...
129  diffusivity_tensor_coefficients, glob,params);
130 
131 % only useful for detailed simulation or nonlinear outputs:
132 %model.output_functional = @output_functional_boundary_integral;
133 
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);
142 
143 model.output_integral_qdeg = 2; %
144 
145 %%%%%%%%%% discretization settings
146 
147 if ~isfield(params,'numintervals_per_block')
148  params.numintervals_per_block = 5;
149 end;
150 
151 model.gridtype = 'triagrid';
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];
156 
157 if ~isfield(params,'pdeg')
158  params.pdeg = 1;
159 end;
160 
161 if ~isfield(params,'qdeg')
162  params.qdeg = 2;
163 end;
164 
165 % numerics settings:
166 model.pdeg = params.pdeg; % degree of polynomial functions
167 model.qdeg = params.qdeg; % quadrature degree
168 model.dimrange = 1; % scalar solution
169 
170 model.boundary_type = @thermalblock_boundary_type;
171 %model.normals = @my_normals;
172 
173 % new plot routine, additional block boundaries are plotted
174 model.plot_sim_data = @thermalblock_plot_sim_data;
175 model.compute_output_functional = 1;
176 model.yscale_uicontrols = 0.2;
177 
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;
182 
183 % for making work with current dmodel/rmodel/descr decomposition
184 model.descr = []; % model is its own description
185 model.crb_enabled = 0;
186 
187 % local data functions:
188 model = elliptic_discrete_model(model);
189 
190 %%%%%%% auxiliary functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191 
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);
196 res(i) = -2;
197 i = find(glob(:,1)>=1-1e-10);
198 res(i) = -2;
199 i = find(glob(:,2)<=1e-10);
200 res(i) = -2;
201 i = find(glob(:,2)>=1-1e-10);
202 res(i) = -1;
203 
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!');
207 end;
208 model.mus = [mu(:)];
209 
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);
214 res(i) = 1;
215 comp = {res};
216 
217 function res = thermalblock_diffusivity_tensor_components(glob,params)
218  % diffusivity tensor component function
219 
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);
224 if ~isempty(i)
225  xi(i) = params.B1-1;
226 end;
227 % xi: range 0 ... B1-1
228 yi = floor(glob(:,2)*params.B2);
229 i = find(yi>=params.B2);
230 if ~isempty(i);
231  yi(i) = params.B2-1;
232 end;
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;
237  block = zeroblock;
238  i = find(block_index==q);
239  if ~isempty(i)
240  block(i,1) = 1;
241  block(i,4) = 1;
242  end;
243  res{q} = block;
244 end;
245 % check!
246 %block = zeroblock;
247 %for q=1:params.number_of_blocks;
248 % block = block + res{q};
249 %end;
250 %disp('check diffusivity matrix!')
251 %keyboard;
252 
253 function alpha = thermalblock_coercivity_alpha(model)
254 alpha = min(model.get_mu(model))
255 
256 %function [RBinit] = my_init_data_basis(model, ...
257 % detailed_data)
258 
259 function RB = my_RB_basisgen(rmodel,detailed_data)
260 % simple greedy
261 
262 disp('entered my_RB_basisgen');
263 
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;
269 
270 % Kommentar MD: Alle Description Felder, die mit RB_ beginnen, werden von
271 % gen_reduced_model in das Feld bg_descr kopiert (ohne den Präfix 'RB_')
272 % (bg_descr.x == descr.RB_x)
273 bg_descr = rmodel.bg_descr;
274 
275 mus = rand_uniform(bg_descr.train_size,rmodel.mu_ranges);
276 max_err_est = 1e10;
277 
278 while( max_err_est> bg_descr.stop_epsilon) && ...
279  (size(detailed_data.RB,2)< bg_descr.stop_Nmax)
280  max_err_est = 0;
281  mu_max = [];
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
286  mu_max = mus(:,i);
287  max_err_est = rb_sim_data.Delta;
288  end;
289  end;
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 * ...
296  sim_data.uh.dofs);
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))]);
301 end;
302 
303 RB = detailed_data.RB;
304 
305 function p = thermalblock_plot_sim_data(model,detailed_data,sim_data, ...
306  plot_params)
307 if nargin<4
308  plot_params = [];
309 end;
310 %if ~isfield(plot_params,'no_lines')
311 plot_params.no_lines = 1;
312 %end;
313 p = lin_stat_plot_sim_data(model,detailed_data,sim_data,plot_params);
314 % plot coarse mesh
315 if ~isfield(plot_params,'plot_blocks')
316  plot_params.plot_blocks = 1;
317 end;
318 if plot_params.plot_blocks
319  X = [0:1/model.B1:1];
320  Y = [0:1/model.B2:1];
321  l1 = line([X;X],...
322  [zeros(1,model.B1+1);...
323  ones(1,model.B1+1)]);
324  set(l1,'color',[0,0,0],'linestyle','-.');
325  %keyboard;
326  l2 = line([zeros(1,model.B2+1);...
327  ones(1,model.B2+1)],...
328  [Y;Y]);
329  set(l2,'color',[0,0,0],'linestyle','-.');
330  p = [p(:);l1(:);l2(:)];
331 end;
Reduced basis implementation for linear stationary PDEs.
function ModelDescr descr = descr_default()
This function initializes the default settings for the ARE model.
Definition: descr_default.m:18
A triangular conforming grid in two dimensions.
Definition: triagrid.m:17
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.
Definition: plot_sim_data.m:17
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
Definition: thermalblock.m:17