rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
fem2_poisson.m
1 function res = fem2_poisson(step,params)
2 %function res = fem2_poisson(step,params)
3 %
4 % Script demonstrating lagrange finite element functions, using
5 % them for function interpolation and finite element methods.
6 %
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.
12 %
13 % step 1: some basic femdiscfunc demonstration and functionatity
14 % step 2: use femdiscfunc for interpolating functions by local and
15 % global evaluations
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
19 % step 6: demo_rb_gui
20 
21 % B. Haasdonk 11.1.2011
22 
23 % adapted to new assembly
24 
25 % Immanuel Maier 12.04.2011
26 
27 % poisson_model
28 
29 if nargin == 0
30  step = 1;
31 end;
32 
33 if nargin < 2
34  params = [];
35 end;
36 
37 res = [];
38 
39 switch step
40 
41  case 1 % elementary fem discrete function operations
42 
43  params = [];
44  pdeg = 4;
45  params.pdeg = pdeg;
46  params.dimrange = 3;
47  % params.dimrange = 1;
48  params.debug = 1;
49  params.numintervals = 5;
50  model = poisson_model(params);
51  % convert to local_model:
52  model = elliptic_discrete_model(model);
53  % convert to generic-fem model:
54  model = generic_fem_model_adapter(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)];
61  end
62  df_info = Fem.CompositeFunctionSpace(ids, repmat({df_info}, 1, params.dimrange));
63  %tmp = load('circle_grid');
64  %grid = triagrid(tmp.p,tmp.t,[]);
65  disp('model initialized');
66 
67  % without model_data, detailed_simulation, etc. but explicit
68  % calls of fem operations
69 
70  % initialize vectorial discrete function, extract scalar
71  % component and plot basis function
72  df = Fem.DiscFunc([],df_info); % initialize zero df
73 
74  fprintf('\n');
75  disp('initialization of femdiscfunc successful, display:');
76  display(df);
77 
78  disp('press enter to continue');
79  pause;
80 
81  % for check of dof consistency we have a plot routine:
82  fprintf('\n');
83  disp('plot of global_dof_index map for consistency check (scalar):');
84  p = plot_dofmap(get(df_info, 1));
85 
86  disp('press enter to continue');
87  pause;
88 
89  % global dof access:
90  fprintf('\n');
91  disp('example of dof access, scalar component extraction and plot:');
92  % set second vector component in 4th basis function nonzero;
93  ncomp = 2;
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))]);
99 
100  params = [];
101  params.subsampling_level = 6;
102  figure,plot(dfscalar,params);
103  dfscalar.dofs(:) = 0; % now zero again.
104 % keyboard;
105 
106  disp('press enter to continue');
107  pause;
108 
109  fprintf('\n');
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;
115 
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))]);
125 
126  disp('press enter to continue');
127  pause;
128 
129  disp('examples of norm computation:')
130  params.dimrange = 1;
131  params.pdeg = 1;
132  dfinfo1 = Fem.Lagrange.DefaultInfo(params.pdeg,grid);
133  df1 = Fem.DiscFunc([],dfinfo1);
134  df1.dofs(:) = 1;
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))]);
143 
144  disp('press enter to continue');
145  pause;
146 
147  % evaluate df in all lagrange nodes of element 4 by loop
148  fprintf('\n');
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);
152  elid = 4;
153  for i = 1:size(lagrange_nodes,1);
154  f = evaluate(dfscalar,elid,lagrange_nodes(i,:));
155  disp(['f(l(',num2str(i),')) = ',num2str(f)]);
156  end;
157 
158  disp('press enter to continue');
159  pause;
160 
161  fprintf('\n');
162  disp('example of requirement of subsampling in plot of discfuncs:');
163  figure;
164  subsamp_levels = [0,2,4,16];
165  for i=1:length(subsamp_levels)
166  subplot(2,2,i),
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))]);
172  end;
173 
174  disp('end of step 1, please inspect variables, if required.')
175  keyboard;
176 
177  case 2
178 
179  params = [];
180  pdeg = 4;
181  params.pdeg = pdeg;
182  params.dimrange = 1;
183  params.numintervals = 5;
184  model = poisson_model(params);
185  % convert to local_model:
186  model = elliptic_discrete_model(model);
187  % convert to generic-fem model:
188  model = generic_fem_model_adapter(model);
189  grid = construct_grid(model);
190  %tmp = load('circle_grid');
191  %grid = triagrid(tmp.p,tmp.t,[]);
192  disp('model initialized');
193 
194  % interpolate exact solution and other coefficient functions
195  % as fem-function and plot
196 
197  disp('examples of interpolation of analytical functions:');
198  df_info=Fem.Lagrange.DefaultInfo(model.pdeg,grid);
199 
200  df = interpol_global(df_info, model.solution);
201  plot(df);
202  title('analytical solution');
203 
204  % discretize source function and plot
205  df = interpol_local(df_info, model.source);
206  figure,plot(df);
207  title('source function');
208 
209  disp('press enter to continue');
210  pause;
211 
212  % discretize diffusivity and plot as 4-sequence
213  % to be implemented for vectorial functions...
214  %params.dimrange = 4;
215  %df4 = femdiscfunc([],grid,params);
216  %df4 = fem_interpol_global(model.diffusivity_tensor, df)
217  % arrange as sequence of 4 scalar functions and plot
218  %plot(df4);
219  %title = 'diffusivity function';
220 
221  % example of local evaluation of vectorial basis function
222  % on reference triangle
223  disp('local evaluation of vectorial basis functions on reference triangle:');
224  lcoord = [0,1];
225  params = [];
226  params.dimrange = 3;
227  params.pdeg = 2;
228  df2 = Fem.DiscFunc([],df_info);
229  res = evaluate_basis(df_info,lcoord)
230 
231  disp('local evaluation of scalar basis functions derivative on reference triangle:');
232  res = evaluate_scalar_basis_derivative(df_info,lcoord)
233 
234  % later:
235  % disp('local evaluation of vectorial basis function derivative on reference triangle:');
236 
237  % later:
238  % interpolation error convergence with grid refinement
239 
240  case 3 % finite element assembly, solution and plot.
241  % different components assembled separately, as later
242  % affine-decomposition will require such modularization
243 
244  % assemble discrete system, solve and plot results
245 
246  if isempty(params)
247  params = [];
248  params.dimrange = 1;
249  pdeg = 1;
250  qdeg = 3 * pdeg; % quadrature_degree
251  params.pdeg = pdeg;
252  params.qdeg = qdeg;
253  params.numintervals = 20;
254  params.no_plot = 0; %plotting active
255  end;
256 
257  no_plot = params.no_plot;
258 
259  %model = poisson_model(params);
260  model = elliptic_debug_model(params);
261  model = elliptic_discrete_model(model); % convert to local_model
262  % convert to generic-fem model:
263  model = generic_fem_model_adapter(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);
268  % grid.NBI(i)=-2;
269 
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');
275  %grid = triagrid(tmp.p,tmp.t,[]);
276  disp('model initialized');
277 
278  %%%%%%%%%%%%%%% assembly of system %%%%%%%%%%%%%%%%%%%
279 
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, ...
287  df_info);
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, ...
291  bc_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');
296 
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;
302  A_vol = Fem.Assembly.matrix_part(...
303  @(varargin) Fem.Assembly.add_integral_kernels(...
304  model.matrix_volume_int_kernel, varargin{:}), model, ...
305  df_info);
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');
315 
316  %%%%%%%%%%%%%%% solve system %%%%%%%%%%%%%%%%%%%
317  % solution variable
318  u_h = Fem.DiscFunc([],df_info);
319  u_h.dofs = A\r;
320  disp('system solved');
321 
322  %%%%%%%%%%%%%%% postprocessing %%%%%%%%%%%%%%%%%%%
323 
324  if ~no_plot
325  disp('plotting...');
326  % plot result
327  params.subsampling_level = 10;
328  figure, plot(u_h,params);
329  title('discrete solution')
330  end;
331 
332  df = interpol_global(df_info, model.solution, model);
333  if ~no_plot
334  figure, plot(df);
335  title('analytical solution');
336  end;
337 
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;
342  if ~no_plot
343  figure, plot(e_h);
344  title('rough error I\_rough(u)-u_h');
345  end;
346 
347  if ~no_plot
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
351 
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');
362  end;
363 
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)]);
369 
370  if ~no_plot
371  disp('solution and errors plotted. Inspect workspace.')
372  keyboard;
373  end;
374 
375  res.l2_error = l2_err;
376  res.h10_error = h10_err;
377 
378  case 4 % error convergence investigation
379 
380  params = [];
381  params.dimrange = 1;
382  pdeg = 2;
383  qdeg = 3 * pdeg; % quadrature_degree
384  params.pdeg = pdeg;
385  params.qdeg = qdeg;
386  params.no_plot = 1;
387 
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;
398  end
399 
400  case 5 % detailed and rb simulation by high-level methods
401 
402  disp('detailed simulation:');
403  model = elliptic_debug_model;
404  model = elliptic_discrete_model(model);
405  model = generic_fem_model_adapter(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);
411 
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);
416 
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);
423 
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)]);
429 
430  case 6
431 
432  disp('demo_rb_gui:')
433  model = elliptic_debug_model;
434  model = elliptic_discrete_model(model);
435  model = generic_fem_model_adapter(model);
436  model_data = gen_model_data(model);
437  detailed_data = gen_detailed_data(model,model_data);
438  plot_params.axis_tight = 1;
439  demo_rb_gui(model,detailed_data,[],plot_params);
440 
441 end
442 
443 end
class representing a continous piecewise polynomial function of arbitrary dimension. DOFS correspond to the values of Lagrange-nodes.
Definition: femdiscfunc.m:17
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.
Definition: triagrid.m:17
function demo_rb_gui(varargin)
reduced basis demo with sliders
Definition: demo_rb_gui.m:17
Composite function space for composition of FE function spaces on same grid.
dofs
DOF vector.
Definition: DiscFunc.m:70
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...
Definition: DiscFunc.m:18
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