1 function res = fem2_poisson(step,params)
2 %
function res = fem2_poisson(step,params)
4 % Script demonstrating lagrange finite element functions,
using
5 % them
for function interpolation and finite element methods.
7 % Script realizing the simple poisson equation or a more complex
8 % elliptic problem with arbitrary diffusivity_tensor, advection,
9 % source, reaction, neumann , dirichlet and robin boundary
10 % conditions on the unit square
11 % with finite elements on
triagrid discretization.
13 % step 1: some basic
femdiscfunc demonstration and functionatity
14 % step 2: use
femdiscfunc for interpolating functions by local and
16 % step 3: solve fem-problem,
return errors
17 % step 4 error convergence investigation
18 % step 5: same as 3 by call of
interface methods + Reduced basis steps
21 % B. Haasdonk 11.1.2011
23 % adapted to
new assembly
25 % Immanuel Maier 12.04.2011
41 case 1 % elementary fem discrete
function operations
47 % params.dimrange = 1;
49 params.numintervals = 5;
50 model = poisson_model(params);
51 % convert to local_model:
53 % convert to
generic-fem model:
55 grid = construct_grid(model);
56 % generate
function info (composite)
57 df_info =
Fem.Lagrange.DefaultInfo(model.pdeg, grid);
58 ids = cell(1, params.dimrange);
59 for i = 1:params.dimrange
60 ids{i} = [
'dim', num2str(i)];
63 %tmp = load(
'circle_grid');
65 disp(
'model initialized');
67 % without model_data, detailed_simulation, etc. but
explicit
68 % calls of fem operations
70 % initialize vectorial discrete
function, extract scalar
71 % component and plot basis
function
75 disp(
'initialization of femdiscfunc successful, display:');
78 disp(
'press enter to continue');
81 %
for check of dof consistency we have a plot routine:
83 disp(
'plot of global_dof_index map for consistency check (scalar):');
84 p = plot_dofmap(
get(df_info, 1));
86 disp(
'press enter to continue');
91 disp(
'example of dof access, scalar component extraction and plot:');
92 % set second vector component in 4th basis
function nonzero;
94 locbasisfunc_index = 4;
95 df.dofs((ncomp-1)*df.ndofs/df.dimrange+locbasisfunc_index) = 1;
96 dfscalar = get_component(df,2); % should be nonzero
function
97 disp([
'entry should be 1 : ',...
98 num2str(dfscalar.dofs(locbasisfunc_index))]);
101 params.subsampling_level = 6;
102 figure,plot(dfscalar,params);
103 dfscalar.dofs(:) = 0; % now zero again.
106 disp(
'press enter to continue');
110 disp(
'example of local dof access:');
111 % local dof access via local to global map
112 eind = 4; % set dof on element number 4
113 lind = (pdeg+2); % local basis
function index with lcoord (0,1/pdeg)
114 dfscalar.dofs(dfscalar.df_info.global_dof_index(eind,lind)) = 1;
116 % example of local evaluation of
femdiscfunc simultaneous on
117 % several elements in the same local coordinate point
118 elids = [4,6,7,10]; % evaluation on some elements
119 lcoord = [0,1/pdeg]; % local coordinate vector == last point in all triangles
120 f = evaluate(dfscalar,elids,lcoord);
121 disp(['first entry should be 1 : ',num2str(f(1))]);
122 % equivalent call (!) by () operator as abbreviation for local evaluation:
123 f = dfscalar(elids,lcoord);
124 disp(['first entry should be 1 : ',num2str(f(1))]);
126 disp('press enter to continue');
129 disp('examples of norm computation:')
132 dfinfo1 =
Fem.Lagrange.DefaultInfo(params.pdeg,grid);
133 df1 =
Fem.DiscFunc([],dfinfo1);
135 disp(['L2-norm(f(x,y)=1) = ',num2str(l2_norm(df1))]);
136 disp(['H10-norm(f(x,y)=1) = ',num2str(h10_norm(df1))]);
137 df1.dofs(:) = df1.grid.X(:);
138 disp(['L2-norm(f(x,y)=x) = ',num2str(l2_norm(df1))]);
139 disp(['H10-norm(f(x,y)=x) = ',num2str(h10_norm(df1))]);
140 df1.dofs(:) = df1.grid.Y(:);
141 disp(['L2-norm(f(x,y)=y) = ',num2str(l2_norm(df1))]);
142 disp(['H10-norm(f(x,y)=y) = ',num2str(h10_norm(df1))]);
144 disp('press enter to continue');
147 % evaluate df in all lagrange nodes of element 4 by loop
149 disp(['dfscalar on element 4 in all lagrange nodes,' ...
150 'only (pdeg+2) entry should be 1:']);
151 lagrange_nodes =
Fem.Lagrange.nodes_lcoord(pdeg);
153 for i = 1:size(lagrange_nodes,1);
154 f = evaluate(dfscalar,elid,lagrange_nodes(i,:));
155 disp(['f(l(',num2str(i),')) = ',num2str(f)]);
158 disp('press enter to continue');
162 disp('example of requirement of subsampling in plot of discfuncs:');
164 subsamp_levels = [0,2,4,16];
165 for i=1:length(subsamp_levels)
167 params.axis_equal = 1;
168 params.subsampling_level = subsamp_levels(i);
169 params.clim = [-0.15 1.15]; % rough bounds
170 plot(dfscalar,params);
171 title(['subsampling level = ',num2str(subsamp_levels(i))]);
174 disp('end of step 1, please inspect variables, if required.')
183 params.numintervals = 5;
184 model = poisson_model(params);
185 % convert to local_model:
187 % convert to generic-fem model:
189 grid = construct_grid(model);
190 %tmp = load('circle_grid');
192 disp('model initialized');
194 % interpolate exact solution and other coefficient functions
195 % as fem-function and plot
197 disp('examples of interpolation of analytical functions:');
198 df_info=
Fem.Lagrange.DefaultInfo(model.pdeg,grid);
200 df = interpol_global(df_info, model.solution);
202 title('analytical solution');
204 % discretize source function and plot
205 df = interpol_local(df_info, model.source);
207 title('source function');
209 disp('press enter to continue');
212 % discretize diffusivity and plot as 4-sequence
213 % to be implemented for vectorial functions...
214 %params.dimrange = 4;
216 %df4 = fem_interpol_global(model.diffusivity_tensor, df)
217 % arrange as sequence of 4 scalar functions and plot
219 %title = 'diffusivity function';
221 % example of local evaluation of vectorial basis function
222 % on reference triangle
223 disp('local evaluation of vectorial basis functions on reference triangle:');
228 df2 =
Fem.DiscFunc([],df_info);
229 res = evaluate_basis(df_info,lcoord)
231 disp('local evaluation of scalar basis functions derivative on reference triangle:');
232 res = evaluate_scalar_basis_derivative(df_info,lcoord)
235 % disp('local evaluation of vectorial basis function derivative on reference triangle:');
238 % interpolation error convergence with grid refinement
240 case 3 % finite element assembly, solution and plot.
241 % different components assembled separately, as later
242 % affine-decomposition will require such modularization
244 % assemble discrete system, solve and plot results
250 qdeg = 3 * pdeg; % quadrature_degree
253 params.numintervals = 20;
254 params.no_plot = 0; %plotting active
257 no_plot = params.no_plot;
259 %model = poisson_model(params);
260 model = elliptic_debug_model(params);
262 % convert to generic-fem model:
264 grid = construct_grid(model);
265 disp(['grid.nelements=',num2str(grid.nelements)]);
266 % for debugging: set all to neumann
267 % i = find(grid.NBI==-1);
270 df_info =
Fem.Lagrange.DefaultInfo(model.pdeg,grid);
271 % generate information for boundary conditions:
272 bc_info =
Fem.BcInfo(model, grid, df_info);
273 disp(['df_info.ndofs=',num2str(df_info.ndofs)]);
274 %tmp = load('circle_grid');
276 disp('model initialized');
278 %%%%%%%%%%%%%%% assembly of system %%%%%%%%%%%%%%%%%%%
280 % assemble right hand side
281 %[r_source, r_dirichlet, r_neumann, r_robin] = ...
282 % fem_rhs_parts_assembly(model,df_info);
283 %r = r_source + r_neumann + r_robin + r_dirichlet;
284 r_vol =
Fem.Assembly.rhs_part(...
285 @(varargin)
Fem.Assembly.add_integral_kernels(...
286 model.rhs_volume_int_kernel, varargin{:}), model, ...
288 r_bnd =
Fem.
Assembly.rhs_part(model.rhs_boundary_int_kernel, ...
289 model, df_info, bc_info);
290 r_dir =
Fem.
Assembly.dirichlet_dof_vector(model, df_info, ...
292 r_vol(bc_info.dirichlet_gids) = 0;
293 r_bnd(bc_info.dirichlet_gids) = 0;
294 r = r_vol + r_bnd + r_dir;
295 disp(
'rhs assembled');
297 % sparse system matrix:
298 A = spalloc(df_info.ndofs,df_info.ndofs,10); % rough upper bound
for number of nonzeros
299 %[A_diff , A_adv, A_reac, A_dirichlet, A_neumann, A_robin] = ...
300 % fem_matrix_parts_assembly(model,df_info);
301 %A = A_diff + A_adv + A_reac + A_neumann + A_robin + A_dirichlet;
304 model.matrix_volume_int_kernel, varargin{:}), model, ...
306 A_bnd =
Fem.
Assembly.matrix_part(model.matrix_boundary_int_kernel, ...
307 model, df_info, bc_info);
308 dir_gids = bc_info.dirichlet_gids;
309 A_dir= sparse(dir_gids, dir_gids, ones(size(dir_gids)), ...
310 df_info.ndofs, df_info.ndofs);
311 A_vol(dir_gids, :) = 0;
312 A_bnd(dir_gids, :) = 0;
313 A = A_vol + A_bnd + A_dir;
314 disp(
'matrix assembled');
316 %%%%%%%%%%%%%%% solve system %%%%%%%%%%%%%%%%%%%
320 disp(
'system solved');
322 %%%%%%%%%%%%%%% postprocessing %%%%%%%%%%%%%%%%%%%
327 params.subsampling_level = 10;
328 figure, plot(u_h,params);
329 title(
'discrete solution')
332 df = interpol_global(df_info, model.solution, model);
335 title('analytical solution');
338 % plot error of (interpolated) exact solution and discrete sol.
339 % interpolation using same degree as discrete solution
340 e_h = interpol_global(df_info, model.solution, model);
341 e_h.dofs = e_h.dofs -u_h.dofs;
344 title('rough error I\_rough(u)-u_h');
348 % better: choose high degree for interpolation of u
349 % then require local_interpolation of u_h into high-resolved space
350 params.pdeg = 4; % choose high degree
352 % map u_h to higher degree discretefunction
353 %params.has_dirichlet_values = 10;
354 df_info_fine =
Fem.Lagrange.DefaultInfo(params.pdeg,grid);
355 u_h_loc = @(grid,elids,lcoord,params) ...
356 u_h(elids,lcoord,params); % no grid-input for
femdiscfunc
357 u_h_fine = interpol_local(df_info_fine, u_h_loc, model);
358 e_h_fine = interpol_global(df_info_fine, model.solution, model);
359 e_h_fine.dofs = e_h_fine.dofs -u_h_fine.dofs;
360 figure, plot(e_h_fine);
361 title('fine error I\_fine(u)-u_h');
364 % determine error in L2 and H10 norm
365 l2_err = l2_norm(e_h);
366 h10_err = h10_norm(e_h);
367 disp(['L2-error norm |u_h - I(u_exact)| = ',num2str(l2_err)]);
368 disp(['H10-error norm |u_h - I(u_exact)| = ',num2str(h10_err)]);
371 disp('solution and errors plotted. Inspect workspace.')
375 res.l2_error = l2_err;
376 res.h10_error = h10_err;
378 case 4 % error convergence investigation
383 qdeg = 3 * pdeg; % quadrature_degree
388 numintervals = [2,4,8,16,32,64,128,256];
389 l2_errs = zeros(length(numintervals),1);
390 h10_errs = zeros(length(numintervals),1);
391 for i = 1:length(numintervals)
392 disp(['----------------------------------------------']);
393 disp(['numintervals = ',num2str(numintervals(i))]);
394 params.numintervals = numintervals(i);
395 res = fem2_poisson(3,params);
396 l2_errs(i) = res.l2_error;
397 h10_errs(i) = res.h10_error;
400 case 5 % detailed and rb simulation by high-level methods
402 disp('detailed simulation:');
403 model = elliptic_debug_model;
406 model_data = gen_model_data(model);
407 model = model.set_mu(model,[0,0,0]);
408 sim_data = detailed_simulation(model,model_data);
409 plot_params.title = 'detailed solution';
410 figure,
plot_sim_data(model,model_data,sim_data,plot_params);
412 disp('offline computations (gen_detailed_data: basis):');
413 detailed_data = gen_detailed_data(model,model_data);
414 disp('offline computations II (gen_reduced_data: operator components):');
415 reduced_data = gen_reduced_data(model,detailed_data);
417 disp('online reduced simulation:');
418 model = model.set_mu(model,[0,0,0]);
419 rb_sim_data = rb_simulation(model,reduced_data);
420 rb_sim_data = rb_reconstruction(model, detailed_data, rb_sim_data);
421 plot_params.title = 'reduced solution';
422 figure,
plot_sim_data(model,model_data,rb_sim_data,plot_params);
424 eh = sim_data.uh - rb_sim_data.uh;
425 l2_err = l2_norm(eh);
426 h10_err = h10_norm(eh);
427 disp(['L2-error: ',num2str(l2_err)]);
428 disp(['H10-error: ',num2str(h10_err)]);
433 model = elliptic_debug_model;
436 model_data = gen_model_data(model);
437 detailed_data = gen_detailed_data(model,model_data);
438 plot_params.axis_tight = 1;
class representing a continous piecewise polynomial function of arbitrary dimension. DOFS correspond to the values of Lagrange-nodes.
function model = generic_fem_model_adapter(model)
Initializes a default linear and stationary model for more generic fem discretization by modifying mo...
A triangular conforming grid in two dimensions.
function demo_rb_gui(varargin)
reduced basis demo with sliders
Composite function space for composition of FE function spaces on same grid.
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.
represents a continous piecewise polynomial function of arbitrary dimension. Can be used for all fini...
function p = plot_sim_data(model, model_data, sim_data, plot_params)
function performing the plot of the simulation results as specified in model.