Source code for finat.alfeld_sorokina
import FIAT
import numpy
from gem import ListTensor
from finat.fiat_elements import FiatElement
from finat.physically_mapped import Citations, identity, PhysicallyMappedElement
from finat.piola_mapped import piola_inverse
[docs]
class AlfeldSorokina(PhysicallyMappedElement, FiatElement):
def __init__(self, cell, degree=2):
if Citations is not None:
Citations().register("AlfeldSorokina2016")
super().__init__(FIAT.AlfeldSorokina(cell, degree))
[docs]
def basis_transformation(self, coordinate_mapping):
sd = self.cell.get_spatial_dimension()
bary, = self.cell.make_points(sd, 0, sd+1)
J = coordinate_mapping.jacobian_at(bary)
detJ = coordinate_mapping.detJ_at(bary)
dofs = self.entity_dofs()
V = identity(self.space_dimension())
# Undo the Piola transform
nodes = self._element.get_dual_set().nodes
Finv = piola_inverse(self.cell, J, detJ)
for dim in sorted(dofs):
for e in sorted(dofs[dim]):
k = 0
while k < len(dofs[dim][e]):
cur = dofs[dim][e][k]
if len(nodes[cur].deriv_dict) > 0:
V[cur, cur] = detJ
k += 1
else:
s = dofs[dim][e][k:k+sd]
V[numpy.ix_(s, s)] = Finv
k += sd
return ListTensor(V.T)