Source code for finat.johnson_mercier

import FIAT
import numpy
from gem import ListTensor, Literal

from finat.aw import _facet_transform
from finat.fiat_elements import FiatElement
from finat.physically_mapped import Citations, PhysicallyMappedElement


[docs]class JohnsonMercier(PhysicallyMappedElement, FiatElement): # symmetric matrix valued def __init__(self, cell, degree, variant=None): if degree != 1: raise ValueError("Degree must be 1 for Johnson-Mercier element") if Citations is not None: Citations().register("Gopalakrishnan2024") self._indices = slice(None, None) super(JohnsonMercier, self).__init__(FIAT.JohnsonMercier(cell, degree, variant=variant))
[docs] def basis_transformation(self, coordinate_mapping): numbf = self._element.space_dimension() ndof = self.space_dimension() V = numpy.eye(numbf, ndof, dtype=object) for multiindex in numpy.ndindex(V.shape): V[multiindex] = Literal(V[multiindex]) Vsub = _facet_transform(self.cell, 1, coordinate_mapping) Vsub = Vsub[:, self._indices] m, n = Vsub.shape V[:m, :n] = Vsub # 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)