3267 lines
123 KiB
C++
3267 lines
123 KiB
C++
// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
|
|
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
|
|
// LICENSE and NOTICE for details. LLNL-CODE-806117.
|
|
//
|
|
// This file is part of the MFEM library. For more information and source code
|
|
// availability visit https://mfem.org.
|
|
//
|
|
// MFEM is free software; you can redistribute it and/or modify it under the
|
|
// terms of the BSD-3 license. We welcome feedback and contributions, see file
|
|
// CONTRIBUTING.md for details.
|
|
|
|
#ifndef MFEM_FE
|
|
#define MFEM_FE
|
|
|
|
#include "../config/config.hpp"
|
|
#include "../general/array.hpp"
|
|
#include "../linalg/linalg.hpp"
|
|
#include "intrules.hpp"
|
|
#include "geom.hpp"
|
|
|
|
#include <map>
|
|
|
|
namespace mfem
|
|
{
|
|
|
|
/// Possible basis types. Note that not all elements can use all BasisType(s).
|
|
class BasisType
|
|
{
|
|
public:
|
|
enum
|
|
{
|
|
Invalid = -1,
|
|
GaussLegendre = 0, ///< Open type
|
|
GaussLobatto = 1, ///< Closed type
|
|
Positive = 2, ///< Bernstein polynomials
|
|
OpenUniform = 3, ///< Nodes: x_i = (i+1)/(n+1), i=0,...,n-1
|
|
ClosedUniform = 4, ///< Nodes: x_i = i/(n-1), i=0,...,n-1
|
|
OpenHalfUniform = 5, ///< Nodes: x_i = (i+1/2)/n, i=0,...,n-1
|
|
Serendipity = 6, ///< Serendipity basis (squares / cubes)
|
|
NumBasisTypes = 7 /**< Keep track of maximum types to prevent
|
|
hard-coding */
|
|
};
|
|
/** @brief If the input does not represents a valid BasisType, abort with an
|
|
error; otherwise return the input. */
|
|
static int Check(int b_type)
|
|
{
|
|
MFEM_VERIFY(0 <= b_type && b_type < NumBasisTypes,
|
|
"unknown BasisType: " << b_type);
|
|
return b_type;
|
|
}
|
|
/** @brief If the input does not represents a valid nodal BasisType, abort
|
|
with an error; otherwise return the input. */
|
|
static int CheckNodal(int b_type)
|
|
{
|
|
MFEM_VERIFY(Check(b_type) != Positive,
|
|
"invalid nodal BasisType: " << Name(b_type));
|
|
return b_type;
|
|
}
|
|
/** @brief Get the corresponding Quadrature1D constant, when that makes
|
|
sense; otherwise return Quadrature1D::Invalid. */
|
|
static int GetQuadrature1D(int b_type)
|
|
{
|
|
switch (b_type)
|
|
{
|
|
case GaussLegendre: return Quadrature1D::GaussLegendre;
|
|
case GaussLobatto: return Quadrature1D::GaussLobatto;
|
|
case Positive: return Quadrature1D::ClosedUniform; // <-----
|
|
case OpenUniform: return Quadrature1D::OpenUniform;
|
|
case ClosedUniform: return Quadrature1D::ClosedUniform;
|
|
case OpenHalfUniform: return Quadrature1D::OpenHalfUniform;
|
|
case Serendipity: return Quadrature1D::GaussLobatto;
|
|
}
|
|
return Quadrature1D::Invalid;
|
|
}
|
|
/// Return the nodal BasisType corresponding to the Quadrature1D type.
|
|
static int GetNodalBasis(int qpt_type)
|
|
{
|
|
switch (qpt_type)
|
|
{
|
|
case Quadrature1D::GaussLegendre: return GaussLegendre;
|
|
case Quadrature1D::GaussLobatto: return GaussLobatto;
|
|
case Quadrature1D::OpenUniform: return OpenUniform;
|
|
case Quadrature1D::ClosedUniform: return ClosedUniform;
|
|
case Quadrature1D::OpenHalfUniform: return OpenHalfUniform;
|
|
}
|
|
return Invalid;
|
|
}
|
|
/// Check and convert a BasisType constant to a string identifier.
|
|
static const char *Name(int b_type)
|
|
{
|
|
static const char *name[] =
|
|
{
|
|
"Gauss-Legendre", "Gauss-Lobatto", "Positive (Bernstein)",
|
|
"Open uniform", "Closed uniform", "Open half uniform"
|
|
};
|
|
return name[Check(b_type)];
|
|
}
|
|
/// Check and convert a BasisType constant to a char basis identifier.
|
|
static char GetChar(int b_type)
|
|
{
|
|
static const char ident[] = { 'g', 'G', 'P', 'u', 'U', 'o' };
|
|
return ident[Check(b_type)];
|
|
}
|
|
/// Convert char basis identifier to a BasisType constant.
|
|
static int GetType(char b_ident)
|
|
{
|
|
switch (b_ident)
|
|
{
|
|
case 'g': return GaussLegendre;
|
|
case 'G': return GaussLobatto;
|
|
case 'P': return Positive;
|
|
case 'u': return OpenUniform;
|
|
case 'U': return ClosedUniform;
|
|
case 'o': return OpenHalfUniform;
|
|
case 's': return GaussLobatto;
|
|
}
|
|
MFEM_ABORT("unknown BasisType identifier");
|
|
return -1;
|
|
}
|
|
};
|
|
|
|
|
|
/** @brief Structure representing the matrices/tensors needed to evaluate (in
|
|
reference space) the values, gradients, divergences, or curls of a
|
|
FiniteElement at a the quadrature points of a given IntegrationRule. */
|
|
/** Object of this type are typically created and owned by the respective
|
|
FiniteElement object. */
|
|
class DofToQuad
|
|
{
|
|
public:
|
|
/// The FiniteElement that created and owns this object.
|
|
/** This pointer is not owned. */
|
|
const class FiniteElement *FE;
|
|
|
|
/** @brief IntegrationRule that defines the quadrature points at which the
|
|
basis functions of the #FE are evaluated. */
|
|
/** This pointer is not owned. */
|
|
const IntegrationRule *IntRule;
|
|
|
|
/// Type of data stored in the arrays #B, #Bt, #G, and #Gt.
|
|
enum Mode
|
|
{
|
|
/** @brief Full multidimensional representation which does not use tensor
|
|
product structure. The ordering of the degrees of freedom is as
|
|
defined by #FE */
|
|
FULL,
|
|
|
|
/** @brief Tensor product representation using 1D matrices/tensors with
|
|
dimensions using 1D number of quadrature points and degrees of
|
|
freedom. */
|
|
/** When representing a vector-valued FiniteElement, two DofToQuad objects
|
|
are used to describe the "closed" and "open" 1D basis functions
|
|
(TODO). */
|
|
TENSOR
|
|
};
|
|
|
|
/// Describes the contents of the #B, #Bt, #G, and #Gt arrays, see #Mode.
|
|
Mode mode;
|
|
|
|
/** @brief Number of degrees of freedom = number of basis functions. When
|
|
#mode is TENSOR, this is the 1D number. */
|
|
int ndof;
|
|
|
|
/** @brief Number of quadrature points. When #mode is TENSOR, this is the 1D
|
|
number. */
|
|
int nqpt;
|
|
|
|
/// Basis functions evaluated at quadrature points.
|
|
/** The storage layout is column-major with dimensions:
|
|
- #nqpt x #ndof, for scalar elements, or
|
|
- #nqpt x dim x #ndof, for vector elements, (TODO)
|
|
|
|
where
|
|
|
|
- dim = dimension of the finite element reference space when #mode is
|
|
FULL, and dim = 1 when #mode is TENSOR. */
|
|
Array<double> B;
|
|
|
|
/// Transpose of #B.
|
|
/** The storage layout is column-major with dimensions:
|
|
- #ndof x #nqpt, for scalar elements, or
|
|
- #ndof x #nqpt x dim, for vector elements (TODO). */
|
|
Array<double> Bt;
|
|
|
|
/** @brief Gradients/divergences/curls of basis functions evaluated at
|
|
quadrature points. */
|
|
/** The storage layout is column-major with dimensions:
|
|
- #nqpt x dim x #ndof, for scalar elements, or
|
|
- #nqpt x #ndof, for H(div) vector elements (TODO), or
|
|
- #nqpt x cdim x #ndof, for H(curl) vector elements (TODO),
|
|
|
|
where
|
|
|
|
- dim = dimension of the finite element reference space when #mode is
|
|
FULL, and 1 when #mode is TENSOR,
|
|
- cdim = 1/1/3 in 1D/2D/3D, respectively, when #mode is FULL, and cdim =
|
|
1 when #mode is TENSOR. */
|
|
Array<double> G;
|
|
|
|
/// Transpose of #G.
|
|
/** The storage layout is column-major with dimensions:
|
|
- #ndof x #nqpt x dim, for scalar elements, or
|
|
- #ndof x #nqpt, for H(div) vector elements (TODO), or
|
|
- #ndof x #nqpt x cdim, for H(curl) vector elements (TODO). */
|
|
Array<double> Gt;
|
|
};
|
|
|
|
|
|
/// Describes the function space on each element
|
|
class FunctionSpace
|
|
{
|
|
public:
|
|
enum
|
|
{
|
|
Pk, ///< Polynomials of order k
|
|
Qk, ///< Tensor products of polynomials of order k
|
|
rQk ///< Refined tensor products of polynomials of order k
|
|
};
|
|
};
|
|
|
|
class ElementTransformation;
|
|
class Coefficient;
|
|
class VectorCoefficient;
|
|
class MatrixCoefficient;
|
|
class KnotVector;
|
|
|
|
|
|
// Base and derived classes for finite elements
|
|
|
|
|
|
/// Abstract class for all finite elements.
|
|
class FiniteElement
|
|
{
|
|
protected:
|
|
int dim; ///< Dimension of reference space
|
|
Geometry::Type geom_type; ///< Geometry::Type of the reference element
|
|
int func_space, range_type, map_type,
|
|
deriv_type, deriv_range_type, deriv_map_type;
|
|
mutable
|
|
int dof, ///< Number of degrees of freedom
|
|
order; ///< Order/degree of the shape functions
|
|
mutable int orders[Geometry::MaxDim]; ///< Anisotropic orders
|
|
IntegrationRule Nodes;
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable DenseMatrix vshape; // Dof x Dim
|
|
#endif
|
|
/// Container for all DofToQuad objects created by the FiniteElement.
|
|
/** Multiple DofToQuad objects may be needed when different quadrature rules
|
|
or different DofToQuad::Mode are used. */
|
|
mutable Array<DofToQuad*> dof2quad_array;
|
|
|
|
public:
|
|
/// Enumeration for range_type and deriv_range_type
|
|
enum RangeType { SCALAR, VECTOR };
|
|
|
|
/** @brief Enumeration for MapType: defines how reference functions are
|
|
mapped to physical space.
|
|
|
|
A reference function \f$ \hat u(\hat x) \f$ can be mapped to a function
|
|
\f$ u(x) \f$ on a general physical element in following ways:
|
|
- \f$ x = T(\hat x) \f$ is the image of the reference point \f$ \hat x \f$
|
|
- \f$ J = J(\hat x) \f$ is the Jacobian matrix of the transformation T
|
|
- \f$ w = w(\hat x) = det(J) \f$ is the transformation weight factor for square J
|
|
- \f$ w = w(\hat x) = det(J^t J)^{1/2} \f$ is the transformation weight factor in general
|
|
*/
|
|
enum MapType
|
|
{
|
|
VALUE, /**< For scalar fields; preserves point values
|
|
\f$ u(x) = \hat u(\hat x) \f$ */
|
|
INTEGRAL, /**< For scalar fields; preserves volume integrals
|
|
\f$ u(x) = (1/w) \hat u(\hat x) \f$ */
|
|
H_DIV, /**< For vector fields; preserves surface integrals of the
|
|
normal component \f$ u(x) = (J/w) \hat u(\hat x) \f$ */
|
|
H_CURL /**< For vector fields; preserves line integrals of the
|
|
tangential component
|
|
\f$ u(x) = J^{-t} \hat u(\hat x) \f$ (square J),
|
|
\f$ u(x) = J(J^t J)^{-1} \hat u(\hat x) \f$ (general J) */
|
|
};
|
|
|
|
/** @brief Enumeration for DerivType: defines which derivative method
|
|
is implemented.
|
|
|
|
Each FiniteElement class implements up to one type of derivative. The
|
|
value returned by GetDerivType() indicates which derivative method is
|
|
implemented.
|
|
*/
|
|
enum DerivType
|
|
{
|
|
NONE, ///< No derivatives implemented
|
|
GRAD, ///< Implements CalcDShape methods
|
|
DIV, ///< Implements CalcDivShape methods
|
|
CURL ///< Implements CalcCurlShape methods
|
|
};
|
|
|
|
/** @brief Construct FiniteElement with given
|
|
@param D Reference space dimension
|
|
@param G Geometry type (of type Geometry::Type)
|
|
@param Do Number of degrees of freedom in the FiniteElement
|
|
@param O Order/degree of the FiniteElement
|
|
@param F FunctionSpace type of the FiniteElement
|
|
*/
|
|
FiniteElement(int D, Geometry::Type G, int Do, int O,
|
|
int F = FunctionSpace::Pk);
|
|
|
|
/// Returns the reference space dimension for the finite element
|
|
int GetDim() const { return dim; }
|
|
|
|
/// Returns the Geometry::Type of the reference element
|
|
Geometry::Type GetGeomType() const { return geom_type; }
|
|
|
|
/// Returns the number of degrees of freedom in the finite element
|
|
int GetDof() const { return dof; }
|
|
|
|
/** @brief Returns the order of the finite element. In the case of
|
|
anisotropic orders, returns the maximum order. */
|
|
int GetOrder() const { return order; }
|
|
|
|
/** @brief Returns true if the FiniteElement basis *may be using* different
|
|
orders/degrees in different spatial directions. */
|
|
bool HasAnisotropicOrders() const { return orders[0] != -1; }
|
|
|
|
/// Returns an array containing the anisotropic orders/degrees.
|
|
const int *GetAnisotropicOrders() const { return orders; }
|
|
|
|
/// Returns the type of FunctionSpace on the element.
|
|
int Space() const { return func_space; }
|
|
|
|
/// Returns the FiniteElement::RangeType of the element, one of {SCALAR, VECTOR}.
|
|
int GetRangeType() const { return range_type; }
|
|
|
|
/** @brief Returns the FiniteElement::RangeType of the element derivative, either
|
|
SCALAR or VECTOR. */
|
|
int GetDerivRangeType() const { return deriv_range_type; }
|
|
|
|
/** @brief Returns the FiniteElement::MapType of the element describing how reference
|
|
functions are mapped to physical space, one of {VALUE, INTEGRAL
|
|
H_DIV, H_CURL}. */
|
|
int GetMapType() const { return map_type; }
|
|
|
|
|
|
/** @brief Returns the FiniteElement::DerivType of the element describing the
|
|
spatial derivative method implemented, one of {NONE, GRAD,
|
|
DIV, CURL}. */
|
|
int GetDerivType() const { return deriv_type; }
|
|
|
|
/** @brief Returns the FiniteElement::DerivType of the element describing how
|
|
reference function derivatives are mapped to physical space, one of {VALUE,
|
|
INTEGRAL, H_DIV, H_CURL}. */
|
|
int GetDerivMapType() const { return deriv_map_type; }
|
|
|
|
/** @brief Evaluate the values of all shape functions of a scalar finite
|
|
element in reference space at the given point @a ip. */
|
|
/** The size (#dof) of the result Vector @a shape must be set in advance. */
|
|
virtual void CalcShape(const IntegrationPoint &ip,
|
|
Vector &shape) const = 0;
|
|
|
|
/** @brief Evaluate the values of all shape functions of a scalar finite
|
|
element in physical space at the point described by @a Trans. */
|
|
/** The size (#dof) of the result Vector @a shape must be set in advance. */
|
|
void CalcPhysShape(ElementTransformation &Trans, Vector &shape) const;
|
|
|
|
/** @brief Evaluate the gradients of all shape functions of a scalar finite
|
|
element in reference space at the given point @a ip. */
|
|
/** Each row of the result DenseMatrix @a dshape contains the derivatives of
|
|
one shape function. The size (#dof x #dim) of @a dshape must be set in
|
|
advance. */
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const = 0;
|
|
|
|
/** @brief Evaluate the gradients of all shape functions of a scalar finite
|
|
element in physical space at the point described by @a Trans. */
|
|
/** Each row of the result DenseMatrix @a dshape contains the derivatives of
|
|
one shape function. The size (#dof x SDim) of @a dshape must be set in
|
|
advance, where SDim >= #dim is the physical space dimension as described
|
|
by @a Trans. */
|
|
void CalcPhysDShape(ElementTransformation &Trans, DenseMatrix &dshape) const;
|
|
|
|
/// Get a const reference to the nodes of the element
|
|
const IntegrationRule & GetNodes() const { return Nodes; }
|
|
|
|
// virtual functions for finite elements on vector spaces
|
|
|
|
/** @brief Evaluate the values of all shape functions of a *vector* finite
|
|
element in reference space at the given point @a ip. */
|
|
/** Each row of the result DenseMatrix @a shape contains the components of
|
|
one vector shape function. The size (#dof x #dim) of @a shape must be set
|
|
in advance. */
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
|
|
/** @brief Evaluate the values of all shape functions of a *vector* finite
|
|
element in physical space at the point described by @a Trans. */
|
|
/** Each row of the result DenseMatrix @a shape contains the components of
|
|
one vector shape function. The size (#dof x SDim) of @a shape must be set
|
|
in advance, where SDim >= #dim is the physical space dimension as
|
|
described by @a Trans. */
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const;
|
|
|
|
/// Equivalent to the CalcVShape() method with the same arguments.
|
|
void CalcPhysVShape(ElementTransformation &Trans, DenseMatrix &shape) const
|
|
{ CalcVShape(Trans, shape); }
|
|
|
|
/** @brief Evaluate the divergence of all shape functions of a *vector*
|
|
finite element in reference space at the given point @a ip. */
|
|
/** The size (#dof) of the result Vector @a divshape must be set in advance.
|
|
*/
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
|
|
/** @brief Evaluate the divergence of all shape functions of a *vector*
|
|
finite element in physical space at the point described by @a Trans. */
|
|
/** The size (#dof) of the result Vector @a divshape must be set in advance.
|
|
*/
|
|
void CalcPhysDivShape(ElementTransformation &Trans, Vector &divshape) const;
|
|
|
|
/** @brief Evaluate the curl of all shape functions of a *vector* finite
|
|
element in reference space at the given point @a ip. */
|
|
/** Each row of the result DenseMatrix @a curl_shape contains the components
|
|
of the curl of one vector shape function. The size (#dof x CDim) of
|
|
@a curl_shape must be set in advance, where CDim = 3 for #dim = 3 and
|
|
CDim = 1 for #dim = 2. */
|
|
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
|
DenseMatrix &curl_shape) const;
|
|
|
|
/** @brief Evaluate the curl of all shape functions of a *vector* finite
|
|
element in physical space at the point described by @a Trans. */
|
|
/** Each row of the result DenseMatrix @a curl_shape contains the components
|
|
of the curl of one vector shape function. The size (#dof x CDim) of
|
|
@a curl_shape must be set in advance, where CDim = 3 for #dim = 3 and
|
|
CDim = 1 for #dim = 2. */
|
|
void CalcPhysCurlShape(ElementTransformation &Trans,
|
|
DenseMatrix &curl_shape) const;
|
|
|
|
/** @brief Get the dofs associated with the given @a face.
|
|
@a *dofs is set to an internal array of the local dofc on the
|
|
face, while *ndofs is set to the number of dofs on that face.
|
|
*/
|
|
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const;
|
|
|
|
/** @brief Evaluate the Hessians of all shape functions of a scalar finite
|
|
element in reference space at the given point @a ip. */
|
|
/** Each row of the result DenseMatrix @a Hessian contains upper triangular
|
|
part of the Hessian of one shape function.
|
|
The order in 2D is {u_xx, u_xy, u_yy}.
|
|
The size (#dof x (#dim (#dim-1)/2) of @a Hessian must be set in advance.*/
|
|
virtual void CalcHessian (const IntegrationPoint &ip,
|
|
DenseMatrix &Hessian) const;
|
|
|
|
/** @brief Evaluate the Hessian of all shape functions of a scalar finite
|
|
element in reference space at the given point @a ip. */
|
|
/** The size (#dof, #dim*(#dim+1)/2) of @a Hessian must be set in advance. */
|
|
virtual void CalcPhysHessian(ElementTransformation &Trans,
|
|
DenseMatrix& Hessian) const;
|
|
|
|
/** @brief Evaluate the Laplacian of all shape functions of a scalar finite
|
|
element in reference space at the given point @a ip. */
|
|
/** The size (#dof) of @a Laplacian must be set in advance. */
|
|
virtual void CalcPhysLaplacian(ElementTransformation &Trans,
|
|
Vector& Laplacian) const;
|
|
|
|
virtual void CalcPhysLinLaplacian(ElementTransformation &Trans,
|
|
Vector& Laplacian) const;
|
|
|
|
/** @brief Return the local interpolation matrix @a I (Dof x Dof) where the
|
|
fine element is the image of the base geometry under the given
|
|
transformation. */
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
/** @brief Return a local restriction matrix @a R (Dof x Dof) mapping fine
|
|
dofs to coarse dofs.
|
|
|
|
The fine element is the image of the base geometry under the given
|
|
transformation, @a Trans.
|
|
|
|
The assumption in this method is that a subset of the coarse dofs can be
|
|
expressed only in terms of the dofs of the given fine element.
|
|
|
|
Rows in @a R corresponding to coarse dofs that cannot be expressed in
|
|
terms of the fine dofs will be marked as invalid by setting the first
|
|
entry (column 0) in the row to infinity().
|
|
|
|
This method assumes that the dimensions of @a R are set before it is
|
|
called. */
|
|
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
|
DenseMatrix &R) const;
|
|
|
|
/** @brief Return interpolation matrix, @a I, which maps dofs from a coarse
|
|
element, @a fe, to the fine dofs on @a this finite element. */
|
|
/** @a Trans represents the mapping from the reference element of @a this
|
|
element into a subset of the reference space of the element @a fe, thus
|
|
allowing the "coarse" FiniteElement to be different from the "fine"
|
|
FiniteElement as when h-refinement is combined with p-refinement or
|
|
p-derefinement. It is assumed that both finite elements use the same
|
|
FiniteElement::MapType. */
|
|
virtual void GetTransferMatrix(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
/** @brief Given a coefficient and a transformation, compute its projection
|
|
(approximation) in the local finite dimensional space in terms
|
|
of the degrees of freedom. */
|
|
virtual void Project (Coefficient &coeff,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
|
|
/** @brief Given a vector coefficient and a transformation, compute its
|
|
projection (approximation) in the local finite dimensional space
|
|
in terms of the degrees of freedom. (VectorFiniteElements) */
|
|
virtual void Project (VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
|
|
/** @brief Given a matrix coefficient and a transformation, compute an
|
|
approximation ("projection") in the local finite dimensional space in
|
|
terms of the degrees of freedom. For VectorFiniteElements, the rows of
|
|
the coefficient are projected in the vector space. */
|
|
virtual void ProjectMatrixCoefficient(
|
|
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const;
|
|
|
|
/** @brief Project a delta function centered on the given @a vertex in
|
|
the local finite dimensional space represented by the @a dofs. */
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
|
|
/** @brief Compute the embedding/projection matrix from the given
|
|
FiniteElement onto 'this' FiniteElement. The ElementTransformation is
|
|
included to support cases when the projection depends on it. */
|
|
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
/** @brief Compute the discrete gradient matrix from the given FiniteElement
|
|
onto 'this' FiniteElement. The ElementTransformation is included to
|
|
support cases when the matrix depends on it. */
|
|
virtual void ProjectGrad(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &grad) const;
|
|
|
|
/** @brief Compute the discrete curl matrix from the given FiniteElement onto
|
|
'this' FiniteElement. The ElementTransformation is included to support
|
|
cases when the matrix depends on it. */
|
|
virtual void ProjectCurl(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &curl) const;
|
|
|
|
/** @brief Compute the discrete divergence matrix from the given
|
|
FiniteElement onto 'this' FiniteElement. The ElementTransformation is
|
|
included to support cases when the matrix depends on it. */
|
|
virtual void ProjectDiv(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &div) const;
|
|
|
|
/** @brief Return a DofToQuad structure corresponding to the given
|
|
IntegrationRule using the given DofToQuad::Mode. */
|
|
/** See the documentation for DofToQuad for more details. */
|
|
virtual const DofToQuad &GetDofToQuad(const IntegrationRule &ir,
|
|
DofToQuad::Mode mode) const;
|
|
/// Deconstruct the FiniteElement
|
|
virtual ~FiniteElement();
|
|
|
|
/** @brief Return true if the BasisType of @a b_type is closed
|
|
(has Quadrature1D points on the boundary). */
|
|
static bool IsClosedType(int b_type)
|
|
{
|
|
const int q_type = BasisType::GetQuadrature1D(b_type);
|
|
return ((q_type != Quadrature1D::Invalid) &&
|
|
(Quadrature1D::CheckClosed(q_type) != Quadrature1D::Invalid));
|
|
}
|
|
|
|
/** @brief Return true if the BasisType of @a b_type is open
|
|
(doesn't have Quadrature1D points on the boundary). */
|
|
static bool IsOpenType(int b_type)
|
|
{
|
|
const int q_type = BasisType::GetQuadrature1D(b_type);
|
|
return ((q_type != Quadrature1D::Invalid) &&
|
|
(Quadrature1D::CheckOpen(q_type) != Quadrature1D::Invalid));
|
|
}
|
|
|
|
/** @brief Ensure that the BasisType of @a b_type is closed
|
|
(has Quadrature1D points on the boundary). */
|
|
static int VerifyClosed(int b_type)
|
|
{
|
|
MFEM_VERIFY(IsClosedType(b_type),
|
|
"invalid closed basis type: " << b_type);
|
|
return b_type;
|
|
}
|
|
|
|
/** @brief Ensure that the BasisType of @a b_type is open
|
|
(doesn't have Quadrature1D points on the boundary). */
|
|
static int VerifyOpen(int b_type)
|
|
{
|
|
MFEM_VERIFY(IsOpenType(b_type), "invalid open basis type: " << b_type);
|
|
return b_type;
|
|
}
|
|
|
|
/** @brief Ensure that the BasisType of @a b_type nodal
|
|
(satisfies the interpolation property). */
|
|
static int VerifyNodal(int b_type)
|
|
{
|
|
return BasisType::CheckNodal(b_type);
|
|
}
|
|
};
|
|
|
|
|
|
/** @brief Class for finite elements with basis functions
|
|
that return scalar values. */
|
|
class ScalarFiniteElement : public FiniteElement
|
|
{
|
|
protected:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector c_shape;
|
|
#endif
|
|
|
|
static const ScalarFiniteElement &CheckScalarFE(const FiniteElement &fe)
|
|
{
|
|
if (fe.GetRangeType() != SCALAR)
|
|
{ mfem_error("'fe' must be a ScalarFiniteElement"); }
|
|
return static_cast<const ScalarFiniteElement &>(fe);
|
|
}
|
|
|
|
const DofToQuad &GetTensorDofToQuad(const class TensorBasisElement &tb,
|
|
const IntegrationRule &ir,
|
|
DofToQuad::Mode mode) const;
|
|
|
|
public:
|
|
/** @brief Construct ScalarFiniteElement with given
|
|
@param D Reference space dimension
|
|
@param G Geometry type (of type Geometry::Type)
|
|
@param Do Number of degrees of freedom in the FiniteElement
|
|
@param O Order/degree of the FiniteElement
|
|
@param F FunctionSpace type of the FiniteElement
|
|
*/
|
|
ScalarFiniteElement(int D, Geometry::Type G, int Do, int O,
|
|
int F = FunctionSpace::Pk)
|
|
#ifdef MFEM_THREAD_SAFE
|
|
: FiniteElement(D, G, Do, O, F)
|
|
{ deriv_type = GRAD; deriv_range_type = VECTOR; deriv_map_type = H_CURL; }
|
|
#else
|
|
: FiniteElement(D, G, Do, O, F), c_shape(dof)
|
|
{ deriv_type = GRAD; deriv_range_type = VECTOR; deriv_map_type = H_CURL; }
|
|
#endif
|
|
|
|
/** @brief Set the FiniteElement::MapType of the element to either VALUE or
|
|
INTEGRAL. Also sets the FiniteElement::DerivType to GRAD if the
|
|
FiniteElement::MapType is VALUE. */
|
|
void SetMapType(int M)
|
|
{
|
|
MFEM_VERIFY(M == VALUE || M == INTEGRAL, "unknown MapType");
|
|
map_type = M;
|
|
deriv_type = (M == VALUE) ? GRAD : NONE;
|
|
}
|
|
|
|
|
|
/** @brief Get the matrix @a I that defines nodal interpolation
|
|
@a between this element and the refined element @a fine_fe. */
|
|
void NodalLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I,
|
|
const ScalarFiniteElement &fine_fe) const;
|
|
|
|
/** @brief Get matrix @a I "Interpolation" defined through local
|
|
L2-projection in the space defined by the @a fine_fe. */
|
|
/** If the "fine" elements cannot represent all basis functions of the
|
|
"coarse" element, then boundary values from different sub-elements are
|
|
generally different. */
|
|
void ScalarLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I,
|
|
const ScalarFiniteElement &fine_fe) const;
|
|
|
|
virtual const DofToQuad &GetDofToQuad(const IntegrationRule &ir,
|
|
DofToQuad::Mode mode) const;
|
|
};
|
|
|
|
|
|
/// Class for standard nodal finite elements.
|
|
class NodalFiniteElement : public ScalarFiniteElement
|
|
{
|
|
protected:
|
|
void ProjectCurl_2D(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &curl) const;
|
|
|
|
public:
|
|
/** @brief Construct NodalFiniteElement with given
|
|
@param D Reference space dimension
|
|
@param G Geometry type (of type Geometry::Type)
|
|
@param Do Number of degrees of freedom in the FiniteElement
|
|
@param O Order/degree of the FiniteElement
|
|
@param F FunctionSpace type of the FiniteElement
|
|
*/
|
|
NodalFiniteElement(int D, Geometry::Type G, int Do, int O,
|
|
int F = FunctionSpace::Pk)
|
|
: ScalarFiniteElement(D, G, Do, O, F) { }
|
|
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ NodalLocalInterpolation(Trans, I, *this); }
|
|
|
|
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
|
DenseMatrix &R) const;
|
|
|
|
virtual void GetTransferMatrix(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ CheckScalarFE(fe).NodalLocalInterpolation(Trans, I, *this); }
|
|
|
|
virtual void Project (Coefficient &coeff,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
|
|
virtual void Project (VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
|
|
// (mc.height x mc.width) @ DOFs -> (Dof x mc.width x mc.height) in dofs
|
|
virtual void ProjectMatrixCoefficient(
|
|
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const;
|
|
|
|
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
virtual void ProjectGrad(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &grad) const;
|
|
|
|
virtual void ProjectDiv(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &div) const;
|
|
};
|
|
|
|
/** @brief Class for finite elements utilizing the
|
|
always positive Bernstein basis. */
|
|
class PositiveFiniteElement : public ScalarFiniteElement
|
|
{
|
|
public:
|
|
/** @brief Construct PositiveFiniteElement with given
|
|
@param D Reference space dimension
|
|
@param G Geometry type (of type Geometry::Type)
|
|
@param Do Number of degrees of freedom in the FiniteElement
|
|
@param O Order/degree of the FiniteElement
|
|
@param F FunctionSpace type of the FiniteElement
|
|
*/
|
|
PositiveFiniteElement(int D, Geometry::Type G, int Do, int O,
|
|
int F = FunctionSpace::Pk) :
|
|
ScalarFiniteElement(D, G, Do, O, F)
|
|
{ }
|
|
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ ScalarLocalInterpolation(Trans, I, *this); }
|
|
|
|
virtual void GetTransferMatrix(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ CheckScalarFE(fe).ScalarLocalInterpolation(Trans, I, *this); }
|
|
|
|
using FiniteElement::Project;
|
|
|
|
// Low-order monotone "projection" (actually it is not a projection): the
|
|
// dofs are set to be the Coefficient values at the nodes.
|
|
virtual void Project(Coefficient &coeff,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
|
|
virtual void Project (VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
|
|
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
};
|
|
|
|
/** @brief Intermediate class for finite elements whose basis functions return
|
|
vector values. */
|
|
class VectorFiniteElement : public FiniteElement
|
|
{
|
|
// Hide the scalar functions CalcShape and CalcDShape.
|
|
private:
|
|
/// Overrides the scalar CalcShape function to print an error.
|
|
virtual void CalcShape(const IntegrationPoint &ip,
|
|
Vector &shape) const;
|
|
|
|
/// Overrides the scalar CalcDShape function to print an error.
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
|
|
protected:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable DenseMatrix J, Jinv;
|
|
mutable DenseMatrix curlshape, curlshape_J;
|
|
#endif
|
|
void SetDerivMembers();
|
|
|
|
void CalcVShape_RT(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const;
|
|
|
|
void CalcVShape_ND(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const;
|
|
|
|
void Project_RT(const double *nk, const Array<int> &d2n,
|
|
VectorCoefficient &vc, ElementTransformation &Trans,
|
|
Vector &dofs) const;
|
|
|
|
// project the rows of the matrix coefficient in an RT space
|
|
void ProjectMatrixCoefficient_RT(
|
|
const double *nk, const Array<int> &d2n,
|
|
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const;
|
|
|
|
void Project_RT(const double *nk, const Array<int> &d2n,
|
|
const FiniteElement &fe, ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
// rotated gradient in 2D
|
|
void ProjectGrad_RT(const double *nk, const Array<int> &d2n,
|
|
const FiniteElement &fe, ElementTransformation &Trans,
|
|
DenseMatrix &grad) const;
|
|
|
|
// Compute the curl as a discrete operator from ND FE (fe) to ND FE (this).
|
|
// The natural FE for the range is RT, so this is an approximation.
|
|
void ProjectCurl_ND(const double *tk, const Array<int> &d2t,
|
|
const FiniteElement &fe, ElementTransformation &Trans,
|
|
DenseMatrix &curl) const;
|
|
|
|
void ProjectCurl_RT(const double *nk, const Array<int> &d2n,
|
|
const FiniteElement &fe, ElementTransformation &Trans,
|
|
DenseMatrix &curl) const;
|
|
|
|
void Project_ND(const double *tk, const Array<int> &d2t,
|
|
VectorCoefficient &vc, ElementTransformation &Trans,
|
|
Vector &dofs) const;
|
|
|
|
/// project the rows of the matrix coefficient in an ND space
|
|
void ProjectMatrixCoefficient_ND(
|
|
const double *tk, const Array<int> &d2t,
|
|
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const;
|
|
|
|
void Project_ND(const double *tk, const Array<int> &d2t,
|
|
const FiniteElement &fe, ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
void ProjectGrad_ND(const double *tk, const Array<int> &d2t,
|
|
const FiniteElement &fe, ElementTransformation &Trans,
|
|
DenseMatrix &grad) const;
|
|
|
|
void LocalInterpolation_RT(const VectorFiniteElement &cfe,
|
|
const double *nk, const Array<int> &d2n,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
void LocalInterpolation_ND(const VectorFiniteElement &cfe,
|
|
const double *tk, const Array<int> &d2t,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
void LocalRestriction_RT(const double *nk, const Array<int> &d2n,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &R) const;
|
|
|
|
void LocalRestriction_ND(const double *tk, const Array<int> &d2t,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &R) const;
|
|
|
|
static const VectorFiniteElement &CheckVectorFE(const FiniteElement &fe)
|
|
{
|
|
if (fe.GetRangeType() != VECTOR)
|
|
{ mfem_error("'fe' must be a VectorFiniteElement"); }
|
|
return static_cast<const VectorFiniteElement &>(fe);
|
|
}
|
|
|
|
public:
|
|
VectorFiniteElement (int D, Geometry::Type G, int Do, int O, int M,
|
|
int F = FunctionSpace::Pk) :
|
|
#ifdef MFEM_THREAD_SAFE
|
|
FiniteElement(D, G, Do, O, F)
|
|
{ range_type = VECTOR; map_type = M; SetDerivMembers(); }
|
|
#else
|
|
FiniteElement(D, G, Do, O, F), Jinv(D)
|
|
{ range_type = VECTOR; map_type = M; SetDerivMembers(); }
|
|
#endif
|
|
};
|
|
|
|
/// A 0D point finite element
|
|
class PointFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the PointFiniteElement
|
|
PointFiniteElement();
|
|
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 1D linear element with nodes on the endpoints
|
|
class Linear1DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the Linear1DFiniteElement
|
|
Linear1DFiniteElement();
|
|
|
|
/** virtual function which evaluates the values of all
|
|
shape functions at a given point ip and stores
|
|
them in the vector shape of dimension Dof (2) */
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
/** virtual function which evaluates the derivatives of all
|
|
shape functions at a given point ip and stores them in
|
|
the matrix dshape (Dof x Dim) (2 x 1) so that each row
|
|
contains the derivative of one shape function */
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 2D linear element on triangle with nodes at the vertices of the triangle
|
|
class Linear2DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the Linear2DFiniteElement
|
|
Linear2DFiniteElement();
|
|
|
|
/** virtual function which evaluates the values of all
|
|
shape functions at a given point ip and stores
|
|
them in the vector shape of dimension Dof (3) */
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
/** virtual function which evaluates the values of all
|
|
partial derivatives of all shape functions at a given
|
|
point ip and stores them in the matrix dshape (Dof x Dim) (3 x 2)
|
|
so that each row contains the derivatives of one shape function */
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
|
{ dofs = 0.0; dofs(vertex) = 1.0; }
|
|
};
|
|
|
|
/// A 2D bi-linear element on a square with nodes at the vertices of the square
|
|
class BiLinear2DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the BiLinear2DFiniteElement
|
|
BiLinear2DFiniteElement();
|
|
|
|
/** virtual function which evaluates the values of all
|
|
shape functions at a given point ip and stores
|
|
them in the vector shape of dimension Dof (4) */
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
/** virtual function which evaluates the values of all
|
|
partial derivatives of all shape functions at a given
|
|
point ip and stores them in the matrix dshape (Dof x Dim) (4 x 2)
|
|
so that each row contains the derivatives of one shape function */
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void CalcHessian (const IntegrationPoint &ip,
|
|
DenseMatrix &h) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
|
{ dofs = 0.0; dofs(vertex) = 1.0; } // { dofs = 1.0; }
|
|
};
|
|
|
|
/// A linear element on a triangle with nodes at the 3 "Gaussian" points
|
|
class GaussLinear2DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the GaussLinear2DFiniteElement
|
|
GaussLinear2DFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
/// A 2D bi-linear element on a square with nodes at the "Gaussian" points
|
|
class GaussBiLinear2DFiniteElement : public NodalFiniteElement
|
|
{
|
|
private:
|
|
static const double p[2];
|
|
|
|
public:
|
|
/// Construct the FiniteElement
|
|
GaussBiLinear2DFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
/** @brief A 2D linear element on a square with 3 nodes at the
|
|
vertices of the lower left triangle */
|
|
class P1OnQuadFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the P1OnQuadFiniteElement
|
|
P1OnQuadFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
|
{ dofs = 1.0; }
|
|
};
|
|
|
|
/// A 1D quadractic finite element with uniformly spaced nodes
|
|
class Quad1DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the Quad1DFiniteElement
|
|
Quad1DFiniteElement();
|
|
|
|
/** virtual function which evaluates the values of all
|
|
shape functions at a given point ip and stores
|
|
them in the vector shape of dimension Dof (3) */
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
/** virtual function which evaluates the derivatives of all
|
|
shape functions at a given point ip and stores them in
|
|
the matrix dshape (Dof x Dim) (3 x 1) so that each row
|
|
contains the derivative of one shape function */
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 1D quadratic positive element utilizing the 2nd order Bernstein basis
|
|
class QuadPos1DFiniteElement : public PositiveFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the QuadPos1DFiniteElement
|
|
QuadPos1DFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/** @brief A 2D quadratic element on triangle with nodes at the
|
|
vertices and midpoints of the triangle. */
|
|
class Quad2DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the Quad2DFiniteElement
|
|
Quad2DFiniteElement();
|
|
|
|
/** virtual function which evaluates the values of all
|
|
shape functions at a given point ip and stores
|
|
them in the vector shape of dimension Dof (6) */
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
/** virtual function which evaluates the values of all
|
|
partial derivatives of all shape functions at a given
|
|
point ip and stores them in the matrix dshape (Dof x Dim) (6 x 2)
|
|
so that each row contains the derivatives of one shape function */
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
|
|
virtual void CalcHessian (const IntegrationPoint &ip,
|
|
DenseMatrix &h) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
/// A quadratic element on triangle with nodes at the "Gaussian" points
|
|
class GaussQuad2DFiniteElement : public NodalFiniteElement
|
|
{
|
|
private:
|
|
static const double p[2];
|
|
DenseMatrix A;
|
|
mutable DenseMatrix D;
|
|
mutable Vector pol;
|
|
public:
|
|
/// Construct the GaussQuad2DFiniteElement
|
|
GaussQuad2DFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
// virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
/// A 2D bi-quadratic element on a square with uniformly spaced nodes
|
|
class BiQuad2DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the BiQuad2DFiniteElement
|
|
BiQuad2DFiniteElement();
|
|
|
|
/** virtual function which evaluates the values of all
|
|
shape functions at a given point ip and stores
|
|
them in the vector shape of dimension Dof (9) */
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
/** virtual function which evaluates the values of all
|
|
partial derivatives of all shape functions at a given
|
|
point ip and stores them in the matrix dshape (Dof x Dim) (9 x 2)
|
|
so that each row contains the derivatives of one shape function */
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// A 2D positive bi-quadratic element on a square utilizing the 2nd order
|
|
/// Bernstein basis
|
|
class BiQuadPos2DFiniteElement : public PositiveFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the BiQuadPos2DFiniteElement
|
|
BiQuadPos2DFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
using FiniteElement::Project;
|
|
virtual void Project(Coefficient &coeff, ElementTransformation &Trans,
|
|
Vector &dofs) const;
|
|
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans,
|
|
Vector &dofs) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
|
{ dofs = 0.; dofs(vertex) = 1.; }
|
|
};
|
|
|
|
/// A 2D bi-quadratic element on a square with nodes at the 9 "Gaussian" points
|
|
class GaussBiQuad2DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the GaussBiQuad2DFiniteElement
|
|
GaussBiQuad2DFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
// virtual void ProjectDelta(int vertex, Vector &dofs) const { dofs = 1.; }
|
|
};
|
|
|
|
|
|
/// A 2D bi-cubic element on a square with uniformly spaces nodes
|
|
class BiCubic2DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the BiCubic2DFiniteElement
|
|
BiCubic2DFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
|
|
/// Compute the Hessian of second order partial derivatives at @a ip.
|
|
virtual void CalcHessian (const IntegrationPoint &ip,
|
|
DenseMatrix &h) const;
|
|
};
|
|
|
|
/// A 1D cubic element with uniformly spaced nodes
|
|
class Cubic1DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the Cubic1DFiniteElement
|
|
Cubic1DFiniteElement();
|
|
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 2D cubic element on a triangle with uniformly spaced nodes
|
|
class Cubic2DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the Cubic2DFiniteElement
|
|
Cubic2DFiniteElement();
|
|
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
|
|
virtual void CalcHessian (const IntegrationPoint &ip,
|
|
DenseMatrix &h) const;
|
|
};
|
|
|
|
/// A 3D cubic element on a tetrahedron with 20 nodes at the thirds of the
|
|
/// tetrahedron
|
|
class Cubic3DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the Cubic3DFiniteElement
|
|
Cubic3DFiniteElement();
|
|
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 2D constant element on a triangle
|
|
class P0TriangleFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the P0TriangleFiniteElement
|
|
P0TriangleFiniteElement();
|
|
|
|
/// evaluate shape function - constant 1
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
/// evaluate derivatives of shape function - constant 0
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
|
{ dofs(0) = 1.0; }
|
|
};
|
|
|
|
|
|
/// A 2D constant element on a square
|
|
class P0QuadFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the P0QuadFiniteElement
|
|
P0QuadFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
|
{ dofs(0) = 1.0; }
|
|
};
|
|
|
|
|
|
/** @brief A 3D linear element on a tetrahedron with nodes at the
|
|
vertices of the tetrahedron */
|
|
class Linear3DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the Linear3DFiniteElement
|
|
Linear3DFiniteElement();
|
|
|
|
/** @brief virtual function which evaluates the values of all
|
|
shape functions at a given point ip and stores
|
|
them in the vector shape of dimension Dof (4) */
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
/** @brief virtual function which evaluates the values of all
|
|
partial derivatives of all shape functions at a given
|
|
point ip and stores them in the matrix dshape (Dof x Dim) (4 x 3)
|
|
so that each row contains the derivatives of one shape function */
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
|
{ dofs = 0.0; dofs(vertex) = 1.0; }
|
|
|
|
/** @brief Get the dofs associated with the given @a face.
|
|
@a *dofs is set to an internal array of the local dofc on the
|
|
face, while *ndofs is set to the number of dofs on that face.
|
|
*/
|
|
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const;
|
|
};
|
|
|
|
/// A 3D quadratic element on a tetrahedron with uniformly spaced nodes
|
|
class Quadratic3DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the Quadratic3DFiniteElement
|
|
Quadratic3DFiniteElement();
|
|
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 3D tri-linear element on a cube with nodes at the vertices of the cube
|
|
class TriLinear3DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the TriLinear3DFiniteElement
|
|
TriLinear3DFiniteElement();
|
|
|
|
/** virtual function which evaluates the values of all
|
|
shape functions at a given point ip and stores
|
|
them in the vector shape of dimension Dof (8) */
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
/** virtual function which evaluates the values of all
|
|
partial derivatives of all shape functions at a given
|
|
point ip and stores them in the matrix dshape (Dof x Dim) (8 x 3)
|
|
so that each row contains the derivatives of one shape function */
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
|
{ dofs = 0.0; dofs(vertex) = 1.0; }
|
|
};
|
|
|
|
|
|
/// A 2D Crouzeix-Raviart element on triangle
|
|
class CrouzeixRaviartFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the CrouzeixRaviartFiniteElement
|
|
CrouzeixRaviartFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
|
{ dofs = 1.0; }
|
|
};
|
|
|
|
/// A 2D Crouzeix-Raviart finite element on square
|
|
class CrouzeixRaviartQuadFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the CrouzeixRaviartQuadFiniteElement
|
|
CrouzeixRaviartQuadFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
|
|
/// A 1D constant element on a segment
|
|
class P0SegmentFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the P0SegmentFiniteElement with dummy order @a Ord
|
|
P0SegmentFiniteElement(int Ord = 0);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/** @brief A 2D 1st order Raviart-Thomas vector element on a triangle */
|
|
class RT0TriangleFiniteElement : public VectorFiniteElement
|
|
{
|
|
private:
|
|
static const double nk[3][2];
|
|
|
|
public:
|
|
/// Construct the RT0TriangleFiniteElement
|
|
RT0TriangleFiniteElement();
|
|
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_RT(Trans, shape); }
|
|
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
|
|
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
using FiniteElement::Project;
|
|
|
|
virtual void Project (VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
};
|
|
|
|
/** @brief A 2D 1st order Raviart-Thomas vector element on a square*/
|
|
class RT0QuadFiniteElement : public VectorFiniteElement
|
|
{
|
|
private:
|
|
static const double nk[4][2];
|
|
|
|
public:
|
|
/// Construct the RT0QuadFiniteElement
|
|
RT0QuadFiniteElement();
|
|
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_RT(Trans, shape); }
|
|
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
|
|
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
using FiniteElement::Project;
|
|
|
|
virtual void Project (VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
};
|
|
|
|
/** @brief A 2D 2nd order Raviart-Thomas vector element on a triangle */
|
|
class RT1TriangleFiniteElement : public VectorFiniteElement
|
|
{
|
|
private:
|
|
static const double nk[8][2];
|
|
|
|
public:
|
|
/// Construct the RT1TriangleFiniteElement
|
|
RT1TriangleFiniteElement();
|
|
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_RT(Trans, shape); }
|
|
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
|
|
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
using FiniteElement::Project;
|
|
|
|
virtual void Project (VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
};
|
|
|
|
/** @brief A 2D 2nd order Raviart-Thomas vector element on a square */
|
|
class RT1QuadFiniteElement : public VectorFiniteElement
|
|
{
|
|
private:
|
|
static const double nk[12][2];
|
|
|
|
public:
|
|
/// Construct the RT1QuadFiniteElement
|
|
RT1QuadFiniteElement();
|
|
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_RT(Trans, shape); }
|
|
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
|
|
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
using FiniteElement::Project;
|
|
|
|
virtual void Project (VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
};
|
|
|
|
/** @brief A 2D 3rd order Raviart-Thomas vector element on a triangle */
|
|
class RT2TriangleFiniteElement : public VectorFiniteElement
|
|
{
|
|
private:
|
|
static const double M[15][15];
|
|
public:
|
|
/// Construct the RT2TriangleFiniteElement
|
|
RT2TriangleFiniteElement();
|
|
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_RT(Trans, shape); }
|
|
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
};
|
|
|
|
/** @brief A 2D 3rd order Raviart-Thomas vector element on a square */
|
|
class RT2QuadFiniteElement : public VectorFiniteElement
|
|
{
|
|
private:
|
|
static const double nk[24][2];
|
|
static const double pt[4];
|
|
static const double dpt[3];
|
|
|
|
public:
|
|
/// Construct the RT2QuadFiniteElement
|
|
RT2QuadFiniteElement();
|
|
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_RT(Trans, shape); }
|
|
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
|
|
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
using FiniteElement::Project;
|
|
|
|
virtual void Project (VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
};
|
|
|
|
/// A 1D linear element with nodes at 1/3 and 2/3 (trace of RT1)
|
|
class P1SegmentFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the P1SegmentFiniteElement
|
|
P1SegmentFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 1D quadratic element with nodes at the Gaussian points (trace of RT2)
|
|
class P2SegmentFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the P2SegmentFiniteElement
|
|
P2SegmentFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 1D element with uniform nodes
|
|
class Lagrange1DFiniteElement : public NodalFiniteElement
|
|
{
|
|
private:
|
|
Vector rwk;
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector rxxk;
|
|
#endif
|
|
public:
|
|
/// Construct the Lagrange1DFiniteElement with the provided @a degree
|
|
Lagrange1DFiniteElement (int degree);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 3D Crouzeix-Raviart element on the tetrahedron.
|
|
class P1TetNonConfFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the P1TetNonConfFiniteElement
|
|
P1TetNonConfFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 3D constant element on a tetrahedron
|
|
class P0TetFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the P0TetFiniteElement
|
|
P0TetFiniteElement ();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
|
{ dofs(0) = 1.0; }
|
|
};
|
|
|
|
/// A 3D constant element on a cube
|
|
class P0HexFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the P0HexFiniteElement
|
|
P0HexFiniteElement ();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
|
{ dofs(0) = 1.0; }
|
|
};
|
|
|
|
/** @brief Tensor products of 1D Lagrange1DFiniteElement
|
|
(only degree 2 is functional) */
|
|
class LagrangeHexFiniteElement : public NodalFiniteElement
|
|
{
|
|
private:
|
|
Lagrange1DFiniteElement * fe1d;
|
|
int dof1d;
|
|
int *I, *J, *K;
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape1dx, shape1dy, shape1dz;
|
|
mutable DenseMatrix dshape1dx, dshape1dy, dshape1dz;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the LagrangeHexFiniteElement with the provided @a degree
|
|
LagrangeHexFiniteElement (int degree);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
~LagrangeHexFiniteElement ();
|
|
};
|
|
|
|
|
|
/// A 1D refined linear element
|
|
class RefinedLinear1DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the RefinedLinear1DFiniteElement
|
|
RefinedLinear1DFiniteElement();
|
|
|
|
/** virtual function which evaluates the values of all
|
|
shape functions at a given point ip and stores
|
|
them in the vector shape of dimension Dof (3) */
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
/** virtual function which evaluates the derivatives of all
|
|
shape functions at a given point ip and stores them in
|
|
the matrix dshape (Dof x Dim) (3 x 1) so that each row
|
|
contains the derivative of one shape function */
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 2D refined linear element on a triangle
|
|
class RefinedLinear2DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the RefinedLinear2DFiniteElement
|
|
RefinedLinear2DFiniteElement();
|
|
|
|
/** virtual function which evaluates the values of all
|
|
shape functions at a given point ip and stores
|
|
them in the vector shape of dimension Dof (6) */
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
/** virtual function which evaluates the values of all
|
|
partial derivatives of all shape functions at a given
|
|
point ip and stores them in the matrix dshape (Dof x Dim) (6 x 2)
|
|
so that each row contains the derivatives of one shape function */
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 2D refined linear element on a tetrahedron
|
|
class RefinedLinear3DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the RefinedLinear3DFiniteElement
|
|
RefinedLinear3DFiniteElement();
|
|
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 2D refined bi-linear FE on a square
|
|
class RefinedBiLinear2DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the RefinedBiLinear2DFiniteElement
|
|
RefinedBiLinear2DFiniteElement();
|
|
|
|
/** virtual function which evaluates the values of all
|
|
shape functions at a given point ip and stores
|
|
them in the vector shape of dimension Dof (9) */
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
/** virtual function which evaluates the values of all
|
|
partial derivatives of all shape functions at a given
|
|
point ip and stores them in the matrix dshape (Dof x Dim) (9 x 2)
|
|
so that each row contains the derivatives of one shape function */
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 3D refined tri-linear element on a cube
|
|
class RefinedTriLinear3DFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the RefinedTriLinear3DFiniteElement
|
|
RefinedTriLinear3DFiniteElement();
|
|
|
|
/** virtual function which evaluates the values of all
|
|
shape functions at a given point ip and stores
|
|
them in the vector shape of dimension Dof (9) */
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
|
|
/** virtual function which evaluates the values of all
|
|
partial derivatives of all shape functions at a given
|
|
point ip and stores them in the matrix dshape (Dof x Dim) (9 x 2)
|
|
so that each row contains the derivatives of one shape function */
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
|
|
/// A 3D 1st order Nedelec element on a cube
|
|
class Nedelec1HexFiniteElement : public VectorFiniteElement
|
|
{
|
|
private:
|
|
static const double tk[12][3];
|
|
|
|
public:
|
|
/// Construct the Nedelec1HexFiniteElement
|
|
Nedelec1HexFiniteElement();
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_ND(Trans, shape); }
|
|
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
|
DenseMatrix &curl_shape) const;
|
|
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
using FiniteElement::Project;
|
|
virtual void Project (VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// A 3D 1st order Nedelec element on a tetrahedron
|
|
class Nedelec1TetFiniteElement : public VectorFiniteElement
|
|
{
|
|
private:
|
|
static const double tk[6][3];
|
|
|
|
public:
|
|
/// Construct the Nedelec1TetFiniteElement
|
|
Nedelec1TetFiniteElement();
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_ND(Trans, shape); }
|
|
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
|
DenseMatrix &curl_shape) const;
|
|
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
using FiniteElement::Project;
|
|
virtual void Project (VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// A 3D 0th order Raviert-Thomas element on a cube
|
|
class RT0HexFiniteElement : public VectorFiniteElement
|
|
{
|
|
private:
|
|
static const double nk[6][3];
|
|
|
|
public:
|
|
/// Construct the RT0HexFiniteElement
|
|
RT0HexFiniteElement();
|
|
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_RT(Trans, shape); }
|
|
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
|
|
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
using FiniteElement::Project;
|
|
|
|
virtual void Project (VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// A 3D 1st order Raviert-Thomas element on a cube
|
|
class RT1HexFiniteElement : public VectorFiniteElement
|
|
{
|
|
private:
|
|
static const double nk[36][3];
|
|
|
|
public:
|
|
/// Construct the RT1HexFiniteElement
|
|
RT1HexFiniteElement();
|
|
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_RT(Trans, shape); }
|
|
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
|
|
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
using FiniteElement::Project;
|
|
|
|
virtual void Project (VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// A 3D 0th order Raviert-Thomas element on a tetrahedron
|
|
class RT0TetFiniteElement : public VectorFiniteElement
|
|
{
|
|
private:
|
|
static const double nk[4][3];
|
|
|
|
public:
|
|
/// Construct the RT0TetFiniteElement
|
|
RT0TetFiniteElement();
|
|
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_RT(Trans, shape); }
|
|
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
|
|
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
|
|
using FiniteElement::Project;
|
|
|
|
virtual void Project (VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
class RotTriLinearHexFiniteElement : public NodalFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the RotTriLinearHexFiniteElement
|
|
RotTriLinearHexFiniteElement();
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
|
|
/// Class for computing 1D special polynomials and their associated basis
|
|
/// functions
|
|
class Poly_1D
|
|
{
|
|
public:
|
|
enum EvalType
|
|
{
|
|
ChangeOfBasis = 0, // Use change of basis, O(p^2) Evals
|
|
Barycentric = 1, // Use barycentric Lagrangian interpolation, O(p) Evals
|
|
Positive = 2, // Fast evaluation of Bernstein polynomials
|
|
NumEvalTypes = 3 // Keep count of the number of eval types
|
|
};
|
|
|
|
class Basis
|
|
{
|
|
private:
|
|
int etype;
|
|
DenseMatrixInverse Ai;
|
|
mutable Vector x, w;
|
|
|
|
public:
|
|
/// Create a nodal or positive (Bernstein) basis
|
|
Basis(const int p, const double *nodes, EvalType etype = Barycentric);
|
|
void Eval(const double x, Vector &u) const;
|
|
void Eval(const double x, Vector &u, Vector &d) const;
|
|
};
|
|
|
|
private:
|
|
typedef std::map< int, Array<double*>* > PointsMap;
|
|
typedef std::map< int, Array<Basis*>* > BasisMap;
|
|
|
|
MemoryType h_mt;
|
|
PointsMap points_container;
|
|
BasisMap bases_container;
|
|
|
|
static Array2D<int> binom;
|
|
|
|
static void CalcMono(const int p, const double x, double *u);
|
|
static void CalcMono(const int p, const double x, double *u, double *d);
|
|
|
|
static void CalcChebyshev(const int p, const double x, double *u);
|
|
static void CalcChebyshev(const int p, const double x, double *u, double *d);
|
|
static void CalcChebyshev(const int p, const double x, double *u, double *d,
|
|
double *dd);
|
|
|
|
QuadratureFunctions1D quad_func;
|
|
|
|
public:
|
|
Poly_1D(): h_mt(MemoryType::HOST) { }
|
|
|
|
/** @brief Get a pointer to an array containing the binomial coefficients "p
|
|
choose k" for k=0,...,p for the given p. */
|
|
static const int *Binom(const int p);
|
|
|
|
/** @brief Get the coordinates of the points of the given BasisType,
|
|
@a btype.
|
|
|
|
@param[in] p The polynomial degree; the number of points is `p+1`.
|
|
@param[in] btype The BasisType.
|
|
|
|
@return A pointer to an array containing the `p+1` coordinates of the
|
|
points. Returns NULL if the BasisType has no associated set of
|
|
points. */
|
|
const double *GetPoints(const int p, const int btype);
|
|
|
|
/// Get coordinates of an open (GaussLegendre) set of points if degree @a p
|
|
const double *OpenPoints(const int p,
|
|
const int btype = BasisType::GaussLegendre)
|
|
{ return GetPoints(p, btype); }
|
|
|
|
/// Get coordinates of a closed (GaussLegendre) set of points if degree @a p
|
|
const double *ClosedPoints(const int p,
|
|
const int btype = BasisType::GaussLobatto)
|
|
{ return GetPoints(p, btype); }
|
|
|
|
/** @brief Get a Poly_1D::Basis object of the given degree and BasisType,
|
|
@a btype.
|
|
|
|
@param[in] p The polynomial degree of the basis.
|
|
@param[in] btype The BasisType.
|
|
|
|
@return A reference to an object of type Poly_1D::Basis that represents
|
|
the requested basis type. */
|
|
Basis &GetBasis(const int p, const int btype);
|
|
|
|
/** @brief Evaluate the values of a hierarchical 1D basis at point x
|
|
hierarchical = k-th basis function is degree k polynomial */
|
|
static void CalcBasis(const int p, const double x, double *u)
|
|
// { CalcMono(p, x, u); }
|
|
// Bernstein basis is not hierarchical --> does not work for triangles
|
|
// and tetrahedra
|
|
// { CalcBernstein(p, x, u); }
|
|
// { CalcLegendre(p, x, u); }
|
|
{ CalcChebyshev(p, x, u); }
|
|
|
|
/// Evaluate the values and derivatives of a hierarchical 1D basis at point @a x
|
|
static void CalcBasis(const int p, const double x, double *u, double *d)
|
|
// { CalcMono(p, x, u, d); }
|
|
// { CalcBernstein(p, x, u, d); }
|
|
// { CalcLegendre(p, x, u, d); }
|
|
{ CalcChebyshev(p, x, u, d); }
|
|
|
|
/// Evaluate the values, derivatives and second derivatives of a hierarchical 1D basis at point x
|
|
static void CalcBasis(const int p, const double x, double *u, double *d,
|
|
double *dd)
|
|
// { CalcMono(p, x, u, d); }
|
|
// { CalcBernstein(p, x, u, d); }
|
|
// { CalcLegendre(p, x, u, d); }
|
|
{ CalcChebyshev(p, x, u, d, dd); }
|
|
|
|
/// Evaluate a representation of a Delta function at point x
|
|
static double CalcDelta(const int p, const double x)
|
|
{ return pow(x, (double) p); }
|
|
|
|
/** @brief Compute the points for the Chebyshev polynomials of order @a p
|
|
and place them in the already allocated @a x array. */
|
|
static void ChebyshevPoints(const int p, double *x);
|
|
|
|
/** @brief Compute the @a p terms in the expansion of the binomial (x + y)^p
|
|
and store them in the already allocated @a u array. */
|
|
static void CalcBinomTerms(const int p, const double x, const double y,
|
|
double *u);
|
|
/** @brief Compute the terms in the expansion of the binomial (x + y)^p and
|
|
their derivatives with respect to x assuming that dy/dx = -1. Store the
|
|
results in the already allocated @a u and @a d arrays.*/
|
|
static void CalcBinomTerms(const int p, const double x, const double y,
|
|
double *u, double *d);
|
|
/** @brief Compute the derivatives (w.r.t. x) of the terms in the expansion
|
|
of the binomial (x + y)^p assuming that dy/dx = -1. Store the results
|
|
in the already allocated @a d array.*/
|
|
static void CalcDBinomTerms(const int p, const double x, const double y,
|
|
double *d);
|
|
|
|
/** @brief Compute the values of the Bernstein basis functions of order
|
|
@a p at coordinate @a x and store the results in the already allocated
|
|
@a u array. */
|
|
static void CalcBernstein(const int p, const double x, double *u)
|
|
{ CalcBinomTerms(p, x, 1. - x, u); }
|
|
|
|
/** @brief Compute the values and derivatives of the Bernstein basis functions
|
|
of order @a p at coordinate @a x and store the results in the already allocated
|
|
@a u and @a d arrays. */
|
|
static void CalcBernstein(const int p, const double x, double *u, double *d)
|
|
{ CalcBinomTerms(p, x, 1. - x, u, d); }
|
|
|
|
static void CalcLegendre(const int p, const double x, double *u);
|
|
static void CalcLegendre(const int p, const double x, double *u, double *d);
|
|
|
|
~Poly_1D();
|
|
};
|
|
|
|
extern Poly_1D poly1d;
|
|
|
|
|
|
/// An element defined as an ND tensor product of 1D elements on a segment,
|
|
/// square, or cube
|
|
class TensorBasisElement
|
|
{
|
|
protected:
|
|
int b_type;
|
|
Array<int> dof_map;
|
|
Poly_1D::Basis &basis1d;
|
|
Array<int> inv_dof_map;
|
|
|
|
public:
|
|
enum DofMapType
|
|
{
|
|
L2_DOF_MAP = 0,
|
|
H1_DOF_MAP = 1,
|
|
Sr_DOF_MAP = 2, // Sr = Serendipity
|
|
};
|
|
|
|
TensorBasisElement(const int dims, const int p, const int btype,
|
|
const DofMapType dmtype);
|
|
|
|
int GetBasisType() const { return b_type; }
|
|
|
|
const Poly_1D::Basis& GetBasis1D() const { return basis1d; }
|
|
|
|
/** @brief Get an Array<int> that maps lexicographically ordered indices to
|
|
the indices of the respective nodes/dofs/basis functions. If the dofs are
|
|
ordered lexicographically, i.e. the mapping is identity, the returned
|
|
Array will be empty. */
|
|
const Array<int> &GetDofMap() const { return dof_map; }
|
|
|
|
static Geometry::Type GetTensorProductGeometry(int dim)
|
|
{
|
|
switch (dim)
|
|
{
|
|
case 1: return Geometry::SEGMENT;
|
|
case 2: return Geometry::SQUARE;
|
|
case 3: return Geometry::CUBE;
|
|
default:
|
|
MFEM_ABORT("invalid dimension: " << dim);
|
|
return Geometry::INVALID;
|
|
}
|
|
}
|
|
|
|
/// Return @a base raised to the power @a dim.
|
|
static int Pow(int base, int dim)
|
|
{
|
|
switch (dim)
|
|
{
|
|
case 1: return base;
|
|
case 2: return base*base;
|
|
case 3: return base*base*base;
|
|
default: MFEM_ABORT("invalid dimension: " << dim); return -1;
|
|
}
|
|
}
|
|
};
|
|
|
|
class NodalTensorFiniteElement : public NodalFiniteElement,
|
|
public TensorBasisElement
|
|
{
|
|
public:
|
|
NodalTensorFiniteElement(const int dims, const int p, const int btype,
|
|
const DofMapType dmtype);
|
|
|
|
const DofToQuad &GetDofToQuad(const IntegrationRule &ir,
|
|
DofToQuad::Mode mode) const
|
|
{
|
|
return (mode == DofToQuad::FULL) ?
|
|
ScalarFiniteElement::GetDofToQuad(ir, mode) :
|
|
ScalarFiniteElement::GetTensorDofToQuad(*this, ir, mode);
|
|
}
|
|
};
|
|
|
|
class PositiveTensorFiniteElement : public PositiveFiniteElement,
|
|
public TensorBasisElement
|
|
{
|
|
public:
|
|
PositiveTensorFiniteElement(const int dims, const int p,
|
|
const DofMapType dmtype);
|
|
|
|
const DofToQuad &GetDofToQuad(const IntegrationRule &ir,
|
|
DofToQuad::Mode mode) const
|
|
{
|
|
return (mode == DofToQuad::FULL) ?
|
|
ScalarFiniteElement::GetDofToQuad(ir, mode) :
|
|
ScalarFiniteElement::GetTensorDofToQuad(*this, ir, mode);
|
|
}
|
|
};
|
|
|
|
class VectorTensorFiniteElement : public VectorFiniteElement,
|
|
public TensorBasisElement
|
|
{
|
|
private:
|
|
mutable Array<DofToQuad*> dof2quad_array_open;
|
|
|
|
protected:
|
|
Poly_1D::Basis &cbasis1d, &obasis1d;
|
|
|
|
public:
|
|
VectorTensorFiniteElement(const int dims, const int d, const int p,
|
|
const int cbtype, const int obtype,
|
|
const int M, const DofMapType dmtype);
|
|
|
|
const DofToQuad &GetDofToQuad(const IntegrationRule &ir,
|
|
DofToQuad::Mode mode) const;
|
|
|
|
const DofToQuad &GetDofToQuadOpen(const IntegrationRule &ir,
|
|
DofToQuad::Mode mode) const;
|
|
|
|
const DofToQuad &GetTensorDofToQuad(const IntegrationRule &ir,
|
|
DofToQuad::Mode mode,
|
|
const bool closed) const;
|
|
|
|
~VectorTensorFiniteElement();
|
|
};
|
|
|
|
/// Arbitrary H1 elements in 1D
|
|
class H1_SegmentElement : public NodalTensorFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, dshape_x;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the H1_SegmentElement of order @a p and BasisType @a btype
|
|
H1_SegmentElement(const int p, const int btype = BasisType::GaussLobatto);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary H1 elements in 2D on a square
|
|
class H1_QuadrilateralElement : public NodalTensorFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, dshape_x, dshape_y;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the H1_QuadrilateralElement of order @a p and BasisType @a btype
|
|
H1_QuadrilateralElement(const int p,
|
|
const int btype = BasisType::GaussLobatto);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary H1 elements in 3D on a cube
|
|
class H1_HexahedronElement : public NodalTensorFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, shape_z, dshape_x, dshape_y, dshape_z;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the H1_HexahedronElement of order @a p and BasisType @a btype
|
|
H1_HexahedronElement(const int p, const int btype = BasisType::GaussLobatto);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
/// Arbitrary order H1 elements in 1D utilizing the Bernstein basis
|
|
class H1Pos_SegmentElement : public PositiveTensorFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
// This is to share scratch space between invocations, which helps speed
|
|
// things up, but with OpenMP, we need one copy per thread. Right now, we
|
|
// solve this by allocating this space within each function call every time
|
|
// we call it. Alternatively, we should do some sort thread private thing.
|
|
// Brunner, Jan 2014
|
|
mutable Vector shape_x, dshape_x;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the H1Pos_SegmentElement of order @a p
|
|
H1Pos_SegmentElement(const int p);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary order H1 elements in 2D utilizing the Bernstein basis on a square
|
|
class H1Pos_QuadrilateralElement : public PositiveTensorFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
// See comment in H1Pos_SegmentElement
|
|
mutable Vector shape_x, shape_y, dshape_x, dshape_y;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the H1Pos_QuadrilateralElement of order @a p
|
|
H1Pos_QuadrilateralElement(const int p);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary order H1 serendipity elements in 2D on a quad
|
|
class H1Ser_QuadrilateralElement : public ScalarFiniteElement
|
|
{
|
|
public:
|
|
/// Construct the H1Ser_QuadrilateralElement of order @a p
|
|
H1Ser_QuadrilateralElement(const int p);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const;
|
|
using FiniteElement::Project;
|
|
};
|
|
|
|
/// Arbitrary order H1 elements in 3D utilizing the Bernstein basis on a cube
|
|
class H1Pos_HexahedronElement : public PositiveTensorFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
// See comment in H1Pos_SegementElement.
|
|
mutable Vector shape_x, shape_y, shape_z, dshape_x, dshape_y, dshape_z;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the H1Pos_HexahedronElement of order @a p
|
|
H1Pos_HexahedronElement(const int p);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary order H1 elements in 2D on a tiangle
|
|
class H1_TriangleElement : public NodalFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, shape_l, dshape_x, dshape_y, dshape_l, u;
|
|
mutable Vector ddshape_x, ddshape_y, ddshape_l;
|
|
mutable DenseMatrix du, ddu;
|
|
#endif
|
|
DenseMatrixInverse Ti;
|
|
|
|
public:
|
|
/// Construct the H1_TriangleElement of order @a p and BasisType @a btype
|
|
H1_TriangleElement(const int p, const int btype = BasisType::GaussLobatto);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void CalcHessian(const IntegrationPoint &ip,
|
|
DenseMatrix &ddshape) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary order H1 elements in 3D on a tetrahedron
|
|
class H1_TetrahedronElement : public NodalFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, shape_z, shape_l;
|
|
mutable Vector dshape_x, dshape_y, dshape_z, dshape_l, u;
|
|
mutable Vector ddshape_x, ddshape_y, ddshape_z, ddshape_l;
|
|
mutable DenseMatrix du, ddu;
|
|
#endif
|
|
DenseMatrixInverse Ti;
|
|
|
|
public:
|
|
/// Construct the H1_TetrahedronElement of order @a p and BasisType @a btype
|
|
H1_TetrahedronElement(const int p,
|
|
const int btype = BasisType::GaussLobatto);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void CalcHessian(const IntegrationPoint &ip,
|
|
DenseMatrix &ddshape) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary order H1 elements in 2D utilizing the Bernstein basis on a triangle
|
|
class H1Pos_TriangleElement : public PositiveFiniteElement
|
|
{
|
|
protected:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector m_shape, dshape_1d;
|
|
mutable DenseMatrix m_dshape;
|
|
#endif
|
|
Array<int> dof_map;
|
|
|
|
public:
|
|
/// Construct the H1Pos_TriangleElement of order @a p
|
|
H1Pos_TriangleElement(const int p);
|
|
|
|
// The size of shape is (p+1)(p+2)/2 (dof).
|
|
static void CalcShape(const int p, const double x, const double y,
|
|
double *shape);
|
|
|
|
// The size of dshape_1d is p+1; the size of dshape is (dof x dim).
|
|
static void CalcDShape(const int p, const double x, const double y,
|
|
double *dshape_1d, double *dshape);
|
|
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary order H1 elements in 3D utilizing the Bernstein basis on a
|
|
/// tetrahedron
|
|
class H1Pos_TetrahedronElement : public PositiveFiniteElement
|
|
{
|
|
protected:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector m_shape, dshape_1d;
|
|
mutable DenseMatrix m_dshape;
|
|
#endif
|
|
Array<int> dof_map;
|
|
|
|
public:
|
|
/// Construct the H1Pos_TetrahedronElement of order @a p
|
|
H1Pos_TetrahedronElement(const int p);
|
|
|
|
// The size of shape is (p+1)(p+2)(p+3)/6 (dof).
|
|
static void CalcShape(const int p, const double x, const double y,
|
|
const double z, double *shape);
|
|
|
|
// The size of dshape_1d is p+1; the size of dshape is (dof x dim).
|
|
static void CalcDShape(const int p, const double x, const double y,
|
|
const double z, double *dshape_1d, double *dshape);
|
|
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary order H1 elements in 3D on a wedge
|
|
class H1_WedgeElement : public NodalFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector t_shape, s_shape;
|
|
mutable DenseMatrix t_dshape, s_dshape;
|
|
#endif
|
|
Array<int> t_dof, s_dof;
|
|
|
|
H1_TriangleElement TriangleFE;
|
|
H1_SegmentElement SegmentFE;
|
|
|
|
public:
|
|
/// Construct the H1_WedgeElement of order @a p and BasisType @a btype
|
|
H1_WedgeElement(const int p,
|
|
const int btype = BasisType::GaussLobatto);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// Class for linear FE on wedge
|
|
class BiLinear3DFiniteElement : public H1_WedgeElement
|
|
{
|
|
public:
|
|
/// Construct a linear FE on wedge
|
|
BiLinear3DFiniteElement() : H1_WedgeElement(1) {}
|
|
};
|
|
|
|
/// Class for quadratic FE on wedge
|
|
class BiQuadratic3DFiniteElement : public H1_WedgeElement
|
|
{
|
|
public:
|
|
/// Construct a quadratic FE on wedge
|
|
BiQuadratic3DFiniteElement() : H1_WedgeElement(2) {}
|
|
};
|
|
|
|
/// Class for cubic FE on wedge
|
|
class BiCubic3DFiniteElement : public H1_WedgeElement
|
|
{
|
|
public:
|
|
/// Construct a cubic FE on wedge
|
|
BiCubic3DFiniteElement() : H1_WedgeElement(3) {}
|
|
};
|
|
|
|
/// Arbitrary order H1 elements in 3D utilizing the Bernstein basis on a wedge
|
|
class H1Pos_WedgeElement : public PositiveFiniteElement
|
|
{
|
|
protected:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector t_shape, s_shape;
|
|
mutable DenseMatrix t_dshape, s_dshape;
|
|
#endif
|
|
Array<int> t_dof, s_dof;
|
|
|
|
H1Pos_TriangleElement TriangleFE;
|
|
H1Pos_SegmentElement SegmentFE;
|
|
|
|
public:
|
|
/// Construct the H1Pos_WedgeElement of order @a p
|
|
H1Pos_WedgeElement(const int p);
|
|
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary L2 elements in 1D on a segment
|
|
class L2_SegmentElement : public NodalTensorFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, dshape_x;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the L2_SegmentElement of order @a p and BasisType @a btype
|
|
L2_SegmentElement(const int p, const int btype = BasisType::GaussLegendre);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
/// Arbitrary order L2 elements in 1D utilizing the Bernstein basis on a segment
|
|
class L2Pos_SegmentElement : public PositiveTensorFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, dshape_x;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the L2Pos_SegmentElement of order @a p
|
|
L2Pos_SegmentElement(const int p);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary order L2 elements in 2D on a square
|
|
class L2_QuadrilateralElement : public NodalTensorFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, dshape_x, dshape_y;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the L2_QuadrilateralElement of order @a p and BasisType @a btype
|
|
L2_QuadrilateralElement(const int p,
|
|
const int btype = BasisType::GaussLegendre);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
virtual void ProjectCurl(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &curl) const
|
|
{ ProjectCurl_2D(fe, Trans, curl); }
|
|
};
|
|
|
|
/// Arbitrary order L2 elements in 2D utilizing the Bernstein basis on a square
|
|
class L2Pos_QuadrilateralElement : public PositiveTensorFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, dshape_x, dshape_y;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the L2Pos_QuadrilateralElement of order @a p
|
|
L2Pos_QuadrilateralElement(const int p);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
/// Arbitrary order L2 elements in 3D on a cube
|
|
class L2_HexahedronElement : public NodalTensorFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, shape_z, dshape_x, dshape_y, dshape_z;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the L2_HexahedronElement of order @a p and BasisType @a btype
|
|
L2_HexahedronElement(const int p,
|
|
const int btype = BasisType::GaussLegendre);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary order L2 elements in 3D utilizing the Bernstein basis on a cube
|
|
class L2Pos_HexahedronElement : public PositiveTensorFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, shape_z, dshape_x, dshape_y, dshape_z;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the L2Pos_HexahedronElement of order @a p
|
|
L2Pos_HexahedronElement(const int p);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary order L2 elements in 2D on a triangle
|
|
class L2_TriangleElement : public NodalFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, shape_l, dshape_x, dshape_y, dshape_l, u;
|
|
mutable DenseMatrix du;
|
|
#endif
|
|
DenseMatrixInverse Ti;
|
|
|
|
public:
|
|
/// Construct the L2_TriangleElement of order @a p and BasisType @a btype
|
|
L2_TriangleElement(const int p,
|
|
const int btype = BasisType::GaussLegendre);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
virtual void ProjectCurl(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &curl) const
|
|
{ ProjectCurl_2D(fe, Trans, curl); }
|
|
};
|
|
|
|
/// Arbitrary order L2 elements in 2D utilizing the Bernstein basis on a triangle
|
|
class L2Pos_TriangleElement : public PositiveFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector dshape_1d;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the L2Pos_TriangleElement of order @a p
|
|
L2Pos_TriangleElement(const int p);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary order L2 elements in 3D on a tetrahedron
|
|
class L2_TetrahedronElement : public NodalFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, shape_z, shape_l;
|
|
mutable Vector dshape_x, dshape_y, dshape_z, dshape_l, u;
|
|
mutable DenseMatrix du;
|
|
#endif
|
|
DenseMatrixInverse Ti;
|
|
|
|
public:
|
|
/// Construct the L2_TetrahedronElement of order @a p and BasisType @a btype
|
|
L2_TetrahedronElement(const int p,
|
|
const int btype = BasisType::GaussLegendre);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary order L2 elements in 3D utilizing the Bernstein basis on a
|
|
/// tetrahedron
|
|
class L2Pos_TetrahedronElement : public PositiveFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector dshape_1d;
|
|
#endif
|
|
|
|
public:
|
|
/// Construct the L2Pos_TetrahedronElement of order @a p
|
|
L2Pos_TetrahedronElement(const int p);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void ProjectDelta(int vertex, Vector &dofs) const;
|
|
};
|
|
|
|
|
|
/// Arbitrary order L2 elements in 3D on a wedge
|
|
class L2_WedgeElement : public NodalFiniteElement
|
|
{
|
|
private:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector t_shape, s_shape;
|
|
mutable DenseMatrix t_dshape, s_dshape;
|
|
#endif
|
|
Array<int> t_dof, s_dof;
|
|
|
|
L2_TriangleElement TriangleFE;
|
|
L2_SegmentElement SegmentFE;
|
|
|
|
public:
|
|
/// Construct the L2_WedgeElement of order @a p and BasisType @a btype
|
|
L2_WedgeElement(const int p,
|
|
const int btype = BasisType::GaussLegendre);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// A 0th order L2 element on a Wedge
|
|
class P0WedgeFiniteElement : public L2_WedgeElement
|
|
{
|
|
public:
|
|
/// Construct the P0WedgeFiniteElement
|
|
P0WedgeFiniteElement () : L2_WedgeElement(0) {}
|
|
};
|
|
|
|
/// Arbitrary order L2 elements in 3D utilizing the Bernstein basis on a wedge
|
|
class L2Pos_WedgeElement : public PositiveFiniteElement
|
|
{
|
|
protected:
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector t_shape, s_shape;
|
|
mutable DenseMatrix t_dshape, s_dshape;
|
|
#endif
|
|
Array<int> t_dof, s_dof;
|
|
|
|
L2Pos_TriangleElement TriangleFE;
|
|
L2Pos_SegmentElement SegmentFE;
|
|
|
|
public:
|
|
/// Construct the L2Pos_WedgeElement of order @a p
|
|
L2Pos_WedgeElement(const int p);
|
|
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
};
|
|
|
|
/// Arbitrary order Raviart-Thomas elements in 2D on a square
|
|
class RT_QuadrilateralElement : public VectorTensorFiniteElement
|
|
{
|
|
private:
|
|
static const double nk[8];
|
|
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_cx, shape_ox, shape_cy, shape_oy;
|
|
mutable Vector dshape_cx, dshape_cy;
|
|
#endif
|
|
Array<int> dof2nk;
|
|
|
|
public:
|
|
/** @brief Construct the RT_QuadrilateralElement of order @a p and closed and
|
|
open BasisType @a cb_type and @a ob_type */
|
|
RT_QuadrilateralElement(const int p,
|
|
const int cb_type = BasisType::GaussLobatto,
|
|
const int ob_type = BasisType::GaussLegendre);
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_RT(Trans, shape); }
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
|
|
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
|
DenseMatrix &R) const
|
|
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
|
|
virtual void GetTransferMatrix(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
|
|
using FiniteElement::Project;
|
|
virtual void Project(VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const
|
|
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
|
|
virtual void ProjectMatrixCoefficient(
|
|
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
|
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
|
|
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ Project_RT(nk, dof2nk, fe, Trans, I); }
|
|
// Gradient + rotation = Curl: H1 -> H(div)
|
|
virtual void ProjectGrad(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &grad) const
|
|
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, grad); }
|
|
// Curl = Gradient + rotation: H1 -> H(div)
|
|
virtual void ProjectCurl(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &curl) const
|
|
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, curl); }
|
|
};
|
|
|
|
|
|
/// Arbitrary order Raviart-Thomas elements in 3D on a cube
|
|
class RT_HexahedronElement : public VectorTensorFiniteElement
|
|
{
|
|
static const double nk[18];
|
|
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_cx, shape_ox, shape_cy, shape_oy, shape_cz, shape_oz;
|
|
mutable Vector dshape_cx, dshape_cy, dshape_cz;
|
|
#endif
|
|
Array<int> dof2nk;
|
|
|
|
public:
|
|
/** @brief Construct the RT_HexahedronElement of order @a p and closed and
|
|
open BasisType @a cb_type and @a ob_type */
|
|
RT_HexahedronElement(const int p,
|
|
const int cb_type = BasisType::GaussLobatto,
|
|
const int ob_type = BasisType::GaussLegendre);
|
|
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_RT(Trans, shape); }
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
|
|
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
|
DenseMatrix &R) const
|
|
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
|
|
virtual void GetTransferMatrix(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
|
|
using FiniteElement::Project;
|
|
virtual void Project(VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const
|
|
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
|
|
virtual void ProjectMatrixCoefficient(
|
|
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
|
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
|
|
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ Project_RT(nk, dof2nk, fe, Trans, I); }
|
|
virtual void ProjectCurl(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &curl) const
|
|
{ ProjectCurl_RT(nk, dof2nk, fe, Trans, curl); }
|
|
};
|
|
|
|
|
|
/// Arbitrary order Raviart-Thomas elements in 2D on a triangle
|
|
class RT_TriangleElement : public VectorFiniteElement
|
|
{
|
|
static const double nk[6], c;
|
|
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, shape_l;
|
|
mutable Vector dshape_x, dshape_y, dshape_l;
|
|
mutable DenseMatrix u;
|
|
mutable Vector divu;
|
|
#endif
|
|
Array<int> dof2nk;
|
|
DenseMatrixInverse Ti;
|
|
|
|
public:
|
|
/// Construct the RT_TriangleElement of order @a p
|
|
RT_TriangleElement(const int p);
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_RT(Trans, shape); }
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
|
|
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
|
DenseMatrix &R) const
|
|
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
|
|
virtual void GetTransferMatrix(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
|
|
using FiniteElement::Project;
|
|
virtual void Project(VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const
|
|
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
|
|
virtual void ProjectMatrixCoefficient(
|
|
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
|
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
|
|
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ Project_RT(nk, dof2nk, fe, Trans, I); }
|
|
// Gradient + rotation = Curl: H1 -> H(div)
|
|
virtual void ProjectGrad(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &grad) const
|
|
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, grad); }
|
|
// Curl = Gradient + rotation: H1 -> H(div)
|
|
virtual void ProjectCurl(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &curl) const
|
|
{ ProjectGrad_RT(nk, dof2nk, fe, Trans, curl); }
|
|
};
|
|
|
|
|
|
/// Arbitrary order Raviart-Thomas elements in 3D on a tetrahedron
|
|
class RT_TetrahedronElement : public VectorFiniteElement
|
|
{
|
|
static const double nk[12], c;
|
|
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, shape_z, shape_l;
|
|
mutable Vector dshape_x, dshape_y, dshape_z, dshape_l;
|
|
mutable DenseMatrix u;
|
|
mutable Vector divu;
|
|
#endif
|
|
Array<int> dof2nk;
|
|
DenseMatrixInverse Ti;
|
|
|
|
public:
|
|
/// Construct the RT_TetrahedronElement of order @a p
|
|
RT_TetrahedronElement(const int p);
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_RT(Trans, shape); }
|
|
virtual void CalcDivShape(const IntegrationPoint &ip,
|
|
Vector &divshape) const;
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_RT(*this, nk, dof2nk, Trans, I); }
|
|
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
|
DenseMatrix &R) const
|
|
{ LocalRestriction_RT(nk, dof2nk, Trans, R); }
|
|
virtual void GetTransferMatrix(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_RT(CheckVectorFE(fe), nk, dof2nk, Trans, I); }
|
|
using FiniteElement::Project;
|
|
virtual void Project(VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const
|
|
{ Project_RT(nk, dof2nk, vc, Trans, dofs); }
|
|
virtual void ProjectMatrixCoefficient(
|
|
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
|
{ ProjectMatrixCoefficient_RT(nk, dof2nk, mc, T, dofs); }
|
|
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ Project_RT(nk, dof2nk, fe, Trans, I); }
|
|
virtual void ProjectCurl(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &curl) const
|
|
{ ProjectCurl_RT(nk, dof2nk, fe, Trans, curl); }
|
|
};
|
|
|
|
|
|
/// Arbitrary order Nedelec elements in 3D on a cube
|
|
class ND_HexahedronElement : public VectorTensorFiniteElement
|
|
{
|
|
static const double tk[18];
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_cx, shape_ox, shape_cy, shape_oy, shape_cz, shape_oz;
|
|
mutable Vector dshape_cx, dshape_cy, dshape_cz;
|
|
#endif
|
|
Array<int> dof2tk;
|
|
|
|
public:
|
|
/** @brief Construct the ND_HexahedronElement of order @a p and closed and
|
|
open BasisType @a cb_type and @a ob_type */
|
|
ND_HexahedronElement(const int p,
|
|
const int cb_type = BasisType::GaussLobatto,
|
|
const int ob_type = BasisType::GaussLegendre);
|
|
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_ND(Trans, shape); }
|
|
|
|
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
|
DenseMatrix &curl_shape) const;
|
|
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
|
|
|
|
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
|
DenseMatrix &R) const
|
|
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
|
|
|
|
virtual void GetTransferMatrix(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
|
|
|
|
using FiniteElement::Project;
|
|
|
|
virtual void Project(VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const
|
|
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
|
|
|
virtual void ProjectMatrixCoefficient(
|
|
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
|
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
|
|
|
|
virtual void Project(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ Project_ND(tk, dof2tk, fe, Trans, I); }
|
|
|
|
virtual void ProjectGrad(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &grad) const
|
|
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
|
|
|
|
virtual void ProjectCurl(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &curl) const
|
|
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
|
|
};
|
|
|
|
|
|
/// Arbitrary order Nedelec elements in 2D on a square
|
|
class ND_QuadrilateralElement : public VectorTensorFiniteElement
|
|
{
|
|
static const double tk[8];
|
|
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_cx, shape_ox, shape_cy, shape_oy;
|
|
mutable Vector dshape_cx, dshape_cy;
|
|
#endif
|
|
Array<int> dof2tk;
|
|
|
|
public:
|
|
/** @brief Construct the ND_QuadrilateralElement of order @a p and closed and
|
|
open BasisType @a cb_type and @a ob_type */
|
|
ND_QuadrilateralElement(const int p,
|
|
const int cb_type = BasisType::GaussLobatto,
|
|
const int ob_type = BasisType::GaussLegendre);
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_ND(Trans, shape); }
|
|
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
|
DenseMatrix &curl_shape) const;
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
|
|
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
|
DenseMatrix &R) const
|
|
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
|
|
virtual void GetTransferMatrix(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
|
|
using FiniteElement::Project;
|
|
virtual void Project(VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const
|
|
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
|
virtual void ProjectMatrixCoefficient(
|
|
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
|
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
|
|
virtual void Project(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ Project_ND(tk, dof2tk, fe, Trans, I); }
|
|
virtual void ProjectGrad(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &grad) const
|
|
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
|
|
};
|
|
|
|
|
|
/// Arbitrary order Nedelec elements in 3D on a tetrahedron
|
|
class ND_TetrahedronElement : public VectorFiniteElement
|
|
{
|
|
static const double tk[18], c;
|
|
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, shape_z, shape_l;
|
|
mutable Vector dshape_x, dshape_y, dshape_z, dshape_l;
|
|
mutable DenseMatrix u;
|
|
#endif
|
|
Array<int> dof2tk;
|
|
DenseMatrixInverse Ti;
|
|
|
|
public:
|
|
/// Construct the ND_TetrahedronElement of order @a p
|
|
ND_TetrahedronElement(const int p);
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_ND(Trans, shape); }
|
|
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
|
DenseMatrix &curl_shape) const;
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
|
|
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
|
DenseMatrix &R) const
|
|
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
|
|
virtual void GetTransferMatrix(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
|
|
using FiniteElement::Project;
|
|
virtual void Project(VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const
|
|
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
|
virtual void ProjectMatrixCoefficient(
|
|
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
|
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
|
|
virtual void Project(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ Project_ND(tk, dof2tk, fe, Trans, I); }
|
|
virtual void ProjectGrad(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &grad) const
|
|
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
|
|
|
|
virtual void ProjectCurl(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &curl) const
|
|
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
|
|
};
|
|
|
|
/// Arbitrary order Nedelec elements in 2D on a triangle
|
|
class ND_TriangleElement : public VectorFiniteElement
|
|
{
|
|
static const double tk[8], c;
|
|
|
|
#ifndef MFEM_THREAD_SAFE
|
|
mutable Vector shape_x, shape_y, shape_l;
|
|
mutable Vector dshape_x, dshape_y, dshape_l;
|
|
mutable DenseMatrix u;
|
|
mutable Vector curlu;
|
|
#endif
|
|
Array<int> dof2tk;
|
|
DenseMatrixInverse Ti;
|
|
|
|
public:
|
|
/// Construct the ND_TriangleElement of order @a p
|
|
ND_TriangleElement(const int p);
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_ND(Trans, shape); }
|
|
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
|
DenseMatrix &curl_shape) const;
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
|
|
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
|
DenseMatrix &R) const
|
|
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
|
|
virtual void GetTransferMatrix(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
|
|
using FiniteElement::Project;
|
|
virtual void Project(VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const
|
|
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
|
virtual void ProjectMatrixCoefficient(
|
|
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
|
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
|
|
virtual void Project(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ Project_ND(tk, dof2tk, fe, Trans, I); }
|
|
virtual void ProjectGrad(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &grad) const
|
|
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
|
|
};
|
|
|
|
|
|
/// Arbitrary order Nedelec elements in 1D on a segment
|
|
class ND_SegmentElement : public VectorFiniteElement
|
|
{
|
|
static const double tk[1];
|
|
|
|
Poly_1D::Basis &obasis1d;
|
|
Array<int> dof2tk;
|
|
|
|
public:
|
|
/** @brief Construct the ND_SegmentElement of order @a p and open
|
|
BasisType @a ob_type */
|
|
ND_SegmentElement(const int p, const int ob_type = BasisType::GaussLegendre);
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
|
|
{ obasis1d.Eval(ip.x, shape); }
|
|
virtual void CalcVShape(const IntegrationPoint &ip,
|
|
DenseMatrix &shape) const;
|
|
virtual void CalcVShape(ElementTransformation &Trans,
|
|
DenseMatrix &shape) const
|
|
{ CalcVShape_ND(Trans, shape); }
|
|
// virtual void CalcCurlShape(const IntegrationPoint &ip,
|
|
// DenseMatrix &curl_shape) const;
|
|
virtual void GetLocalInterpolation(ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
|
|
virtual void GetLocalRestriction(ElementTransformation &Trans,
|
|
DenseMatrix &R) const
|
|
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
|
|
virtual void GetTransferMatrix(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
|
|
using FiniteElement::Project;
|
|
virtual void Project(VectorCoefficient &vc,
|
|
ElementTransformation &Trans, Vector &dofs) const
|
|
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
|
|
virtual void ProjectMatrixCoefficient(
|
|
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
|
|
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
|
|
virtual void Project(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &I) const
|
|
{ Project_ND(tk, dof2tk, fe, Trans, I); }
|
|
virtual void ProjectGrad(const FiniteElement &fe,
|
|
ElementTransformation &Trans,
|
|
DenseMatrix &grad) const
|
|
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
|
|
};
|
|
|
|
|
|
/// An arbitrary order and dimension NURBS element
|
|
class NURBSFiniteElement : public ScalarFiniteElement
|
|
{
|
|
protected:
|
|
mutable Array <const KnotVector*> kv;
|
|
mutable const int *ijk;
|
|
mutable int patch, elem;
|
|
mutable Vector weights;
|
|
|
|
public:
|
|
/** @brief Construct NURBSFiniteElement with given
|
|
@param D Reference space dimension
|
|
@param G Geometry type (of type Geometry::Type)
|
|
@param Do Number of degrees of freedom in the FiniteElement
|
|
@param O Order/degree of the FiniteElement
|
|
@param F FunctionSpace type of the FiniteElement
|
|
*/
|
|
NURBSFiniteElement(int D, Geometry::Type G, int Do, int O, int F)
|
|
: ScalarFiniteElement(D, G, Do, O, F)
|
|
{
|
|
ijk = NULL;
|
|
patch = elem = -1;
|
|
kv.SetSize(dim);
|
|
weights.SetSize(dof);
|
|
weights = 1.0;
|
|
}
|
|
|
|
void Reset () const { patch = elem = -1; }
|
|
void SetIJK (const int *IJK) const { ijk = IJK; }
|
|
int GetPatch () const { return patch; }
|
|
void SetPatch (int p) const { patch = p; }
|
|
int GetElement () const { return elem; }
|
|
void SetElement (int e) const { elem = e; }
|
|
Array <const KnotVector*> &KnotVectors() const { return kv; }
|
|
Vector &Weights () const { return weights; }
|
|
/// Update the NURBSFiniteElement according to the currently set knot vectors
|
|
virtual void SetOrder () const { }
|
|
};
|
|
|
|
|
|
/// An arbitrary order 1D NURBS element on a segment
|
|
class NURBS1DFiniteElement : public NURBSFiniteElement
|
|
{
|
|
protected:
|
|
mutable Vector shape_x;
|
|
|
|
public:
|
|
/// Construct the NURBS1DFiniteElement of order @a p
|
|
NURBS1DFiniteElement(int p)
|
|
: NURBSFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Qk),
|
|
shape_x(p + 1) { }
|
|
|
|
virtual void SetOrder() const;
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void CalcHessian (const IntegrationPoint &ip,
|
|
DenseMatrix &hessian) const;
|
|
};
|
|
|
|
/// An arbitrary order 2D NURBS element on a square
|
|
class NURBS2DFiniteElement : public NURBSFiniteElement
|
|
{
|
|
protected:
|
|
mutable Vector u, shape_x, shape_y, dshape_x, dshape_y, d2shape_x, d2shape_y;
|
|
mutable DenseMatrix du;
|
|
|
|
public:
|
|
/// Construct the NURBS2DFiniteElement of order @a p
|
|
NURBS2DFiniteElement(int p)
|
|
: NURBSFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
|
|
FunctionSpace::Qk),
|
|
u(dof), shape_x(p + 1), shape_y(p + 1), dshape_x(p + 1),
|
|
dshape_y(p + 1), d2shape_x(p + 1), d2shape_y(p + 1), du(dof,2)
|
|
{ orders[0] = orders[1] = p; }
|
|
|
|
/// Construct the NURBS2DFiniteElement with x-order @a px and y-order @a py
|
|
NURBS2DFiniteElement(int px, int py)
|
|
: NURBSFiniteElement(2, Geometry::SQUARE, (px + 1)*(py + 1),
|
|
std::max(px, py), FunctionSpace::Qk),
|
|
u(dof), shape_x(px + 1), shape_y(py + 1), dshape_x(px + 1),
|
|
dshape_y(py + 1), d2shape_x(px + 1), d2shape_y(py + 1), du(dof,2)
|
|
{ orders[0] = px; orders[1] = py; }
|
|
|
|
virtual void SetOrder() const;
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void CalcHessian (const IntegrationPoint &ip,
|
|
DenseMatrix &hessian) const;
|
|
};
|
|
|
|
/// An arbitrary order 3D NURBS element on a cube
|
|
class NURBS3DFiniteElement : public NURBSFiniteElement
|
|
{
|
|
protected:
|
|
mutable Vector u, shape_x, shape_y, shape_z;
|
|
mutable Vector dshape_x, dshape_y, dshape_z;
|
|
mutable Vector d2shape_x, d2shape_y, d2shape_z;
|
|
mutable DenseMatrix du;
|
|
|
|
public:
|
|
/// Construct the NURBS3DFiniteElement of order @a p
|
|
NURBS3DFiniteElement(int p)
|
|
: NURBSFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
|
|
FunctionSpace::Qk),
|
|
u(dof), shape_x(p + 1), shape_y(p + 1), shape_z(p + 1),
|
|
dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1),
|
|
d2shape_x(p + 1), d2shape_y(p + 1), d2shape_z(p + 1), du(dof,3)
|
|
{ orders[0] = orders[1] = orders[2] = p; }
|
|
|
|
/// Construct the NURBS3DFiniteElement with x-order @a px and y-order @a py
|
|
/// and z-order @a pz
|
|
NURBS3DFiniteElement(int px, int py, int pz)
|
|
: NURBSFiniteElement(3, Geometry::CUBE, (px + 1)*(py + 1)*(pz + 1),
|
|
std::max(std::max(px,py),pz), FunctionSpace::Qk),
|
|
u(dof), shape_x(px + 1), shape_y(py + 1), shape_z(pz + 1),
|
|
dshape_x(px + 1), dshape_y(py + 1), dshape_z(pz + 1),
|
|
d2shape_x(px + 1), d2shape_y(py + 1), d2shape_z(pz + 1), du(dof,3)
|
|
{ orders[0] = px; orders[1] = py; orders[2] = pz; }
|
|
|
|
virtual void SetOrder() const;
|
|
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
|
virtual void CalcDShape(const IntegrationPoint &ip,
|
|
DenseMatrix &dshape) const;
|
|
virtual void CalcHessian (const IntegrationPoint &ip,
|
|
DenseMatrix &hessian) const;
|
|
};
|
|
|
|
} // namespace mfem
|
|
|
|
#endif
|