Skip to content

Commit

Permalink
implement maximum_degree (#244)
Browse files Browse the repository at this point in the history
  • Loading branch information
mscroggs authored Sep 19, 2023
1 parent c65fcf6 commit c4a68db
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 35 deletions.
30 changes: 30 additions & 0 deletions symfem/basis_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import sympy

import symfem

from .functions import AnyFunction, FunctionInput, ScalarFunction, SympyFormat, ValuesToSubstitute
from .geometry import PointType
from .references import Reference
Expand Down Expand Up @@ -355,6 +357,20 @@ def __iter__(self) -> typing.Iterator[AnyFunction]:
f = self.get_function()
return f.__iter__()

def maximum_degree(self, cell: symfem.references.Reference) -> int:
"""Return the maximum degree of the function on a reference cell.
This function returns the order of the lowerst order Lagrange space on the input cell
that includes this function.
Args:
cell: The cell
Returns:
A version the function with floats as coefficients
"""
return self.get_function().maximum_degree(cell)


class SubbedBasisFunction(BasisFunction):
"""A basis function following a substitution."""
Expand Down Expand Up @@ -404,3 +420,17 @@ def plot_values(
n: The number of plotting points
"""
self.get_function().plot_values(reference, img, value_scale, n)

def maximum_degree(self, cell: symfem.references.Reference) -> int:
"""Return the maximum degree of the function on a reference cell.
This function returns the order of the lowerst order Lagrange space on the input cell
that includes this function.
Args:
cell: The cell
Returns:
A version the function with floats as coefficients
"""
raise ValueError("Cannot infer degree of a substituted basis function.")
5 changes: 5 additions & 0 deletions symfem/elements/dual.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ def get_polynomial_basis(
"""
raise ValueError("Polynomial basis not supported for barycentric dual elements.")

@property
def maximum_degree(self) -> int:
"""Get the maximum degree of this polynomial set for the element."""
raise NotImplementedError()

def get_dual_matrix(self) -> sympy.matrices.dense.MutableDenseMatrix:
"""Get the dual matrix.
Expand Down
33 changes: 25 additions & 8 deletions symfem/finite_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import math
import typing
from abc import ABC, abstractmethod
from abc import ABC, abstractmethod, abstractproperty
from itertools import product

import sympy
Expand Down Expand Up @@ -75,7 +75,6 @@ def dof_plot_positions(self) -> typing.List[PointType]:
Returns:
The DOF positions
"""
pass

@abstractmethod
def dof_directions(self) -> typing.List[typing.Union[PointType, None]]:
Expand All @@ -84,7 +83,6 @@ def dof_directions(self) -> typing.List[typing.Union[PointType, None]]:
Returns:
The DOF directions
"""
pass

@abstractmethod
def dof_entities(self) -> typing.List[typing.Tuple[int, int]]:
Expand All @@ -93,7 +91,6 @@ def dof_entities(self) -> typing.List[typing.Tuple[int, int]]:
Returns:
The entities
"""
pass

def plot_dof_diagram(
self, filename: typing.Union[str, typing.List[str]],
Expand Down Expand Up @@ -154,7 +151,6 @@ def entity_dofs(self, entity_dim: int, entity_number: int) -> typing.List[int]:
Returns:
The numbers of the DOFs associated with the entity
"""
pass

@abstractmethod
def get_basis_functions(
Expand All @@ -168,7 +164,6 @@ def get_basis_functions(
Returns:
The basis functions
"""
pass

def get_basis_function(self, n: int) -> BasisFunction:
"""Get a single basis function of the element.
Expand Down Expand Up @@ -283,7 +278,6 @@ def map_to_cell(
Returns:
The basis functions mapped to the cell
"""
pass

@abstractmethod
def get_polynomial_basis(self) -> typing.List[AnyFunction]:
Expand All @@ -292,7 +286,10 @@ def get_polynomial_basis(self) -> typing.List[AnyFunction]:
Returns:
The polynomial basis
"""
pass

@abstractproperty
def maximum_degree(self) -> int:
"""Get the maximum degree of this polynomial set for the element."""

def test(self):
"""Run tests for this element."""
Expand Down Expand Up @@ -510,6 +507,9 @@ def __init__(
assert isinstance(b, AnyFunction)
self.dofs = dofs
self._basis_functions: typing.Union[typing.List[AnyFunction], None] = None
self._maximum_degree = None
if reference.name == "pyramid":
self._maximum_degree = order

def entity_dofs(self, entity_dim: int, entity_number: int) -> typing.List[int]:
"""Get the numbers of the DOFs associated with the given entity.
Expand Down Expand Up @@ -555,6 +555,13 @@ def get_polynomial_basis(self) -> typing.List[AnyFunction]:
"""
return self._basis

@property
def maximum_degree(self) -> int:
"""Get the maximum degree of this polynomial set for the element."""
if self._maximum_degree is None:
self._maximum_degree = max(p.maximum_degree(self.reference) for p in self._basis)
return self._maximum_degree

def get_dual_matrix(
self, inverse=False, caching=True
) -> sympy.matrices.dense.MutableDenseMatrix:
Expand Down Expand Up @@ -890,6 +897,11 @@ def get_polynomial_basis(self) -> typing.List[AnyFunction]:
"""
raise NotImplementedError()

@property
def maximum_degree(self) -> int:
"""Get the maximum degree of this polynomial set for the element."""
raise NotImplementedError()

def test(self):
"""Run tests for this element."""
super().test()
Expand Down Expand Up @@ -1066,6 +1078,11 @@ def get_polynomial_basis(self) -> typing.List[AnyFunction]:
"""
raise NotImplementedError()

@property
def maximum_degree(self) -> int:
"""Get the maximum degree of this polynomial set for the element."""
raise NotImplementedError()

def test(self):
"""Run tests for this element."""
super().test()
Expand Down
Loading

0 comments on commit c4a68db

Please sign in to comment.