rbmatlab 0.10.01
|
00001 function res = fem_poisson(step,params) 00002 %function res = fem_poisson(step) 00003 % 00004 % Script demonstrating lagrange finite element functions, using 00005 % them for function interpolation and finite element methods. 00006 % 00007 % Script realizing the simple poisson equation or a more complex 00008 % elliptic problem with arbitrary diffusivity_tensor, advection, 00009 % source, reaction, neumann , dirichlet and robin boundary 00010 % conditions on the unit square 00011 % with finite elements on triagrid discretization. 00012 % 00013 % step 1: some basic femdiscfunc demonstration and functionatity 00014 % step 2: use femdiscfunc for interpolating functions by local and 00015 % global evaluations 00016 % step 3: solve fem-problem, return errors 00017 % step 4 error convergence investigation 00018 % step 5: same as 3 by call of interface methods + Reduced basis steps 00019 % step 6: demo_rb_gui 00020 00021 % B. Haasdonk 11.1.2011 00022 00023 % adapted to new assembly 00024 00025 % Immanuel Maier 12.04.2011 00026 00027 % poisson_model 00028 00029 if nargin == 0 00030 step = 1; 00031 end; 00032 00033 if nargin < 2 00034 params = []; 00035 end; 00036 00037 res = []; 00038 00039 switch step 00040 00041 case 1 % elementary fem discrete function operations 00042 00043 params = []; 00044 pdeg = 4; 00045 params.pdeg = pdeg; 00046 params.dimrange = 3; 00047 % params.dimrange = 1; 00048 params.debug = 1; 00049 params.numintervals = 5; 00050 model = poisson_model(params); 00051 % convert to local_model: 00052 model = elliptic_discrete_model(model); 00053 grid = construct_grid(model); 00054 df_info = feminfo(params,grid); 00055 %tmp = load('circle_grid'); 00056 %grid = triagrid(tmp.p,tmp.t,[]); 00057 disp('model initialized'); 00058 00059 % without model_data, detailed_simulation, etc. but explicit 00060 % calls of fem operations 00061 00062 % initialize vectorial discrete function, extract scalar 00063 % component and plot basis function 00064 df = femdiscfunc([],df_info); % initialize zero df 00065 00066 fprintf('\n'); 00067 disp('initialization of femdiscfunc successful, display:'); 00068 display(df); 00069 00070 disp('press enter to continue'); 00071 pause; 00072 00073 % for check of dof consistency we have a plot routine: 00074 fprintf('\n'); 00075 disp('plot of global_dof_index map for consistency check:'); 00076 p = plot_dofmap(df); 00077 00078 disp('press enter to continue'); 00079 pause; 00080 00081 % global dof access: 00082 fprintf('\n'); 00083 disp('example of dof access, scalar component extraction and plot:'); 00084 % set second vector component in 4th basis function nonzero; 00085 ncomp = 2; 00086 locbasisfunc_index = 4; 00087 df.dofs((locbasisfunc_index-1)*df.dimrange+ncomp) = 1; 00088 dfscalar = scalar_component(df,2); % should be nonzero function 00089 disp(['entry should be 1 : ',... 00090 num2str(dfscalar.dofs(locbasisfunc_index))]); 00091 00092 params = []; 00093 params.subsampling_level = 6; 00094 figure,plot(dfscalar,params); 00095 dfscalar.dofs(:) = 0; % now zero again. 00096 % keyboard; 00097 00098 disp('press enter to continue'); 00099 pause; 00100 00101 fprintf('\n'); 00102 disp('example of local dof access:'); 00103 % local dof access via local to global map 00104 eind = 4; % set dof on element number 4 00105 lind = (pdeg+2); % local basis function index with lcoord (0,1/pdeg) 00106 dfscalar.dofs(dfscalar.global_dof_index(eind,lind)) = 1; 00107 00108 % example of local evaluation of femdiscfunc simultaneous on 00109 % several elements in the same local coordinate point 00110 elids = [4,6,7,10]; % evaluation on some elements 00111 lcoord = [0,1/pdeg]; % local coordinate vector == last point in all triangles 00112 f = evaluate(dfscalar,elids,lcoord); 00113 disp(['first entry should be 1 : ',num2str(f(1))]); 00114 % equivalent call (!) by () operator as abbreviation for local evaluation: 00115 f = dfscalar(elids,lcoord); 00116 disp(['first entry should be 1 : ',num2str(f(1))]); 00117 00118 disp('press enter to continue'); 00119 pause; 00120 00121 disp('examples of norm computation:') 00122 params.dimrange = 1; 00123 params.pdeg = 1; 00124 dfinfo1 = feminfo(params,grid); 00125 df1 = femdiscfunc([],dfinfo1); 00126 df1.dofs(:) = 1; 00127 disp(['L2-norm(f(x,y)=1) = ',num2str(fem_l2_norm(df1))]); 00128 disp(['H10-norm(f(x,y)=1) = ',num2str(fem_h10_norm(df1))]); 00129 df1.dofs(:) = df1.grid.X(:); 00130 disp(['L2-norm(f(x,y)=x) = ',num2str(fem_l2_norm(df1))]); 00131 disp(['H10-norm(f(x,y)=x) = ',num2str(fem_h10_norm(df1))]); 00132 df1.dofs(:) = df1.grid.Y(:); 00133 disp(['L2-norm(f(x,y)=y) = ',num2str(fem_l2_norm(df1))]); 00134 disp(['H10-norm(f(x,y)=y) = ',num2str(fem_h10_norm(df1))]); 00135 00136 disp('press enter to continue'); 00137 pause; 00138 00139 % evaluate df in all lagrange nodes of element 4 by loop 00140 fprintf('\n'); 00141 disp(['dfscalar on element 4 in all lagrange nodes,' ... 00142 'only (pdeg+2) entry should be 1:']); 00143 lagrange_nodes = lagrange_nodes_lcoord(pdeg); 00144 elid = 4; 00145 for i = 1:size(lagrange_nodes,1); 00146 f = evaluate(dfscalar,elid,lagrange_nodes(i,:)); 00147 disp(['f(l(',num2str(i),')) = ',num2str(f)]); 00148 end; 00149 00150 disp('press enter to continue'); 00151 pause; 00152 00153 fprintf('\n'); 00154 disp('example of requirement of subsampling in plot of discfuncs:'); 00155 figure; 00156 subsamp_levels = [0,2,4,16]; 00157 for i=1:length(subsamp_levels) 00158 subplot(2,2,i), 00159 params.axis_equal = 1; 00160 params.subsampling_level = subsamp_levels(i); 00161 params.clim = [-0.15 1.15]; % rough bounds 00162 plot(dfscalar,params); 00163 title(['subsampling level = ',num2str(subsamp_levels(i))]); 00164 end; 00165 00166 disp('end of step 1, please inspect variables, if required.') 00167 keyboard; 00168 00169 case 2 00170 00171 params = []; 00172 pdeg = 4; 00173 params.pdeg = pdeg; 00174 params.dimrange = 1; 00175 params.numintervals = 5; 00176 model = poisson_model(params); 00177 % convert to local_model: 00178 model = elliptic_discrete_model(model); 00179 grid = construct_grid(model); 00180 %tmp = load('circle_grid'); 00181 %grid = triagrid(tmp.p,tmp.t,[]); 00182 disp('model initialized'); 00183 00184 % interpolate exact solution and other coefficient functions 00185 % as fem-function and plot 00186 00187 disp('examples of interpolation of analytical functions:'); 00188 df_info=feminfo(model,grid); 00189 df = femdiscfunc([],df_info); 00190 00191 df = fem_interpol_global(model.solution, df); 00192 plot(df); 00193 title('analytical solution'); 00194 00195 % discretize source function and plot 00196 00197 % problems with fem_interpol_local!! 00198 %df = fem_interpol_local(model.source, df); 00199 df = fem_interpol_global(model.source, df); 00200 figure,plot(df); 00201 title('source function'); 00202 00203 disp('press enter to continue'); 00204 pause; 00205 00206 % discretize diffusivity and plot as 4-sequence 00207 % to be implemented for vectorial functions... 00208 %params.dimrange = 4; 00209 %df4 = femdiscfunc([],grid,params); 00210 %df4 = fem_interpol_global(model.diffusivity_tensor, df) 00211 % arrange as sequence of 4 scalar functions and plot 00212 %plot(df4); 00213 %title = 'diffusivity function'; 00214 00215 % example of local evaluation of vectorial basis function 00216 % on reference triangle 00217 disp('local evaluation of vectorial basis functions on reference triangle:'); 00218 lcoord = [0,1]; 00219 params = []; 00220 params.dimrange = 3; 00221 params.pdeg = 2; 00222 df2 = femdiscfunc([],df_info); 00223 res = fem_evaluate_basis(df2,lcoord) 00224 00225 disp('local evaluation of scalar basis functions derivative on reference triangle:'); 00226 res = fem_evaluate_scalar_basis_derivative(df,lcoord) 00227 00228 % later: 00229 % disp('local evaluation of vectorial basis function derivative on reference triangle:'); 00230 00231 % later: 00232 % interpolation error convergence with grid refinement 00233 00234 case 3 % finite element assembly, solution and plot. 00235 % different components assembled separately, as later 00236 % affine-decomposition will require such modularization 00237 00238 % assemble discrete system, solve and plot results 00239 00240 if isempty(params) 00241 params = []; 00242 params.dimrange = 1; 00243 pdeg = 1; 00244 qdeg = 3 * pdeg; % quadrature_degree 00245 params.pdeg = pdeg; 00246 params.qdeg = qdeg; 00247 params.numintervals = 20; 00248 params.no_plot = 0; %plotting active 00249 end; 00250 00251 no_plot = params.no_plot; 00252 00253 %model = poisson_model(params); 00254 model = elliptic_debug_model(params); 00255 model = elliptic_discrete_model(model); % convert to local_model 00256 grid = construct_grid(model); 00257 disp(['grid.nelements=',num2str(grid.nelements)]); 00258 % for debugging: set all to neumann 00259 % i = find(grid.NBI==-1); 00260 % grid.NBI(i)=-2; 00261 00262 df_info = feminfo(model,grid); 00263 disp(['df_info.ndofs=',num2str(df_info.ndofs)]); 00264 %tmp = load('circle_grid'); 00265 %grid = triagrid(tmp.p,tmp.t,[]); 00266 disp('model initialized'); 00267 00268 %%%%%%%%%%%%%%% assembly of system %%%%%%%%%%%%%%%%%%% 00269 00270 % assemble right hand side 00271 [r_source, r_dirichlet, r_neumann, r_robin] = ... 00272 fem_rhs_parts_assembly(model,df_info); 00273 r = r_source + r_neumann + r_robin + r_dirichlet; 00274 disp('rhs assembled'); 00275 00276 % sparse system matrix: 00277 A = spalloc(df_info.ndofs,df_info.ndofs,10); % rough upper bound for number of nonzeros 00278 [A_diff , A_adv, A_reac, A_dirichlet, A_neumann, A_robin] = ... 00279 fem_matrix_parts_assembly(model,df_info); 00280 A = A_diff + A_adv + A_reac + A_neumann + A_robin + A_dirichlet; 00281 disp('matrix assembled'); 00282 00283 %%%%%%%%%%%%%%% solve system %%%%%%%%%%%%%%%%%%% 00284 % solution variable 00285 u_h = femdiscfunc([],df_info); 00286 u_h.dofs = A\r; 00287 disp('system solved'); 00288 00289 %%%%%%%%%%%%%%% postprocessing %%%%%%%%%%%%%%%%%%% 00290 00291 if ~no_plot 00292 disp('plotting...'); 00293 % plot result 00294 params.subsampling_level = 10; 00295 figure, plot(u_h,params); 00296 title('discrete solution') 00297 end; 00298 00299 df = femdiscfunc([],df_info); 00300 df = fem_interpol_global(model.solution, df,model); 00301 if ~no_plot 00302 figure, plot(df); 00303 title('analytical solution'); 00304 end; 00305 00306 % plot error of (interpolated) exact solution and discrete sol. 00307 % interpolation using same degree as discrete solution 00308 e_h = femdiscfunc([],df_info); 00309 e_h = fem_interpol_global(model.solution, e_h,model); 00310 e_h.dofs = e_h.dofs -u_h.dofs; 00311 if ~no_plot 00312 figure, plot(e_h); 00313 title('rough error I\_rough(u)-u_h'); 00314 end; 00315 00316 if ~no_plot 00317 % better: choose high degree for interpolation of u 00318 % then require local_interpolation of u_h into high-resolved space 00319 params.pdeg = 4; % choose high degree 00320 00321 % map u_h to higher degree discretefunction 00322 params.has_dirichlet_values = 10; 00323 df_info_fine = feminfo(params,grid); 00324 u_h_fine = femdiscfunc([],df_info_fine); 00325 u_h_fine = fem_interpol_local(u_h, u_h_fine,model); 00326 e_h_fine = femdiscfunc([],df_info_fine); 00327 e_h_fine = fem_interpol_global(model.solution, e_h_fine,model); 00328 e_h_fine.dofs = e_h_fine.dofs -u_h_fine.dofs; 00329 figure, plot(e_h_fine); 00330 title('fine error I\_fine(u)-u_h'); 00331 end; 00332 00333 % determine error in L2 and H10 norm 00334 l2_err = fem_l2_norm(e_h); 00335 h10_err = fem_h10_norm(e_h); 00336 disp(['L2-error norm |u_h - I(u_exact)| = ',num2str(l2_err)]); 00337 disp(['H10-error norm |u_h - I(u_exact)| = ',num2str(h10_err)]); 00338 00339 if ~no_plot 00340 disp('solution and errors plotted. Inspect workspace.') 00341 keyboard; 00342 end; 00343 00344 res.l2_error = l2_err; 00345 res.h10_error = h10_err; 00346 00347 case 4 % error convergence investigation 00348 00349 params = []; 00350 params.dimrange = 1; 00351 pdeg = 2; 00352 qdeg = 3 * pdeg; % quadrature_degree 00353 params.pdeg = pdeg; 00354 params.qdeg = qdeg; 00355 params.no_plot = 1; 00356 00357 numintervals = [2,4,8,16,32,64,128,256]; 00358 l2_errs = zeros(length(numintervals),1); 00359 h10_errs = zeros(length(numintervals),1); 00360 for i = 1:length(numintervals) 00361 disp(['----------------------------------------------']); 00362 disp(['numintervals = ',num2str(numintervals(i))]); 00363 params.numintervals = numintervals(i); 00364 res = fem_poisson(3,params); 00365 l2_errs(i) = res.l2_error; 00366 h10_errs(i) = res.h10_error; 00367 end 00368 00369 case 5 % detailed and rb simulation by high-level methods 00370 00371 disp('detailed simulation:'); 00372 model = elliptic_debug_model; 00373 model = elliptic_discrete_model(model); 00374 model_data = gen_model_data(model); 00375 model = model.set_mu(model,[0,0,0]); 00376 sim_data = detailed_simulation(model,model_data); 00377 plot_params.title = 'detailed_solution'; 00378 figure, plot_sim_data(model,model_data,sim_data,plot_params); 00379 00380 disp('offline computations (gen_detailed_data: basis):'); 00381 detailed_data = gen_detailed_data(model,model_data); 00382 disp('offline computations II (gen_reduced_data: operator components):'); 00383 reduced_data = gen_reduced_data(model,detailed_data); 00384 00385 disp('online reduced simulation:'); 00386 model = model.set_mu(model,[0,0,0]); 00387 rb_sim_data = rb_simulation(model,reduced_data); 00388 rb_sim_data = rb_reconstruction(model, detailed_data, rb_sim_data); 00389 plot_params.title = 'reduced solution'; 00390 figure, plot_sim_data(model,model_data,rb_sim_data,plot_params); 00391 00392 eh = sim_data.uh - rb_sim_data.uh; 00393 l2_err = fem_l2_norm(eh); 00394 h10_err = fem_h10_norm(eh); 00395 disp(['L2-error: ',num2str(l2_err)]); 00396 disp(['H10-error: ',num2str(h10_err)]); 00397 00398 case 6 00399 00400 disp('demo_rb_gui:') 00401 model = elliptic_debug_model; 00402 model = elliptic_discrete_model(model); 00403 model_data = gen_model_data(model); 00404 detailed_data = gen_detailed_data(model,model_data); 00405 plot_params.axis_tight = 1; 00406 demo_rb_gui(model,detailed_data,[],plot_params); 00407 00408 end;