rbmatlab 0.10.01
models/thermalblock_descr.m
Go to the documentation of this file.
00001 function model = thermalblock_descr(params)
00002 % Thermal Block example similar as described in the book of 
00003 % A.T. patera and G. Rozza (just one parameter more)
00004 %
00005 % i.e. 
00006 % - div ( a(x) grad u(x)) = q(x)    on Omega
00007 %                   u(x)) = g_D(x)  on Gamma_D
00008 %     a(x) (grad u(x)) n) = g_N(x)  on Gamma_N
00009 %                       s = l(u) linear output functional
00010 %
00011 % where Omega = [0,1]^2 is divided into B1 * B2 blocks 
00012 % QA := B1*B2. The heat conductivities are given by mu_i:
00013 %
00014 %   -------------------------
00015 %   | ...   | ..... | mu_QA |
00016 %   -------------------------
00017 %   | ....  | ...   | ..... |
00018 %   -------------------------
00019 %   | mu_1  | ...   | mu_B1 |
00020 %   -------------------------
00021 %
00022 % `Gamma_D =` upper edge
00023 % `Gamma_N = boundary(Omega)\Gamma_D`
00024 %
00025 % `a(x) = mu_i(x) if x\in B_i`
00026 % `q(x) = 0`
00027 % `g_D  = 0` on top
00028 % `g_N  = 1` on lower edge, 0 otherwise
00029 % `l(u)` = average over lower edge
00030 
00031 % S. Langhof and B. Haasdonk 26.2.2011
00032 % I. Maier 26.04.2011
00033 
00034 model.name = 'thermalblock';
00035 model.dmodel_constructor = @ThermalBlock.DetailedModel;
00036 model.rb_problem_type = 'LinStat';
00037 
00038 % MD: Mein Vorschlag für simple Basis-Generierungsalgorithmen, verwendet
00039 % die Klasse SimpleDetailedData für die man den Konstruktor mittels eines
00040 % Funktionspointers spezifizieren kann. Genauso könnte man Simple* Klassen
00041 % für die anderen Interfaces, also DetailedModel, ReducedModel und
00042 % ReducedData implementieren. Das fände ich aber ehrlich gesagt unschön...
00043 % Die Basisgenerierung kann so simpel sein, dass es vielleicht Sinn macht,
00044 % die in eine kleine Funktion auszulagern, aber die anderen Klassen haben
00045 % meistens komplexere Datenstrukturen oder mehr Methoden, so dass die
00046 % "Description" Klasse wieder sehr unübersichtlich und intransparent wird,
00047 % wenn man das alles hier hinein packt...
00048 model.detailed_data_constructor = @SimpleDetailedData;
00049 
00050 model.RB_customized_basis_generation_ptr = @my_RB_basisgen;
00051 model.RB_train_rand_seed = 100;
00052 model.RB_train_size = 1000;
00053 model.RB_stop_epsilon = 1e-3;
00054 model.RB_stop_Nmax = 100;
00055 
00056 if nargin == 0
00057     params.B1=3;
00058     params.B2=3;
00059 %    model.default = '3x3 demo version';
00060 end
00061 % number of blocks in X and Y direction
00062 model.B1 = params.B1;
00063 model.B2 = params.B2;
00064 model.number_of_blocks = params.B1*params.B2;
00065 
00066 % each block has a different heat conductivity
00067 % upper left has conductivity 1
00068 mu_names = {};
00069 mu_ranges = {};
00070 mu_range = [0.1,10];
00071 for p = 1:model.number_of_blocks
00072   mu_names = [mu_names,{['mu',num2str(p)]}];
00073   mu_ranges = [mu_ranges,{mu_range}];
00074 end;
00075 model.mu_names = mu_names;
00076 model.mu_ranges = mu_ranges;
00077 
00078 %default values 1 everywhere
00079 model.mus = ones(model.number_of_blocks,1);
00080 
00081 % simple snapshots without orthogonalization
00082 model.RB_generation_mode = 'lagrangian';
00083 model.RB_mu_list = {[0.1,1,1,1,1,1,1,1,1],...
00084                     [1,0.1,1,1,1,1,1,1,1],...
00085                     [1,1,0.1,1,1,1,1,1,1],...
00086                     [1,1,1,0.1,1,1,1,1,1],...
00087                     [1,1,1,1,0.1,1,1,1,1],...
00088                     [1,1,1,1,1,0.1,1,1,1],...
00089                     [1,1,1,1,1,1,0.1,1,1],...
00090                     [1,1,1,1,1,1,1,0.1,1],...
00091                     [1,1,1,1,1,1,1,1,0.1]};
00092 
00093 %model.RB_generation_mode = 'model_RB_basisgen';
00094 
00095 
00096 
00097 %%%%%%%%% set data functions
00098 model.has_diffusivity = 1;
00099 model.has_output_functional = 1;
00100 model.has_dirichlet_values = 1;
00101 model.has_neumann_values = 1;
00102 
00103 % zero dirichlet values, i.e. 1 component, Q_dir = 1
00104 dirichlet_values_coefficients = @(dummy,params) [0];
00105 dirichlet_values_components = @(glob,params) {zeros(size(glob,1),1)};
00106 model.local_dirichlet_values = @(glob,params) ...
00107     eval_affine_decomp_general(dirichlet_values_components, ...
00108                                dirichlet_values_coefficients,glob,params);
00109 
00110 % 1/0 neumann values depending on edge, non parametric, i.e Q_neu = 1;
00111 neumann_values_coefficients = @(dummy,params) 1; % single component
00112 model.local_neumann_values = @(glob,params) ...
00113     eval_affine_decomp_general(@thermalblock_neumann_values_components, ...
00114                                neumann_values_coefficients, glob, params);
00115 
00116 % diffusion tensor: each row four entries a11,a_21,a_12,a_22. 
00117 % a11(x)=a22(x) = mu_i if x in block i, a12=a21 = 0. 
00118 diffusivity_tensor_coefficients = @(dummy,params) ...
00119     params.mus(:);
00120 model.local_diffusivity_tensor = @(glob,params) ...
00121     eval_affine_decomp_general(...
00122         @thermalblock_diffusivity_tensor_components, ...
00123         diffusivity_tensor_coefficients, glob,params);
00124 
00125 % only useful for detailed simulation or nonlinear outputs:
00126 %model.output_functional = @output_functional_boundary_integral;
00127 
00128 model.operators_output = @fem_operators_output_boundary_integral;
00129 % output weight function: simply 1 on lower edge, 0 else => Ql = 1 component
00130 output_function_components = @(glob,model) {1.0*(glob(:,2)<eps)};
00131 output_function_coefficients = @(glob,model) 1;
00132 model.output_function = @(glob,params) ...
00133     eval_affine_decomp_general(...
00134         output_function_components,...
00135         output_function_coefficients, glob,params);
00136 
00137 model.output_integral_qdeg = 2; %
00138 
00139 %%%%%%%%%% discretization settings
00140 
00141 if ~isfield(params,'numintervals_per_block')
00142   params.numintervals_per_block = 5;
00143 end;
00144 
00145 model.gridtype = 'triagrid';
00146 model.xnumintervals = params.numintervals_per_block*params.B1;
00147 model.ynumintervals = params.numintervals_per_block*params.B2;
00148 model.xrange = [0,1];
00149 model.yrange = [0,1];
00150 
00151 if ~isfield(params,'pdeg')
00152   params.pdeg = 1; 
00153 end;
00154 
00155 if ~isfield(params,'qdeg')
00156   params.qdeg = 2; 
00157 end;
00158 
00159 % numerics settings:
00160 model.pdeg = params.pdeg; % degree of polynomial functions
00161 model.qdeg = params.qdeg; % quadrature degree
00162 model.dimrange = 1; % scalar solution
00163 
00164 model.boundary_type = @thermalblock_boundary_type;
00165 %model.normals = @my_normals;
00166 
00167 % new plot routine, additional block boundaries are plotted
00168 model.compute_output_functional = 1;
00169 model.yscale_uicontrols = 0.2;
00170 
00171 % for error estimation:
00172 model.coercivity_alpha = @(model) min(model.mus(:));
00173 model.continuity_gamma = @(model) max(model.mus(:));
00174 model.enable_error_estimator = 1;
00175 
00176 % for making work with current dmodel/rmodel/descr decomposition
00177 model.crb_enabled = 0;
00178 
00179 % local data functions:
00180 %model = elliptic_discrete_model(model);
00181 
00182 %%%%%%% auxiliary functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00183 
00184 function res = thermalblock_boundary_type(glob,params)
00185   % returns the boundary type
00186 res = zeros(size(glob,1),1);
00187 i  = find(glob(:,1)<=1e-10);
00188 res(i) = -2;
00189 i  = find(glob(:,1)>=1-1e-10);
00190 res(i) = -2;
00191 i  = find(glob(:,2)<=1e-10);
00192 res(i) = -2;
00193 i  = find(glob(:,2)>=1-1e-10);
00194 res(i) = -1;
00195 
00196 function model = thermalblock_set_mu(model,mu)
00197 if length(mu)~=model.number_of_blocks
00198   error('length of mu does not fit to number of blocks!');
00199 end;
00200 model.mus = [mu(:)];
00201 
00202 function comp = thermalblock_neumann_values_components(glob,params) 
00203   % Neumann values component function
00204 res = zeros(size(glob,1),1);
00205 i = find(glob(:,2)<eps);
00206 res(i) = 1;
00207 comp = {res};
00208 
00209 function res = thermalblock_diffusivity_tensor_components(glob,params)
00210   % diffusivity tensor component function
00211 
00212 % for each point in glob find global block number
00213 % xi: range 0 ... B1-1
00214 xi = floor(glob(:,1)*params.B1);
00215 i = find(xi>=params.B1);
00216 if ~isempty(i)
00217   xi(i) = params.B1-1; 
00218 end;
00219 % xi: range 0 ... B1-1
00220 yi = floor(glob(:,2)*params.B2);
00221 i = find(yi>=params.B2);
00222 if ~isempty(i);
00223   yi(i) = params.B2-1; 
00224 end;
00225 block_index = yi*params.B1+xi+1;
00226 zeroblock = zeros(size(glob,1),4);
00227 res = cell(1,params.number_of_blocks);
00228 for q = 1:params.number_of_blocks;
00229   block = zeroblock;
00230   i = find(block_index==q);
00231   if ~isempty(i)
00232     block(i,1) = 1;
00233     block(i,4) = 1;
00234   end;
00235   res{q} = block;
00236 end;
00237 % check!
00238 %block = zeroblock;
00239 %for q=1:params.number_of_blocks;
00240 %  block = block + res{q};
00241 %end;
00242 %disp('check diffusivity matrix!')
00243 %keyboard;
00244 
00245 function alpha = thermalblock_coercivity_alpha(model)
00246 alpha = min(model.get_mu(model))
00247 
00248 %function [RBinit] = my_init_data_basis(model, ...
00249 %                                          detailed_data)
00250 
00251 function RB = my_RB_basisgen(rmodel,detailed_data)
00252 % simple greedy
00253 
00254 disp('entered my_RB_basisgen');
00255 
00256 sim_data = detailed_simulation(rmodel, detailed_data.model_data);
00257 n = fem_h10_norm(sim_data.uh);
00258 detailed_data.RB = sim_data.uh.dofs / n;
00259 reduced_data = gen_reduced_data(rmodel, detailed_data);
00260 h10_matrix = sim_data.uh.df_info.h10_inner_product_matrix;
00261 
00262 rng('default');
00263 mus = rand_uniform(rmodel.train_size,rmodel.mu_ranges);
00264 max_err_est = 1e10;
00265 
00266 while( max_err_est> rmodel.stop_epsilon) && ...
00267       (size(detailed_data.RB,2)< rmodel.stop_Nmax)
00268   max_err_est = 0;
00269   mu_max = [];
00270   tic;
00271   for i = 1:size(mus,2);
00272     set_mu(rmodel, mus(:,i));
00273     rb_sim_data = rb_simulation(rmodel,reduced_data);
00274     if rb_sim_data.Delta > max_err_est
00275       mu_max = mus(:,i);
00276       max_err_est = rb_sim_data.Delta; 
00277     end;
00278   end;
00279   toc
00280   disp(['max error estimator: ',num2str(max_err_est),...
00281         ' for mu = ',num2str(mu_max')]);
00282   set_mu(rmodel,mu_max);
00283   sim_data = detailed_simulation(rmodel,detailed_data.model_data);
00284   pr = sim_data.uh.dofs - ...
00285        detailed_data.RB * (detailed_data.RB' * h10_matrix * ...
00286                            sim_data.uh.dofs);
00287   n = sqrt(max(pr'*h10_matrix*pr,0));
00288   detailed_data.RB = [detailed_data.RB,pr/n];  
00289   reduced_data = gen_reduced_data(rmodel,detailed_data);
00290   disp(['new basis size: ',num2str(size(detailed_data.RB,2))]);
00291 end;
00292 
00293 RB = detailed_data.RB;
00294 
All Classes Namespaces Files Functions Variables