Source code for pysofe.spaces.functions

"""
Provides convinience classes for functions in the fem framework.
"""

# IMPORTS
import numpy as np

# DEBUGGING
from IPython import embed as IPS

[docs]class FEFunction(object): ''' A finite element function defined via degrees of freedoms. Parameters ---------- fe_space : pysofe.spaces.space.FESpace The function space dof_values : array_like Values for the degrees of freedom of the function space ''' def __init__(self, fe_space, dof_values): if not isinstance(dof_values, np.ndarray): dof_values = np.asarray(dof_values) assert dof_values.ndim == 1 if not np.size(dof_values) == fe_space.n_dof: raise ValueError("fe space and dof values don't match!") self.fe_space = fe_space self.dofs = dof_values @property def order(self): ''' The polynomial order of the function. ''' return self.fe_space.element.order def __call__(self, points, deriv=0): return self._evaluate(points, deriv) def _evaluate(self, points, deriv=0): ''' Evaluates the function or its derivatives at given points. Parameters ---------- points : array_like The local points at the reference domain deriv : int The derivation order ''' # determine for which entities to evaluate the function dim = np.size(points, axis=0) # check input if dim < self.fe_space.mesh.dimension and deriv > 0: raise NotImplementedError('Higher order derivatives for traces not supported!') # get dof map and adjust values dof_map = self.fe_space.get_dof_map(d=dim) values = self.dofs.take(indices=dof_map-1, axis=0) # evaluate basis functions (or derivatives) if deriv == 0: # values : nB x nE basis = self.fe_space.element.eval_basis(points, deriv) # nB x nP #U = np.dot(values.T, basis) # nE x nP U = (values[:,:,None] * basis[:,None,:]).sum(axis=0) # nE x nP elif deriv == 1: # values : nB x nE dbasis_global = self.fe_space.eval_global_derivatives(points) # nE x nB x nP x nD U = (values.T[:,:,None,None] * dbasis_global).sum(axis=1) # nE x nP x nD else: raise NotImplementedError('Invalid derivation order ({})'.format(d)) return U