rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
BubbleInfo.m
1 classdef BubbleInfo < Fem.IFemInfo & DataTree.ILeafNode
2  %classdef LagrangeBubbleInfo < Fem.IFemInfo & DataTree.ILeafNode
3  % scalar Lagrange FE functions (degree 1) with additional bubble function
4  % on triangular grid
5 
6  % could possibly be generalized to arbitrary pdeg of Lagrange basis
7 
8  % I. Maier 14.08.2012
9 
10  properties (SetAccess = private)
11 
12  pdeg = 3;
13 
14  dimrange = 1;
15 
16  ndofs;
17 
18  ndofs_per_element = 4;
19 
20  grid;
21 
22  basis_weight_matrix;
23 
24  dofs_lcoord;
25 
26  dofs_edges_llcoord;
27 
28  l2_inner_product_matrix;
29 
30  h10_inner_product_matrix;
31 
32  dof_ids_local;
33  end
34 
35  properties (SetAccess = private, Dependent)
36 
37  detDF;
38  end
39 
40  methods
41 
42  function lbi = BubbleInfo(~, grid)
43  %function velocity_df_info = BubbleInfo(~, grid)
44  % constructor
45 
46  lbi.dof_ids_local = {1:lbi.ndofs_per_element};
47 
48  lbi.grid = grid;
49  lbi.ndofs = grid.nvertices + grid.nelements;
50 
51  % basis weight matrix
52  lbi.basis_weight_matrix = ...
53  [1,-1,-1, 0, 0, 0, 0, 0, 0, 0; ...
54  0, 1, 0, 0, 0, 0, 0, 0, 0, 0; ...
55  0, 0, 1, 0, 0, 0, 0, 0, 0, 0; ...
56  0, 0, 0, 0,27, 0, 0,-27,-27, 0];
57 
58  % local coordinates of dofs
59  lbi.dofs_lcoord = [0, 0; 1, 0; 0, 1; 1/3 1/3];
60 
61  % edge-local coordinates of dofs
62  lbi.dofs_edges_llcoord = Fem.Lagrange.nodes_edges_llcoord(lbi.dofs_lcoord);
63 
64  % reaction term == 1 then reaction matrix is l2matrix
65  model = [];
66  model.disable_caching = 1;
67  model.reaction = ...
68  @(grid, eindices, loc, params) ones(length(eindices), 1);
69  model.qdeg = 2*lbi.pdeg;
70  lbi.l2_inner_product_matrix = Fem.Assembly.matrix_part(...
71  @Fem.IntegralKernels.matrix_reaction, model, lbi);
72 
73  % H10_inner_product_matrix: identity diffusion
74  model.diffusivity_tensor = @(grid, eindices, loc, params) ...
75  [ones(length(eindices), 1), zeros(length(eindices), 1), ...
76  zeros(length(eindices), 1), ones(length(eindices), 1)];
77  lbi.h10_inner_product_matrix = Fem.Assembly.matrix_part(...
78  @Fem.IntegralKernels.matrix_diffusion, model, lbi);
79  end
80 
81  % copy constructor
82  function obj2 = copy(obj1)
83  obj2 = Fem.Lagrange.BubbleInfo([], obj1.grid);
84  end
85 
86  %function dof_ids_local = get.dof_ids_local(this)
87  % dof_ids_local = {1:this.ndofs_per_element};
88  %end
89 
90  function detDF = get.detDF(this)
91  detDF = 2 * this.grid.A;
92  end
93 
94  function res = get_global_dof_index(this, einds, gids)
95  % returns entries of global-dof-map for several elements and several
96  % local dof ids
97  global_dof_index = ...
98  [this.grid.VI, this.grid.nvertices + (1:this.grid.nelements)'];
99  res = global_dof_index(einds, gids);
100  end
101 
102  function res = get_dof_ids_global(this, ~)
103  % returns global dof ids belonging to one component (indices into
104  % DOF-vector)
105  res = 1:this.ndofs;
106  end
107 
108  function res = evaluate_basis(this, lcoord)
109  % evaluation of all basis functions in local coordinate
110  res = this.basis_weight_matrix * power_vector2(lcoord, this.pdeg);
111  end
112 
113  function res = evaluate_scalar_basis_derivative(this, lcoord, ~)
114  % evaluation of the gradient of a scalar basis in local coordinate
115  res = this.basis_weight_matrix * power_vector2_derivative(lcoord, this.pdeg);
116  end
117 
118  function res = evaluate_basis_function(this, lcoord, i)
119  % evaluation of i-th basis function in local coordinate
120  res = this.basis_weight_matrix(i, :) * power_vector2(lcoord, this.pdeg);
121  end
122 
123  function res = evaluate_basis_function_derivative(this, lcoord, i)
124  % evaluation of the gradient of i-th basis function in local
125  % coordinate
126  res = this.basis_weight_matrix(i,:) * power_vector2_derivative(lcoord, this.pdeg);
127  end
128 
129  function df = interpol_local(this, func, params)
130  % interpolating a given analytical function
131  % input:
132  % - func: function which can be evaluated at
133  % @(grid, elinds, lcoord, params)
134 
135  if nargin<3
136  params = [];
137  end
138 
139  df = Fem.DiscFunc([], this);
140 
141  for i = 1:(this.ndofs_per_element - 1)
142 
143  gids = this.get_global_dof_index(1:this.grid.nelements, i);
144  df.dofs(gids) = func(this.grid, 1:this.grid.nelements, ...
145  this.dofs_lcoord(i, :), params);
146  end
147 
148  interp_error = triaquadrature(3, @(lcoord) ...
149  func(this.grid, 1:this.grid.nelements, lcoord, params) - ...
150  df(1:this.grid.nelements, lcoord));
151 
152  bubble_integr = triaquadrature(3, ...
153  @(lcoord) this.evaluate_basis_function(lcoord, this.ndofs_per_element));
154 
155  gids = this.get_global_dof_index(1:this.grid.nelements, this.ndofs_per_element);
156  df.dofs(gids) = interp_error / bubble_integr(1); % detDF cancels out
157  end
158 
159  end
160 
161 end
Interface for a leaf node of a data tree.
Definition: ILeafNode.m:18
scalar Lagrange FE functions (degree 1) with additional bubble function on triangular grid ...
Definition: BubbleInfo.m:19
Abstract class for implementing finite elements. Fem info classes implementing this interface are com...
Definition: IFemInfo.m:18