rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
DefaultInfo.m
1 classdef DefaultInfo < Fem.IFemInfo & DataTree.ILeafNode
2  %classdef LagrangeInfo < Fem.IFemInfo & DataTree.ILeafNode
3  % scalar Lagrange FE functions on triangular grid
4 
5  properties (SetAccess = private)
6 
7  pdeg;
8  dimrange = 1;
9  ndofs;
10  ndofs_per_element;
11  grid;
12 
13  basis_weight_matrix;
14 
15  % index vector of global DOFs
16  global_dof_index;
17 
18  dofs_lcoord;
19  dofs_edges_llcoord;
20 
21  % weight matrix for `L^2` inner product
22  l2_inner_product_matrix;
23 
24  % weight matrix for `H^1_0` inner product
25  h10_inner_product_matrix;
26 
27  dof_ids_local;
28  end
29 
30  properties (SetAccess = private, Dependent)
31 
32  detDF;
33  end
34 
35  methods
36 
37  function df_info = DefaultInfo(pdeg, grid)
38  %function df_info = DefaultInfo(pdeg, grid)
39  %
40  df_info.pdeg = pdeg;
41  df_info.dimrange = 1;
42  df_info.grid = grid;
43  df_info.ndofs = lagrange_ndofs(df_info);
44  df_info.ndofs_per_element = (pdeg+1) * (pdeg+2) / 2;
45 
46  df_info.dof_ids_local = {1:df_info.ndofs_per_element};
47 
48  df_info.global_dof_index = Fem.Lagrange.global_dof_index(df_info, grid);
49 
50  df_info.basis_weight_matrix = lagrange_basis_weight_matrix(df_info);
51 
52  df_info.dofs_lcoord = Fem.Lagrange.nodes_lcoord(pdeg);
53  df_info.dofs_edges_llcoord = Fem.Lagrange.nodes_edges_llcoord(df_info.dofs_lcoord);
54 
55  % reaction term == 1 then reaction matrix is l2matrix
56  model = [];
57  model.disable_caching = 1;
58  model.reaction = ...
59  @(grid, eindices, loc, params) ones(length(eindices), 1);
60  model.qdeg = 2*df_info.pdeg;
61  df_info.l2_inner_product_matrix = Fem.Assembly.matrix_part(...
62  @Fem.IntegralKernels.matrix_reaction, model, df_info);
63 
64  % H10_inner_product_matrix: identity diffusion
65  model.diffusivity_tensor = @(grid, eindices, loc, params) ...
66  [ones(length(eindices), 1), zeros(length(eindices), 1), ...
67  zeros(length(eindices), 1), ones(length(eindices), 1)];
68  df_info.h10_inner_product_matrix = Fem.Assembly.matrix_part(...
69  @Fem.IntegralKernels.matrix_diffusion, model, df_info);
70  end
71 
72  % copy constructor
73  function obj2 = copy(obj1)
74  obj2 = Fem.Lagrange.DefaultInfo(obj1.pdeg, obj1.grid);
75  end
76 
77  function detDF = get.detDF(this)
78  detDF = this.grid.A(:)*2;
79  end
80 
81  %function dof_ids_local = get.dof_ids_local(this)
82  % dof_ids_local = {1:this.ndofs_per_element};
83  %end
84 
85  function res = evaluate_basis(this, lcoord)
86  res = this.basis_weight_matrix * power_vector2(lcoord, this.pdeg);
87  end
88 
89  function res = evaluate_scalar_basis_derivative(this, lcoord, ~)
90  res = this.basis_weight_matrix * power_vector2_derivative(lcoord, this.pdeg);
91  end
92 
93  function res = evaluate_basis_function(this, lcoord, i)
94  res = this.basis_weight_matrix(i, :) * power_vector2(lcoord, this.pdeg);
95  end
96 
97  function res = evaluate_basis_function_derivative(this, lcoord, i)
98  res = this.basis_weight_matrix(i,:) * power_vector2_derivative(lcoord, this.pdeg);
99  end
100 
101  function res = get_global_dof_index(this, varargin)
102  if isempty(varargin)
103  res = this.global_dof_index;
104  else
105  res = this.global_dof_index(varargin{:});
106  end
107  end
108 
109  function res = get_dof_ids_global(this, ~)
110  res = 1:this.ndofs;
111  end
112 
113  function df = interpol_local(this, func, params)
114 
115  if nargin<3
116  params = [];
117  end
118 
119  df = Fem.DiscFunc([], this);
120  for i = 1:this.ndofs_per_element
121  df.dofs(this.global_dof_index(:, i)) = func(this.grid, 1:this.grid.nelements, ...
122  this.dofs_lcoord(i, :), params);
123  end
124  end
125 
126  p = plot_dofmap(this,params);
127 
128  end
129 
130  methods (Access = private, Hidden)
131 
132  function res = lagrange_ndofs(this)
133  ndof_nodes = this.grid.nvertices;
134  ndof_edges = (this.grid.nedges_interior + this.grid.nedges_boundary) * (this.pdeg-1);
135  ndof_elements = this.grid.nelements * (this.pdeg-1) * (this.pdeg-2) / 2;
136  res = ndof_nodes + ndof_edges + ndof_elements;
137  end
138 
139  function V = lagrange_basis_weight_matrix(this)
140 
141  switch this.pdeg
142  case 1
143  V = [1,-1,-1 ; ...
144  0, 1, 0; ...
145  0, 0, 1];
146  case 2
147  V = [1 -3 -3 2 4 2
148  0 4 0 -4 -4 0
149  0 -1 0 2 0 0
150  0 0 4 0 -4 -4
151  0 0 0 0 4 0
152  0 0 -1 0 0 2
153  ];
154  case 3
155  V = [
156  2 -11 -11 18 36 18 -9 -27 -27 -9
157  0 18 0 -45 -45 0 27 54 27 0
158  0 -9 0 36 9 0 -27 -27 0 0
159  0 2 0 -9 0 0 9 0 0 0
160  0 0 18 0 -45 -45 0 27 54 27
161  0 0 0 0 54 0 0 -54 -54 0
162  0 0 0 0 -9 0 0 27 0 0
163  0 0 -9 0 9 36 0 0 -27 -27
164  0 0 0 0 -9 0 0 0 27 0
165  0 0 2 0 0 -9 0 0 0 9
166  ] / 2;
167  case 4
168  V = [
169  3 -25 -25 70 140 70 -80 -240 -240 -80 32 128 192 128 32
170  0 48 0 -208 -208 0 288 576 288 0 -128 -384 -384 -128 0
171  0 -36 0 228 84 0 -384 -432 -48 0 192 384 192 0 0
172  0 16 0 -112 -16 0 224 96 0 0 -128 -128 0 0 0
173  0 -3 0 22 0 0 -48 0 0 0 32 0 0 0 0
174  0 0 48 0 -208 -208 0 288 576 288 0 -128 -384 -384 -128
175  0 0 0 0 288 0 0 -672 -672 0 0 384 768 384 0
176  0 0 0 0 -96 0 0 480 96 0 0 -384 -384 0 0
177  0 0 0 0 16 0 0 -96 0 0 0 128 0 0 0
178  0 0 -36 0 84 228 0 -48 -432 -384 0 0 192 384 192
179  0 0 0 0 -96 0 0 96 480 0 0 0 -384 -384 0
180  0 0 0 0 12 0 0 -48 -48 0 0 0 192 0 0
181  0 0 16 0 -16 -112 0 0 96 224 0 0 0 -128 -128
182  0 0 0 0 16 0 0 0 -96 0 0 0 0 128 0
183  0 0 -3 0 0 22 0 0 0 -48 0 0 0 0 32
184  ]/3;
185  otherwise
186  % these computations should not be done everytime!
187  % for higher pdeg, perhaps also use higher accuracy!!!
188  disp(['please hardcode the following matrix into' ...
189  ' Fem.Lagrange.DefaultInfo.lagrange_basis_weight_matrix:']);
190  % V = inv(P) where P = (p(l1),...p(lm)) powervector of lagrange-nodes
191  lagrange_nodes = this.dofs_lcoord;
192  P = zeros(size(lagrange_nodes,1));
193  for i = 1: size(lagrange_nodes,1)
194  P(:,i) = power_vector2(lagrange_nodes(i,:), this.pdeg);
195  end
196  V = inv(P);
197  end
198  end
199 
200  end
201 
202 end
203 
204 
scalar Lagrange FE functions on triangular grid
Definition: DefaultInfo.m:19
Interface for a leaf node of a data tree.
Definition: ILeafNode.m:18
represents a continous piecewise polynomial function of arbitrary dimension. Can be used for all fini...
Definition: DiscFunc.m:18
Abstract class for implementing finite elements. Fem info classes implementing this interface are com...
Definition: IFemInfo.m:18