rbmatlab 0.10.01
models/inspiration/fem_poisson.m
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;
All Classes Namespaces Files Functions Variables