Source code for FIAT.crouzeix_raviart
# Copyright (C) 2010 Marie E. Rognes
#
# This file is part of FIAT (https://www.fenicsproject.org)
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# Written by Marie E. Rognes <meg@simula.no> based on original
# implementation by Robert C. Kirby.
#
# Last changed: 2010-01-28
from FIAT import finite_element, polynomial_set, dual_set, functional
def _initialize_entity_ids(topology):
entity_ids = {}
for (i, entity) in list(topology.items()):
entity_ids[i] = {}
for j in entity:
entity_ids[i][j] = []
return entity_ids
[docs]
class CrouzeixRaviartDualSet(dual_set.DualSet):
"""Dual basis for Crouzeix-Raviart element (linears continuous at
boundary midpoints)."""
def __init__(self, cell, degree):
# Get topology dictionary
d = cell.get_spatial_dimension()
topology = cell.get_topology()
# Initialize empty nodes and entity_ids
entity_ids = _initialize_entity_ids(topology)
nodes = [None for i in list(topology[d - 1].keys())]
# Construct nodes and entity_ids
for i in topology[d - 1]:
# Construct midpoint
x = cell.make_points(d - 1, i, d)[0]
# Degree of freedom number i is evaluation at midpoint
nodes[i] = functional.PointEvaluation(cell, x)
entity_ids[d - 1][i] += [i]
# Initialize super-class
super(CrouzeixRaviartDualSet, self).__init__(nodes, cell, entity_ids)
[docs]
class CrouzeixRaviart(finite_element.CiarletElement):
"""The Crouzeix-Raviart finite element:
K: Triangle/Tetrahedron
Polynomial space: P_1
Dual basis: Evaluation at facet midpoints
"""
def __init__(self, cell, degree):
# Crouzeix Raviart is only defined for polynomial degree == 1
if not (degree == 1):
raise Exception("Crouzeix-Raviart only defined for degree 1")
# Construct polynomial spaces, dual basis and initialize
# FiniteElement
space = polynomial_set.ONPolynomialSet(cell, 1)
dual = CrouzeixRaviartDualSet(cell, 1)
super(CrouzeixRaviart, self).__init__(space, dual, 1)