Source code for pysofe.elements.simple.lagrange

"""
Provides classes for some simple Lagrange type finite elements.
"""

# IMPORTS
import numpy as np

from ..base import Element

[docs]class P1(Element): """ Linear Lagrange basis functions on simplicial domains. Parameters ---------- dimension : int The spatial dimension of the element """ is_nodal = True def __init__(self, dimension): order = 1 n_basis = (1, 2, 3, 4)[:(dimension+1)] n_verts = (1, 2, 3, 4)[:(dimension+1)] Element.__init__(self, dimension, order, n_basis, n_verts) self._dof_tuple = (1, 0, 0, 0)[:(dimension+1)] def _eval_d0basis(self, points): # determine number of points and their dimension nD, nP = points.shape # get number of basis functions associated with # the entities of this dimension nB = self.n_basis[nD] # evaluate the basis functions basis = np.zeros((nB, nP)) basis[0] = 1. - points.sum(axis=0) for i in xrange(nD): basis[i+1] = points[i] return basis def _eval_d1basis(self, points): # determine number of points and their dimension nD, nP = points.shape # get number of basis functions associated with # the entities of this dimension nB = self.n_basis[nD] # evaluate the basis functions basis = np.zeros((nB, nP, nD)) basis[0] = -1. for i in xrange(nD): basis[i+1,:,i] = 1. return basis def _eval_d2basis(self, points): # determine number of points and their dimension nD, nP = points.shape # get number of basis functions associated with # the entities of this dimension nB = self.n_basis[nD] # evaluate the basis functions basis = np.zeros((nB, nP, nD, nD)) return basis
[docs]class P2(Element): """ Quadratic Lagrange basis functions on simplicial domains. Parameters ---------- dimension : int The spatial dimension of the element """ is_nodal = True def __init__(self, dimension): order = 2 n_basis = (1, 3, 6, 10)[:(dimension+1)] n_verts = (1, 2, 3, 4)[:(dimension+1)] Element.__init__(self, dimension, order, n_basis, n_verts) self._dof_tuple = (1, 1, 0, 0)[:(dimension+1)] def _eval_d0basis(self, points): # determine number of points and their dimension nD, nP = points.shape # get number of basis functions associated with # the entities specified by given points nB = self.n_basis[nD] # now we evaluate each basis function in every point given basis = np.zeros((nB, nP)) if nD == 1: l1 = 1. - points[0] l2 = points[0] basis[0] = (2 * l1 - 1) * l1 basis[1] = (2 * l2 - 1) * l2 basis[2] = 4. * l1 * l2 elif nD == 2: l1 = 1. - points.sum(axis=0) l2 = points[0] l3 = points[1] basis[0] = (2 * l1 - 1) * l1 basis[1] = (2 * l2 - 1) * l2 basis[2] = (2 * l3 - 1) * l3 basis[3] = 4. * l1 * l2 basis[4] = 4. * l1 * l3 basis[5] = 4. * l2 * l3 elif nD == 3: l1 = 1. - points.sum(axis=0) l2 = points[0] l3 = points[1] l4 = points[2] basis[0] = (2 * l1 - 1) * l1 basis[1] = (2 * l2 - 1) * l2 basis[2] = (2 * l3 - 1) * l3 basis[3] = (2 * l4 - 1) * l4 basis[4] = 4 * l1 * l2 basis[5] = 4 * l1 * l3 basis[6] = 4 * l1 * l4 basis[7] = 4 * l2 * l3 basis[8] = 4 * l2 * l4 basis[9] = 4 * l3 * l4 return basis def _eval_d1basis(self, points): # determine number of points and their dimension nD, nP = points.shape # get number of basis functions associated with # the entities specified by given points nB = self.n_basis[nD] # now we evaluate each basis function in every point given basis = np.zeros((nB, nP, nD)) if nD == 1: basis[0,:,0] = 4 * points[0] - 3 basis[1,:,0] = 4 * points[0] - 1 basis[2,:,0] = 4 - 8 * points[0] elif nD == 2: x0, x1 = points basis[0,:,[0,1]] = 4 * (x0 + x1) - 3 basis[1,:,0] = 4 * x0 - 1 basis[2,:,1] = 4 * x1 - 1 basis[3,:,0] = 4 * (1 - 2*x0 - x1) basis[3,:,1] = -4 * x0 basis[4,:,0] = -4 * x1 basis[4,:,1] = 4 * (1 - x0 - 2*x1) basis[5,:,0] = 4 * x1 basis[5,:,1] = 4 * x0 elif nD == 3: x0, x1, x2 = points basis[0,:,[0,1,2]] = 4 * (x0 + x1 + x2) - 3 basis[1,:,0] = 4 * x0 - 1 basis[2,:,1] = 4 * x1 - 1 basis[3,:,2] = 4 * x2 - 1 basis[4,:,0] = 4 * (1 - 2*x0 - x1 - x2) basis[4,:,[1,2]] = -4 * x0 basis[5,:,1] = 4 * (1 - x0 - 2*x1 - x2) basis[5,:,[0,2]] = -4 * x1 basis[6,:,0] = 4 * (1 - x0 - x1 - 2*x2) basis[6,:,[0,1]] = -4 * x2 basis[7,:,0] = 4 * x1 basis[7,:,1] = 4 * x0 basis[8,:,0] = 4 * x2 basis[8,:,2] = 4 * x0 basis[9,:,1] = 4 * x2 basis[9,:,2] = 4 * x1 return basis def _eval_d2basis(self, points): # determine number of points and their dimension nD, nP = points.shape # get number of basis functions associated with # the entities specified by given points nB = self.n_basis[nD] # now we evaluate each basis function in every point given basis = np.zeros((nB, nP, nD, nD)) if nD == 1: basis[2,:,0,:] = -8. elif nD == 2: basis[0,:,:,:] = 4. basis[1,:,0,0] = 4. basis[2,:,1,1] = 4. basis[3,:,0,0] = -8. basis[3,:,0,1] = -4. basis[3,:,1,0] = -4. basis[4,:,0,1] = -4. basis[4,:,1,0] = -4. basis[4,:,1,1] = -8. basis[5,:,0,1] = 4. basis[5,:,1,0] = 4. elif nD == 3: basis[0,:,:,:] = 4. basis[1,:,0,0] = 4. basis[2,:,1,1] = 4. basis[3,:,2,2] = 4. basis[4,:,0,0] = -8. basis[4,:,0,[1,2]] = -4. basis[4,:,[1,2],0] = -4. basis[5,:,1,1] = -8. basis[5,:,1,[0,2]] = -4. basis[5,:,[0,2],1] = -4. basis[6,:,2,2] = -8. basis[6,:,2,[0,1]] = -4. basis[6,:,[0,1],2] = -4. basis[7,:,0,1] = 4. basis[7,:,1,0] = 4. basis[8,:,0,2] = 4. basis[8,:,2,0] = 4. basis[9,:,1,2] = 4. basis[9,:,2,1] = 4. return basis