r"""Discontinuous Galerkin finite elements (piecewise polynomials) on a simplicial domain (triangulation)
:math:`\mathcal{T}`, i.e. elements of :math:`D\mathcal{P}_{r, 0} (\mathcal{T})` or :math:`D\mathcal{P}_r (\mathcal{T})`,
expressed using the Bernstein polynomial basis.
"""
import numbers
import numpy as np
import polynomials_on_simplices.algebra.multiindex as multiindex
from polynomials_on_simplices.geometry.mesh.simplicial_complex import simplex_vertices
from polynomials_on_simplices.piecewise_polynomial.piecewise_polynomial import (
PiecewisePolynomialBase, generate_inverse_local_to_global_map, generate_local_to_global_map)
from polynomials_on_simplices.polynomial.polynomials_simplex_bernstein_basis import (
PolynomialBernsteinSimplex, bernstein_basis_simplex, dual_bernstein_basis_fn_simplex, get_dimension,
zero_polynomial_simplex)
from polynomials_on_simplices.polynomial.polynomials_unit_simplex_bernstein_basis import (
unique_identifier_bernstein_basis)
[docs]class PiecewisePolynomialBernstein(PiecewisePolynomialBase):
r"""
Implementation of the abstract piecewise polynomial base class using the Bernstein polynomial basis on the unit
simplex.
.. math:: p(x) = \sum_{i = 1}^N a_i \phi_i(x),
where the basis :math:`\{ \phi_i \}_{i = 1}^N` for the space of piecewise polynomials is constructed from the
Bernstein polynomial basis and the local-to-global map. See
:class:`~polynomials_on_simplices.piecewise_polynomial.piecewise_polynomial.PiecewisePolynomialBase` and
:func:`~polynomials_on_simplices.piecewise_polynomial.piecewise_polynomial.generate_local_to_global_map` for details.
"""
def __init__(self, coeff, triangles, vertices, r, tau=None, boundary_simplices=None, keep_boundary_dofs_last=False,
support=None, bsp_tree=None, basis_polynomials=None):
r"""
:param coeff: Coefficients for the piecewise polynomial in the :math:`\{ \phi_i \}_{i = 1}^N` basis derived
from the Bernstein basis for :math:`\mathcal{P}_r (\Delta_c^m)` and the local-to-global map :math:`\tau`.
:type coeff: List[Union[Scalar, Vector]]
:param triangles: Triangles (or in general simplices) in the mesh :math:`\mathcal{T}` (num_triangles by m + 1
array of indices).
:param vertices: Vertices in the mesh :math:`\mathcal{T}` (num_vertices by m array of scalars).
:param int r: Degree of each polynomial in the piecewise polynomial.
:param tau: Local-to-global map for mapping local basis functions to the index of the corresponding global
basis function. Will be generated if not supplied.
:type tau: Optional[Callable :math:`\tau(j, \nu)`]
:param boundary_simplices: List of simplices or subsimplices on which the piecewise polynomial function should
vanish (for an element of :math:`D\mathcal{P}_{r, 0} (\mathcal{T})`) or which should be treated separately
(if `keep_boundary_dofs_last` is set to True). Each simplex or subsimplex is specified as a list of
vertex indices of the vertices that form the simplex.
:type boundary_simplices: List[List[int]]
:param bool keep_boundary_dofs_last: Whether or not to collect all global basis functions associated with any
boundary simplex last in the enumeration of all basis functions. Enumerating basis functions associated with
boundary simplices last is useful for handling :math:`D\mathcal{P}_{r, 0} (\mathcal{T})` as a subset of
:math:`D\mathcal{P}_r (\mathcal{T})` in a practical way.
:param Optional[Set[int]] support: Indices of the triangles in the triangulation where the piecewise polynomial
is supported. Will be generated if not supplied.
:param bsp_tree: Optional implementation detail. A binary space partitioning tree built
around the triangulation for quicker lookup of triangle a point lies in. Will be generated if not supplied.
:param basis_polynomials: Precomputed basis polynomials for each triangle in the given triangulation. Will be
generated where necessary if not supplied.
:type basis_polynomials: Optional[Dict[int, List[
:class:`~.polynomial.polynomials_simplex_bernstein_basis.PolynomialBernsteinSimplex`]]]
"""
PiecewisePolynomialBase.__init__(self, coeff, triangles, vertices, r, tau, boundary_simplices,
keep_boundary_dofs_last, support, bsp_tree)
# Compute basis polynomials
if basis_polynomials is not None:
for j in self.triangles_in_the_support:
self._basis_polynomials[j] = basis_polynomials[j]
else:
for j in self.triangles_in_the_support:
self._basis_polynomials[j] = bernstein_basis_simplex(self.r,
simplex_vertices(triangles[j], self.vertices))
[docs] def basis(self):
r"""
Get basis for the space :math:`\mathcal{P}_r (\Delta_c^m)` used to express the piecewise polynomial.
:return: Unique identifier for the basis used.
:rtype: str
"""
return unique_identifier_bernstein_basis()
def __mul__(self, other):
"""
Multiplication of this piecewise polynomial with another piecewise polynomial (only if n = 1), a scalar, or
a vector (only if n = 1), self * other.
:param other: Piecewise polynomial, scalar or vector we should multiply this piecewise polynomial with.
:return: Product of this piecewise polynomial with other.
:rtype: Instance of self.__class__
"""
if isinstance(other, numbers.Number) or isinstance(other, np.ndarray):
return self.multiply_with_constant(other)
# Multiplication of two piecewise polynomials
# Multiplied piecewise polynomials need to have the same domain dimension
assert self.domain_dimension() == other.domain_dimension()
# And the same underlying triangle mesh
assert self.triangles.data == other.triangles.data
assert self.vertices.data == other.vertices.data
assert ((self.boundary_simplices is None and other.boundary_simplices is None)
or (self.boundary_simplices.data == other.boundary_simplices.data))
assert self.keep_boundary_dofs_last == other.keep_boundary_dofs_last
# Cannot multiply two vector valued piecewise polynomials
assert self.target_dimension() == 1
assert other.target_dimension() == 1
m = self.domain_dimension()
r = self.degree() + other.degree()
# New local-to-global map for the product piecewise polynomial
if self.keep_boundary_dofs_last:
tau, num_dofs, num_internal_dofs = self.__class__.generate_local_to_global_map(self.triangles, r,
self.boundary_simplices,
self.keep_boundary_dofs_last)
else:
tau, num_dofs = self.__class__.generate_local_to_global_map(self.triangles, r, self.boundary_simplices)
coeff = np.zeros(num_dofs)
support = self.support().intersection(other.support())
for j in support:
p = self.restrict_to_simplex(j)
q = other.restrict_to_simplex(j)
pq_coeff = (p * q).coeff
k = 0
for nu in multiindex.generate_all(m, r):
i = tau(j, nu)
coeff[i] = pq_coeff[k]
k += 1
return self.__class__(coeff, self.triangles, self.vertices, r, tau, self.boundary_simplices,
self.keep_boundary_dofs_last, support, self._bsp_tree)
def __pow__(self, exp):
r"""
Raise the piecewise polynomial to a power.
.. math::
(p^{\mu})(x) = p(x)^{\mu} = p_1(x)^{\mu_1} p_2(x)^{\mu_2} \ldots p_n(x)^{\mu_n}.
:param exp: Power we want the raise the piecewise polynomial to (natural number or multi-index depending on
the dimension of the target of the piecewise polynomial).
:type exp: int or :class:`~polynomials_on_simplices.algebra.multiindex.MultiIndex` or Tuple[int, ...]
:return: This piecewise polynomial raised to the given power.
:rtype: Instance of self.__class__
"""
if isinstance(exp, numbers.Integral):
assert exp >= 0
assert self.target_dimension() == 1
if exp == 0:
return self.get_unit_piecewise_polynomial_bernstein(self.triangles, self.vertices, 1, None,
self.boundary_simplices,
self.keep_boundary_dofs_last, self._bsp_tree)
if exp == 1:
return self.__class__(self.coeff, self.triangles, self.vertices, self.r, self.tau,
self.boundary_simplices, self.keep_boundary_dofs_last, self.support(),
self._bsp_tree, self._basis_polynomials)
return self * self**(exp - 1)
else:
n = self.target_dimension()
assert len(exp) == n
assert [entry >= 0 for entry in exp]
norm_exp = multiindex.norm(exp)
if norm_exp == 0:
return self.get_unit_piecewise_polynomial_bernstein(self.triangles, self.vertices, 1, None,
self.boundary_simplices,
self.keep_boundary_dofs_last, self._bsp_tree)
for i in range(len(exp)):
if exp[i] == 0:
continue
ei = multiindex.unit_multiindex(n, i)
return (self.__class__(self.coeff[:, i], self.triangles, self.vertices, self.r, self.tau,
self.boundary_simplices, self.keep_boundary_dofs_last, self.support(),
self._bsp_tree, self._basis_polynomials)
* self**(exp - ei))
[docs] def degree_elevate(self, s):
r"""
Express the piecewise polynomial using a higher degree polynomial basis.
Let :math:`p(x)` be this piecewise polynomial.
Let :math:`\{ \bar{\varphi}_{\nu, r} \}_{\substack{\nu \in \mathbb{N}_0^m \\ |\nu| \leq r}}` be the
polynomial basis for :math:`\mathcal{P}_r(\Delta_c^m)` used for this piecewise polynomial, and let
:math:`\{ \bar{\varphi}_{\nu, s} \}_{\substack{\nu \in \mathbb{N}_0^m \\ |\nu| \leq s}}, s \geq r` be the
corresponding higher degree polynomial basis for :math:`\mathcal{P}_s(\Delta_c^m)`. Then this function
returns a piecewise polynomial :math:`q` using the basis :math:`\{ \bar{\varphi}_{\nu, s} \}` such that
:math:`p(x) = q(x) \, \forall x \in \mathbb{R}^m`.
:param int s: New degree for the basic polynomial basis the piecewise polynomial should use.
:return: Elevation of this piecewise polynomial to the higher degree basis.
:rtype: Instance of self.__class__
"""
assert s >= self.degree()
if s == self.degree():
return self.__class__(self.coeff, self.triangles, self.vertices, self.r, self.tau, self.boundary_simplices,
self.keep_boundary_dofs_last, self.support(), self._bsp_tree, self._basis_polynomials)
# New local-to-global map for the higher degree piecewise polynomial
if self.keep_boundary_dofs_last:
tau, num_dofs, num_internal_dofs = self.__class__.generate_local_to_global_map(self.triangles, s,
self.boundary_simplices,
self.keep_boundary_dofs_last)
else:
tau, num_dofs = self.__class__.generate_local_to_global_map(self.triangles, s, self.boundary_simplices)
m = self.domain_dimension()
n = self.target_dimension()
if n == 1:
coeff = np.zeros(num_dofs)
else:
coeff = np.zeros((num_dofs, n))
mis = multiindex.generate_all(m, s)
for j in range(len(self.triangles)):
p = self.restrict_to_simplex(j).degree_elevate(s)
for k in range(len(p.coeff)):
i = tau(j, mis[k])
coeff[i] = p.coeff[k]
return self.__class__(coeff, self.triangles, self.vertices, s, tau, self.boundary_simplices,
self.keep_boundary_dofs_last, self.support(), self._bsp_tree)
[docs] def restrict_to_simplex(self, i):
r"""
Restriction of the piecewise polynomial to a specified simplex :math:`T_i \in \mathcal{T}`.
:param int i: Index of the simplex we want to restrict the piecewise polynomial to (in :math:`0, 1, \ldots,
| \mathcal{T} | - 1`).
:return: Polynomial which agrees with the piecewise polynomial on the simplex :math:`T_i`.
:rtype: :class:`~.polynomial.polynomials_simplex_bernstein_basis.PolynomialBernsteinSimplex`.
"""
assert i < len(self.triangles)
tri_vertices = simplex_vertices(self.triangles[i], self.vertices)
m = self.domain_dimension()
n = self.target_dimension()
r = self.degree()
if i not in self.support():
return zero_polynomial_simplex(tri_vertices, r, n)
dim = get_dimension(r, m)
if n == 1:
coeff = np.zeros(dim)
else:
coeff = np.zeros((dim, n))
mis = multiindex.generate_all(m, r)
for k in range(len(mis)):
idx = self.tau(i, mis[k])
coeff[k] = self.coeff[idx]
return PolynomialBernsteinSimplex(coeff, tri_vertices, r)
[docs] @staticmethod
def get_unit_piecewise_polynomial_bernstein(triangles, vertices, n=1, tau=None, boundary_simplices=None,
keep_boundary_dofs_last=False, bsp_tree=None):
r"""
Get the piecewise polynomial of degree r on the given triangulation :math:`\mathcal{T}`, where the polynomials
on each simplex is expressed in the Bernstein basis, which is identically one. See
:func:`unit_piecewise_polynomial_bernstein`.
"""
return unit_piecewise_polynomial_bernstein(triangles, vertices, n, tau, boundary_simplices,
keep_boundary_dofs_last, bsp_tree)
[docs]def piecewise_polynomial_bernstein_basis_fn(triangles, vertices, r, i, tau=None, num_dofs=None, boundary_simplices=None,
keep_boundary_dofs_last=False, bsp_tree=None, basis_polynomials=None):
r"""
Generate a basis function for the space of piecewise polynomials of degree r on the given triangulation
:math:`\mathcal{T}`, where the polynomials on each simplex is expressed in the Bernstein basis.
:param triangles: Triangles (or in general simplices) in the mesh :math:`\mathcal{T}` (num_triangles by m + 1
array of indices).
:param vertices: Vertices in the mesh :math:`\mathcal{T}` (num_vertices by m array of scalars).
:param int r: Degree of each polynomial in the piecewise polynomial.
:param int i: Index of the basis function that should be generated.
:param tau: Local-to-global map for mapping local basis functions to the index of the corresponding global
basis function. Will be generated if not supplied.
:type tau: Optional[Callable :math:`\tau(j, \nu)`]
:param Optional[int] num_dofs: Dimension of the space of piecewise polynomials on the given triangulation. Will
be computed if not supplied.
:param boundary_simplices: List of simplices or subsimplices on which the piecewise polynomial functions should
vanish (for :math:`D\mathcal{P}_{r, 0} (\mathcal{T})`) or which should be treated separately (if
`keep_boundary_dofs_last` is set to True). Each simplex or subsimplex is specified as a list of
vertex indices of the vertices that form the simplex.
:type boundary_simplices: List[List[int]]
:param bool keep_boundary_dofs_last: Whether or not to collect all global basis functions associated with any
boundary simplex last in the enumeration of all basis functions. Enumerating basis functions associated with
boundary simplices last is useful for handling :math:`D\mathcal{P}_{r, 0} (\mathcal{T})` as a subset of
:math:`D\mathcal{P}_r (\mathcal{T})` in a practical way.
:param bsp_tree: Optional implementation detail. A binary space partitioning tree built around the triangulation
:math:`\mathcal{T}` for quicker lookup of triangle a point lies in. Will be generated if not supplied.
:param basis_polynomials: Precomputed basis polynomials for each triangle in the given triangulation. Will be
generated where necessary if not supplied.
:type basis_polynomials: Optional[Dict[int, List[
:class:`~polynomials_on_simplices.polynomial.polynomials_simplex_bernstein_basis.PolynomialBernsteinSimplex`]]]
:return: Basis function.
:rtype: :class:`PiecewisePolynomialBernstein`.
"""
if tau is None or num_dofs is None:
if keep_boundary_dofs_last:
tau, num_dofs, num_interior_dofs = generate_local_to_global_map(triangles, r, boundary_simplices,
keep_boundary_dofs_last)
else:
tau, num_dofs = generate_local_to_global_map(triangles, r, boundary_simplices)
coeff = np.zeros(num_dofs)
coeff[i] = 1
return PiecewisePolynomialBernstein(coeff, triangles, vertices, r, tau, boundary_simplices, keep_boundary_dofs_last,
bsp_tree=bsp_tree, basis_polynomials=basis_polynomials)
[docs]def piecewise_polynomial_bernstein_basis(triangles, vertices, r, tau=None, num_dofs=None, boundary_simplices=None,
keep_boundary_dofs_last=False, bsp_tree=None):
r"""
Generate all basis functions for the space of piecewise polynomials of degree r on the given
triangulation :math:`\mathcal{T}`, where the polynomials on each simplex is expressed in the Bernstein basis.
:param triangles: Triangles (or in general simplices) in the mesh :math:`\mathcal{T}` (num_triangles by m + 1
array of indices).
:param vertices: Vertices in the mesh :math:`\mathcal{T}` (num_vertices by m array of scalars).
:param int r: Degree of each polynomial in the piecewise polynomial.
:param tau: Local-to-global map for mapping local basis functions to the index of the corresponding global
basis function. Will be generated if not supplied.
:type tau: Optional[Callable :math:`\tau(j, \nu)`]
:param Optional[int] num_dofs: Dimension of the space of piecewise polynomials on the given triangulation. Will
be computed if not supplied.
:param boundary_simplices: List of simplices or subsimplices on which the piecewise polynomial functions should
vanish (for :math:`D\mathcal{P}_{r, 0} (\mathcal{T})`) or which should be treated separately (if
`keep_boundary_dofs_last` is set to True). Each simplex or subsimplex is specified as a list of
vertex indices of the vertices that form the simplex.
:type boundary_simplices: List[List[int]]
:param bool keep_boundary_dofs_last: Whether or not to collect all global basis functions associated with any
boundary simplex last in the enumeration of all basis functions. Enumerating basis functions associated with
boundary simplices last is useful for handling :math:`D\mathcal{P}_{r, 0} (\mathcal{T})` as a subset of
:math:`D\mathcal{P}_r (\mathcal{T})` in a practical way.
:param bsp_tree: Optional implementation detail. A binary space partitioning tree built around the triangulation
:math:`\mathcal{T}` for quicker lookup of triangle a point lies in. Will be generated if not supplied.
:rtype: List[:class:`PiecewisePolynomialBernstein`].
"""
basis = []
if tau is None or num_dofs is None:
if keep_boundary_dofs_last:
tau, num_dofs, num_interior_dofs = generate_local_to_global_map(triangles, r, boundary_simplices,
keep_boundary_dofs_last)
else:
tau, num_dofs = generate_local_to_global_map(triangles, r, boundary_simplices)
basis_polynomials = {}
for j in range(len(triangles)):
tri_vertices = simplex_vertices(triangles[j], vertices)
basis_polynomials[j] = bernstein_basis_simplex(r, tri_vertices)
for i in range(num_dofs):
basis.append(piecewise_polynomial_bernstein_basis_fn(triangles, vertices, r, i, tau, num_dofs,
boundary_simplices, keep_boundary_dofs_last,
bsp_tree=bsp_tree, basis_polynomials=basis_polynomials))
return basis
[docs]def dual_piecewise_polynomial_bernstein_basis_fn(triangles, vertices, r, i, tau=None, num_dofs=None, tau_inv=None,
boundary_simplices=None, keep_boundary_dofs_last=False):
r"""
Generate a dual basis function to the basis for the space of piecewise polynomials of degree r on the given
triangulation :math:`\mathcal{T}, D \mathcal{P}_r(\mathcal{T})` or :math:`D \mathcal{P}_{r, 0}(\mathcal{T})`, where
the polynomials on each simplex is expressed in the Bernstein basis.
I.e. the linear map :math:`\phi_i^* : D \mathcal{P}_r(\mathcal{T}) \to \mathbb{R}` that satisfies
.. math:: \phi_i^* (\phi_j) = \delta_{ij},
where :math:`\phi_j` is the j:th Bernstein basis function for the space of piecewise polynomials of degree r
(see :func:`piecewise_polynomial_bernstein_basis_fn`).
:param triangles: Triangles (or in general simplices) in the mesh :math:`\mathcal{T}` (num_triangles by m + 1
array of indices).
:param vertices: Vertices in the mesh :math:`\mathcal{T}` (num_vertices by m array of scalars).
:param int r: Degree of each polynomial in the piecewise polynomial.
:param int i: Index of the dual basis function that should be generated.
:param tau: Local-to-global map for mapping local basis functions to the index of the corresponding global
basis function. Will be generated if not supplied.
:type tau: Optional[Callable :math:`\tau(j, \nu)`]
:param Optional[int] num_dofs: Dimension of the space of piecewise polynomials on the given triangulation. Will
be computed if not supplied.
:param tau_inv: Inverse of the local-to-global map. Will be generated if not supplied.
:type tau_inv: Optional[Callable :math:`\tau^{-1}(i)`]
:param boundary_simplices: List of simplices or subsimplices on which the piecewise polynomial functions should
vanish (for :math:`D\mathcal{P}_{r, 0} (\mathcal{T})`) or which should be treated separately (if
`keep_boundary_dofs_last` is set to True). Each simplex or subsimplex is specified as a list of
vertex indices of the vertices that form the simplex.
:type boundary_simplices: List[List[int]]
:param bool keep_boundary_dofs_last: Whether or not to collect all global basis functions associated with any
boundary simplex last in the enumeration of all basis functions. Enumerating basis functions associated with
boundary simplices last is useful for handling :math:`D\mathcal{P}_{r, 0} (\mathcal{T})` as a subset of
:math:`D\mathcal{P}_r (\mathcal{T})` in a practical way.
:return: The i:th dual Bernstein basis function as specified by mu and r.
:rtype: Callable :math:`\phi_i^*(p)`.
"""
if tau is None or num_dofs is None:
if keep_boundary_dofs_last:
tau, num_dofs, num_interior_dofs = generate_local_to_global_map(triangles, r, boundary_simplices,
keep_boundary_dofs_last)
else:
tau, num_dofs = generate_local_to_global_map(triangles, r, boundary_simplices)
if tau_inv is None:
tau_inv = generate_inverse_local_to_global_map(tau, len(triangles), num_dofs, r, len(vertices[0]))
j, nu = tau_inv(i)
q = dual_bernstein_basis_fn_simplex(nu, r, simplex_vertices(triangles[j], vertices))
def phi_star(p):
p_j = p.restrict_to_simplex(j)
return q(p_j)
return phi_star
[docs]def dual_piecewise_polynomial_bernstein_basis(triangles, vertices, r, tau=None, num_dofs=None, tau_inv=None,
boundary_simplices=None, keep_boundary_dofs_last=False):
r"""
Generate all dual basis functions to the basis of piecewise polynomials of degree r on the given
triangulation :math:`\mathcal{T}, D \mathcal{P}_r(\mathcal{T})` or :math:`D \mathcal{P}_{r, 0}(\mathcal{T})`, where
the polynomials on each simplex is expressed in the Bernstein basis.
See :func:`dual_piecewise_polynomial_bernstein_basis_fn`.
:param triangles: Triangles (or in general simplices) in the mesh :math:`\mathcal{T}` (num_triangles by m + 1
array of indices).
:param vertices: Vertices in the mesh :math:`\mathcal{T}` (num_vertices by m array of scalars).
:param int r: Degree of each polynomial in the piecewise polynomial.
:param tau: Local-to-global map for mapping local basis functions to the index of the corresponding global
basis function. Will be generated if not supplied.
:type tau: Optional[Callable :math:`\tau(j, \nu)`]
:param Optional[int] num_dofs: Dimension of the space of piecewise polynomials on the given triangulation. Will
be computed if not supplied.
:param tau_inv: Inverse of the local-to-global map. Will be generated if not supplied.
:type tau_inv: Optional[Callable :math:`\tau^{-1}(i)`]
:param boundary_simplices: List of simplices or subsimplices on which the piecewise polynomial functions should
vanish (for :math:`D\mathcal{P}_{r, 0} (\mathcal{T})`) or which should be treated separately (if
`keep_boundary_dofs_last` is set to True). Each simplex or subsimplex is specified as a list of
vertex indices of the vertices that form the simplex.
:type boundary_simplices: List[List[int]]
:param bool keep_boundary_dofs_last: Whether or not to collect all global basis functions associated with any
boundary simplex last in the enumeration of all basis functions. Enumerating basis functions associated with
boundary simplices last is useful for handling :math:`D\mathcal{P}_{r, 0} (\mathcal{T})` as a subset of
:math:`D\mathcal{P}_r (\mathcal{T})` in a practical way.
:return: List of dual base functions.
:rtype: List[Callable :math:`\phi_i^*(p)`].
"""
basis = []
if tau is None or num_dofs is None:
if keep_boundary_dofs_last:
tau, num_dofs, num_interior_dofs = generate_local_to_global_map(triangles, r, boundary_simplices,
keep_boundary_dofs_last)
else:
tau, num_dofs = generate_local_to_global_map(triangles, r, boundary_simplices)
if tau_inv is None:
try:
m = len(vertices[0])
except TypeError:
m = 1
tau_inv = generate_inverse_local_to_global_map(tau, len(triangles), num_dofs, r, m)
for i in range(num_dofs):
basis.append(dual_piecewise_polynomial_bernstein_basis_fn(triangles, vertices, r, i, tau, num_dofs, tau_inv,
boundary_simplices, keep_boundary_dofs_last))
return basis
[docs]def zero_piecewise_polynomial_bernstein(triangles, vertices, n=1, tau=None, boundary_simplices=None,
keep_boundary_dofs_last=False, bsp_tree=None):
r"""
Get the piecewise polynomial of degree r on the given triangulation :math:`\mathcal{T}`, where the polynomials on
each simplex is expressed in the Bernstein basis, which is identically zero.
:param triangles: Triangles (or in general simplices) in the mesh :math:`\mathcal{T}` (num_triangles by m + 1
array of indices).
:param vertices: Vertices in the mesh :math:`\mathcal{T}` (num_vertices by m array of scalars).
:param int n: Dimension of the target of the piecewise polynomial.
:param tau: Local-to-global map for mapping local basis functions to the index of the corresponding global
basis function. Will be generated if not supplied.
:type tau: Optional[Callable :math:`\tau(j, \nu)`]
:param boundary_simplices: List of simplices or subsimplices on which the piecewise polynomial functions should
vanish (for :math:`D\mathcal{P}_{r, 0} (\mathcal{T})`) or which should be treated separately (if
`keep_boundary_dofs_last` is set to True). Each simplex or subsimplex is specified as a list of
vertex indices of the vertices that form the simplex.
:type boundary_simplices: List[List[int]]
:param bool keep_boundary_dofs_last: Whether or not to collect all global basis functions associated with any
boundary simplex last in the enumeration of all basis functions. Enumerating basis functions associated with
boundary simplices last is useful for handling :math:`D\mathcal{P}_{r, 0} (\mathcal{T})` as a subset of
:math:`D\mathcal{P}_r (\mathcal{T})` in a practical way.
:param bsp_tree: Optional implementation detail. A binary space partitioning tree built around the triangulation
:math:`\mathcal{T}` for quicker lookup of triangle a point lies in. Will be generated if not supplied.
:return: The zero piecewise polynomial.
:rtype: :class:`PiecewisePolynomialBernstein`.
"""
dim = len(triangles)
if n == 1:
coeff = np.zeros(dim)
else:
coeff = np.zeros((dim, n))
support = set()
return PiecewisePolynomialBernstein(coeff, triangles, vertices, 0, tau, boundary_simplices, keep_boundary_dofs_last,
support, bsp_tree)
[docs]def unit_piecewise_polynomial_bernstein(triangles, vertices, n=1, tau=None, boundary_simplices=None,
keep_boundary_dofs_last=False, bsp_tree=None):
r"""
Get the piecewise polynomial of degree r on the given triangulation :math:`\mathcal{T}`, where the polynomials
on each simplex is expressed in the Bernstein basis, which is identically one.
:param triangles: Triangles (or in general simplices) in the mesh :math:`\mathcal{T}` (num_triangles by m + 1
array of indices).
:param vertices: Vertices in the mesh :math:`\mathcal{T}` (num_vertices by m array of scalars).
:param int n: Dimension of the target of the piecewise polynomial.
:param tau: Local-to-global map for mapping local basis functions to the index of the corresponding global
basis function. Will be generated if not supplied.
:type tau: Optional[Callable :math:`\tau(j, \nu)`]
:param boundary_simplices: List of simplices or subsimplices on which the piecewise polynomial functions should
vanish (for :math:`D\mathcal{P}_{r, 0} (\mathcal{T})`) or which should be treated separately (if
`keep_boundary_dofs_last` is set to True). Each simplex or subsimplex is specified as a list of
vertex indices of the vertices that form the simplex.
:type boundary_simplices: List[List[int]]
:param bool keep_boundary_dofs_last: Whether or not to collect all global basis functions associated with any
boundary simplex last in the enumeration of all basis functions. Enumerating basis functions associated with
boundary simplices last is useful for handling :math:`D\mathcal{P}_{r, 0} (\mathcal{T})` as a subset of
:math:`D\mathcal{P}_r (\mathcal{T})` in a practical way.
:param bsp_tree: Optional implementation detail. A binary space partitioning tree built around the triangulation
:math:`\mathcal{T}` for quicker lookup of triangle a point lies in. Will be generated if not supplied.
:return: The unit piecewise polynomial.
:rtype: :class:`PiecewisePolynomialBernstein`.
"""
dim = len(triangles)
if n == 1:
coeff = np.ones(dim)
else:
coeff = np.ones((dim, n))
support = set(range(len(triangles)))
return PiecewisePolynomialBernstein(coeff, triangles, vertices, 0, tau, boundary_simplices, keep_boundary_dofs_last,
support, bsp_tree)