1 classdef DiscFunc < handle
2 % represents a continous piecewise polynomial
function of arbitrary
3 % dimension. Can be used
for all finite elements (discrete
function
6 % `dofs` correspond to the values of the nodes.
7 % `df_info` is an
object of discrete
function information.
9 % Bernard Haasdonk 11.1.2011
17 % dimension of range space
20 % grid of type .gridbase
23 % discrete
function information of type .IFemInfo
35 % number of DOFs per grid element
38 % global coordinate of DOFs
39 dofs_global_coordinate;
44 function df =
DiscFunc(dofs, df_info)
45 % constructor, dofs possibly [], grid required!
48 % dofs: a vector of #
'df.ndofs' global degress of freedom
for the
49 % discrete
function,
if '==[]' a zero vector is created.
50 % df_info:
object of type .IFemInfo describing the structure of the
51 % underlying discrete
function space
53 % required fields of df_info:
54 % pdeg: polynomial degree of lagrange functions
55 % dimrange: dimension of the range
58 df.pdeg = df_info.pdeg;
59 df.dimrange = df_info.dimrange;
60 df.grid = df_info.grid;
65 df.nelements = df_info.grid.nelements;
66 df.ndofs = df_info.ndofs;
67 df.ndofs_per_element = df_info.ndofs_per_element;
69 df.dofs = zeros(df.ndofs,1);
72 df.dofs_global_coordinate = zeros(df.ndofs, 2);
73 for i = 1:df.ndofs_per_element
74 df.dofs_global_coordinate(df_info.get_global_dof_index(':', i), :) ...
75 = local2global(df.grid, 1:df.nelements, df_info.dofs_lcoord(i, :), []);
79 function cdf = get_component(this, ncomp)
80 % extraction of component of vectorial fem function
83 cdf_info = get(this.df_info, ncomp);
84 indices = this.df_info.get_dof_ids_global(ncomp);
88 function p = plot(this, params)
90 % todo: ids as titles. enhanced subplots
98 for i = 1:length(this.df_info)
100 df = get_component(this, i);
102 params.title = this.df_info.idmap{i};
107 p = plot(df, params);
111 p = plot_discfunc(
this, params);
112 if isfield(params,
'title')
118 function res = evaluate(this, einds, lcoord, varargin)
119 % local evaluate on several elements
121 if isa(einds, '
gridbase') % for compatibility reasons
124 lcoord = varargin{1};
127 % indices (all dimensions)
128 if strcmp(einds,
':')
129 gids = this.df_info.get_global_dof_index();
131 gids = this.df_info.get_global_dof_index(...
132 einds, 1:this.ndofs_per_element);
135 % get values and compute
138 d = reshape(d, size(gids, 1), this.ndofs_per_element);
139 basis_values = evaluate_basis(this.df_info, lcoord);
140 res = d * basis_values;
143 function res = evaluate_derivative(this, einds, lcoord)
144 % computes the gradient in local coordinate
145 % res(:, i, j) is the x_i derivative of the j-th component
147 % indices (all dimensions)
148 if strcmp(einds, ':')
149 gids = this.df_info.get_global_dof_index();
152 gids = this.df_info.get_global_dof_index(...
153 einds, 1:this.ndofs_per_element);
154 JIT = this.grid.JIT(einds, :, :);
160 res = zeros(size(gids, 1), 2, this.dimrange);
161 for i = 1:this.dimrange
163 grad_hat_basis = evaluate_scalar_basis_derivative(this.df_info, lcoord, i);
165 % basis gradients on elements
166 gradx_basis = JIT(:, 1, 1) * grad_hat_basis(:, 1)' ...
167 + JIT(:, 1, 2) * grad_hat_basis(:, 2)';
168 grady_basis = JIT(:, 2, 1) * grad_hat_basis(:, 1)' ...
169 + JIT(:, 2, 2) * grad_hat_basis(:, 2)';
171 res(:, 1, i) = sum(gradx_basis .* d(:, this.df_info.dof_ids_local{i}), 2);
172 res(:, 2, i) = sum(grady_basis .* d(:, this.df_info.dof_ids_local{i}), 2);
176 function res = l2_norm(
this)
177 % computes the l2-norm
179 res_sqr = this.dofs(:)
' * ...
180 this.df_info.l2_inner_product_matrix * this.dofs(:);
189 function res = h10_norm(this)
192 res_sqr = this.dofs(:)' * ...
193 this.df_info.h10_inner_product_matrix * this.dofs(:);
202 function res = h1_norm(
this)
205 res_sqr = this.dofs(:)
' * ...
206 (this.df_info.l2_inner_product_matrix + ...
207 this.df_info.h10_inner_product_matrix) * this.dofs(:);
216 function res = subsref(this, S)
217 % This method enables indexation of discrete functions
219 % redirects arguments to evaluate function, so
221 % df(einds, lcoord) == df.evaluate(einds, lcoord)
227 res = builtin('subsref
', this, S);
229 res = this.evaluate(S.subs{:});
234 function cdf = copy(this)
236 cdf = Fem.DiscFunc(this.dofs, this.df_info);
240 function df3 = plus(df1, df2)
242 df3 = Fem.DiscFunc([], df1.df_info);
243 df3.dofs = df1.dofs + df2.dofs;
247 function df3 = minus(df1, df2)
249 df3 = Fem.DiscFunc([], df1.df_info);
250 df3.dofs = df1.dofs - df2.dofs;
254 function df2 = uminus(df1)
256 df2 = Fem.DiscFunc([], df1.df_info);
257 df2.dofs = -df1.dofs;
261 function df2 = mtimes(factor, df1)
263 df2 = Fem.DiscFunc([], df1.df_info);
264 df2.dofs = factor * df1.dofs;
scalar Lagrange FE functions on triangular grid
nelements
number of elements
Base class for all grid classes.
nelements
number of overall elements (leaf + nonleaf)
represents a continous piecewise polynomial function of arbitrary dimension. Can be used for all fini...