Source code for finat.hz

"""Implementation of the Hu-Zhang finite elements."""
import FIAT
from gem import ListTensor
from finat.fiat_elements import FiatElement
from finat.physically_mapped import Citations, identity, PhysicallyMappedElement
from finat.aw import _facet_transform, _evaluation_transform


[docs] class HuZhang(PhysicallyMappedElement, FiatElement): def __init__(self, cell, degree=3, variant=None): if Citations is not None: Citations().register("Hu2015") self.variant = variant super().__init__(FIAT.HuZhang(cell, degree, variant=variant))
[docs] def basis_transformation(self, coordinate_mapping): ndofs = self.space_dimension() V = identity(ndofs) sd = self.cell.get_spatial_dimension() W = _evaluation_transform(self.cell, coordinate_mapping) # Put into the right rows and columns. V[0:3, 0:3] = V[3:6, 3:6] = V[6:9, 6:9] = W ncomp = W.shape[0] num_verts = sd+1 cur = num_verts * ncomp Vsub = _facet_transform(self.cell, self.degree-2, coordinate_mapping) fdofs = Vsub.shape[0] V[cur:cur+fdofs, cur:cur+fdofs] = Vsub cur += fdofs # internal DOFs if self.variant == "point": while cur < ndofs: V[cur:cur+ncomp, cur:cur+ncomp] = W cur += ncomp # RESCALING FOR CONDITIONING h = coordinate_mapping.cell_size() for e in range(num_verts): V[:, ncomp*e:ncomp*(e+1)] *= 1/(h[e] * h[e]) # Note: that the edge DOFs are scaled by edge lengths in FIAT implies # that they are already have the necessary rescaling to improve # conditioning. return ListTensor(V.T)