9#ifndef LF_FE_LOCCOMPELLBVP
10#define LF_FE_LOCCOMPELLBVP
16#include <lf/mesh/utils/utils.h>
17#include <lf/quad/quad.h>
22#include "scalar_fe_space.h"
23#include "scalar_reference_finite_element.h"
75template <base::Scalar SCALAR, mesh::utils::MeshFunction DIFF_COEFF>
83 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>())
::Scalar;
84 using ElemMat = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
111 std::shared_ptr<const
ScalarFESpace<SCALAR>> fe_space, DIFF_COEFF alpha);
116 bool isActive(const
lf::mesh::Entity & )
const {
return true; }
154template <
class PTR,
class DIFF_COEFF>
160template <base::Scalar SCALAR, mesh::utils::MeshFunction DIFF_COEFF>
164 : alpha_(std::move(alpha)), fe_space_(std::move(fe_space)) {}
169template <base::Scalar SCALAR, mesh::utils::MeshFunction DIFF_COEFF>
175 LF_ASSERT_MSG(geo_ptr !=
nullptr,
"Invalid geometry!");
176 LF_ASSERT_MSG((geo_ptr->
DimLocal() == 2),
177 "Only 2D implementation available!");
179 "{}, shape = \n{}", cell.
RefEl(),
185 const auto sfl = fe_space_->ShapeFunctionLayout(cell);
191 "Mismatch " << determinants.size() <<
" <-> " << qr.
NumPoints());
194 LF_ASSERT_MSG(JinvT.cols() ==
static_cast<std::ptrdiff_t
>(2) * qr.
NumPoints(),
195 "Mismatch " << JinvT.cols() <<
" <-> " << 2 * qr.
NumPoints());
196 LF_ASSERT_MSG(JinvT.rows() == world_dim,
197 "Mismatch " << JinvT.rows() <<
" <-> " << world_dim);
199 auto alphaval = alpha_(cell, qr.
Points());
202 ElemMat mat(sfl->NumRefShapeFunctions(), sfl->NumRefShapeFunctions());
206 const auto grsf = sfl->GradientsReferenceShapeFunctions(qr.
Points());
209 const double w = qr.
Weights()[k] * determinants[k];
212 JinvT.block(0,
static_cast<Eigen::Index
>(2) * k, world_dim, 2) *
213 grsf.block(0,
static_cast<Eigen::Index
>(2) * k, mat.rows(), 2)
216 mat += w * trf_grad.adjoint() * (alphaval[k] * trf_grad);
255template <base::Scalar SCALAR, mesh::utils::MeshFunction REACTION_COEFF>
263 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>())
::Scalar;
264 using ElemMat = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
289 REACTION_COEFF gamma);
295 bool isActive(const
lf::mesh::Entity & )
const {
return true; }
335template <
class PTR,
class REACTION_COEFF>
341template <base::Scalar SCALAR, mesh::utils::MeshFunction REACTION_COEFF>
344 : gamma_(std::move(gamma)), fe_space_(std::move(fe_space)) {}
349template <base::Scalar SCALAR, mesh::utils::MeshFunction REACTION_COEFF>
355 LF_ASSERT_MSG(geo_ptr !=
nullptr,
"Invalid geometry!");
356 LF_ASSERT_MSG((geo_ptr->
DimLocal() == 2),
357 "Only 2D implementation available!");
364 const auto sfl = fe_space_->ShapeFunctionLayout(cell);
370 "Mismatch " << determinants.size() <<
" <-> " << qr.
NumPoints());
372 auto gammaval = gamma_(cell, qr.
Points());
374 ElemMat mat(sfl->NumRefShapeFunctions(), sfl->NumRefShapeFunctions());
377 const auto rsf = sfl->EvalReferenceShapeFunctions(qr.
Points());
380 const double w = qr.
Weights()[k] * determinants[k];
381 mat += w * ((gammaval[k] * rsf.col(k)) * (rsf.col(k).adjoint()));
411template <
typename SCALAR,
typename COEFF,
typename EDGE
SELECTOR>
416 using ElemMat = Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>;
439 EDGESELECTOR edge_selector = base::PredicateTrue{})
440 :
gamma_(std::move(gamma)),
452 "Wrong type for an edge");
490template <
class PTR,
class COEFF,
class EDGE
SELECTOR = base::PredicateTrue>
501template <
class SCALAR,
class COEFF,
class EDGE
SELECTOR>
507 const auto sfl = fe_space_->ShapeFunctionLayout(edge);
514 "Mismatch " << determinants.size() <<
" <-> " << qr.
NumPoints());
517 ElemMat mat(sfl->NumRefShapeFunctions(), sfl->NumRefShapeFunctions());
520 auto gammaval = gamma_(edge, qr.
Points());
523 const auto rsf = sfl->EvalReferenceShapeFunctions(qr.
Points());
525 for (
long k = 0; k < determinants.size(); ++k) {
528 const auto w = (qr.
Weights()[k] * determinants[k]) * gammaval[k];
529 mat += ((rsf.col(k)) * (rsf.col(k).adjoint())) * w;
568template <base::Scalar SCALAR, mesh::utils::MeshFunction MESH_FUNCTION>
572 decltype(
static_cast<SCALAR
>(0) *
575 using ElemVec = Eigen::Matrix<scalar_t, Eigen::Dynamic, 1>;
598 std::shared_ptr<const
ScalarFESpace<SCALAR>> fe_space, MESH_FUNCTION f);
600 bool isActive(const
lf::mesh::Entity & )
const {
return true; }
627template <
class PTR,
class MESH_FUNCTION>
633template <base::Scalar SCALAR, mesh::utils::MeshFunction MESH_FUNCTION>
637 : f_(std::move(f)), fe_space_(std::move(fe_space)) {}
642template <base::Scalar SCALAR, mesh::utils::MeshFunction MESH_FUNCTION>
650 const auto sfl = fe_space_->ShapeFunctionLayout(cell);
657 LF_ASSERT_MSG(geo_ptr !=
nullptr,
"Invalid geometry!");
658 LF_ASSERT_MSG((geo_ptr->
DimLocal() == 2),
659 "Only 2D implementation available!");
661 "{}, shape = \n{}", cell.
RefEl(),
668 "Mismatch " << determinants.size() <<
" <-> " << qr.
NumPoints());
670 "LOCVEC({}): Metric factors :\n{}", cell.
RefEl(),
671 determinants.transpose());
673 ElemVec vec(sfl->NumRefShapeFunctions());
676 auto fval = f_(cell, qr.
Points());
679 const auto rsf = sfl->EvalReferenceShapeFunctions(qr.
Points());
682 for (
long k = 0; k < determinants.size(); ++k) {
684 "LOCVEC: [{}] -> [weight = {}]",
688 (qr.
Weights()[k] * determinants[k] * fval[k]) * rsf.col(k).conjugate();
734 using ElemVec = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
758 std::shared_ptr<const
ScalarFESpace<SCALAR>> fe_space, FUNCTOR g,
759 EDGESELECTOR edge_sel = base::PredicateTrue{})
789template <
class PTR,
class FUNCTOR,
class EDGE
SELECTOR = base::PredicateTrue>
805 LF_ASSERT_MSG(geo_ptr !=
nullptr,
"Invalid geometry!");
806 LF_ASSERT_MSG(geo_ptr->
DimLocal() == 1,
"The passed entity is not an edge!");
809 const auto sfl = fe_space_->ShapeFunctionLayout(edge);
818 "Mismatch " << determinants.size() <<
" <-> " << qr.
NumPoints());
821 ElemVec vec(sfl->NumRefShapeFunctions());
824 auto g_vals = g_(edge, qr.
Points());
827 const auto rsf = sfl->EvalReferenceShapeFunctions(qr.
Points());
832 const auto w = (qr.
Weights()[k] * determinants[k]) * g_vals[k];
833 vec += rsf.col(k).conjugate() * w;
A Function Object that can be invoked with any arguments and that always returns the value true.
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
const Eigen::MatrixXd & NodeCoords() const
Get the coordinates of the nodes of this reference element.
Class for computing element matrices for general scalar-valued finite elements and homogeneous 2nd-or...
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > ElemMat
DiffusionElementMatrixProvider(DiffusionElementMatrixProvider &&) noexcept=default
ElemMat Eval(const lf::mesh::Entity &cell) const
Routine for the computation of element matrices.
DiffusionElementMatrixProvider(const DiffusionElementMatrixProvider &)=delete
standard constructors
~DiffusionElementMatrixProvider()=default
quad::QuadRuleCache qr_cache_
std::shared_ptr< const ScalarFESpace< SCALAR > > fe_space_
bool isActive(const lf::mesh::Entity &) const
All cells are considered active.
typename decltype(mesh::utils::MeshFunctionReturnType< DIFF_COEFF >() * Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 >())::Scalar Scalar
type of returned element matrix
Quadrature-based computation of local mass matrix for an edge.
MassEdgeMatrixProvider(MassEdgeMatrixProvider &&) noexcept=default
quad::QuadRuleCache qr_cache_
decltype(SCALAR(0) *mesh::utils::MeshFunctionReturnType< COEFF >(0)) scalar_t
bool isActive(const lf::mesh::Entity &edge) const
If true, then an edge is taken into account during assembly.
ElemMat Eval(const lf::mesh::Entity &edge) const
actual computation of edge mass matrix
Eigen::Matrix< scalar_t, Eigen::Dynamic, Eigen::Dynamic > ElemMat
~MassEdgeMatrixProvider()=default
MassEdgeMatrixProvider(const MassEdgeMatrixProvider &)=delete
std::shared_ptr< const ScalarFESpace< SCALAR > > fe_space_
Class for local quadrature based computation of element matrix for Lagrangian finite elements and a w...
MassElementMatrixProvider(const MassElementMatrixProvider &)=delete
standard constructors
quad::QuadRuleCache qr_cache_
std::shared_ptr< const ScalarFESpace< SCALAR > > fe_space_
typename decltype(mesh::utils::MeshFunctionReturnType< REACTION_COEFF >() * Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 >())::Scalar Scalar
type of returned element matrix
ElemMat Eval(const lf::mesh::Entity &cell) const
main routine for the computation of element matrices
MassElementMatrixProvider(MassElementMatrixProvider &&) noexcept=default
bool isActive(const lf::mesh::Entity &) const
All cells are considered active.
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > ElemMat
~MassElementMatrixProvider()=default
Space of scalar valued finite element functions on a Mesh.
Local edge contributions to element vector.
ElemVec Eval(const lf::mesh::Entity &edge) const
std::shared_ptr< const ScalarFESpace< SCALAR > > fe_space_
ScalarLoadEdgeVectorProvider(ScalarLoadEdgeVectorProvider &&) noexcept=default
decltype(SCALAR(0) *mesh::utils::MeshFunctionReturnType< FUNCTOR >(0)) Scalar
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > ElemVec
ScalarLoadEdgeVectorProvider(const ScalarLoadEdgeVectorProvider &)=delete
bool isActive(const lf::mesh::Entity &cell) const
all edges are active
~ScalarLoadEdgeVectorProvider()=default
quad::QuadRuleCache qr_cache_
Local computation of general element (load) vector for scalar finite elements; volume contributions o...
bool isActive(const lf::mesh::Entity &) const
all cells are active
ElemVec Eval(const lf::mesh::Entity &cell) const
decltype(static_cast< SCALAR >(0) * static_cast< mesh::utils::MeshFunctionReturnType< MESH_FUNCTION > >( 0)) scalar_t
MESH_FUNCTION f_
An object providing the source function.
ScalarLoadElementVectorProvider(const ScalarLoadElementVectorProvider &)=delete
ScalarLoadElementVectorProvider(ScalarLoadElementVectorProvider &&) noexcept=default
~ScalarLoadElementVectorProvider()=default
quad::QuadRuleCache qr_cache_
std::shared_ptr< const ScalarFESpace< SCALAR > > fe_space_
Eigen::Matrix< scalar_t, Eigen::Dynamic, 1 > ElemVec
Interface class for shape information on a mesh cell in the spirit of parametric finite element metho...
virtual Eigen::MatrixXd Global(const Eigen::MatrixXd &local) const =0
Map a number of points in local coordinates into the global coordinate system.
virtual dim_t DimLocal() const =0
Dimension of the domain of this mapping.
virtual dim_t DimGlobal() const =0
Dimension of the image of this mapping.
virtual Eigen::MatrixXd JacobianInverseGramian(const Eigen::MatrixXd &local) const =0
Evaluate the Jacobian * Inverse Gramian ( ) simultaneously at numPoints.
virtual Eigen::VectorXd IntegrationElement(const Eigen::MatrixXd &local) const =0
The integration element (factor appearing in integral transformation formula, see below) at number of...
Interface class representing a topological entity in a cellular complex
virtual const geometry::Geometry * Geometry() const =0
Describes the geometry of this entity.
virtual base::RefEl RefEl() const =0
Describes the reference element type of this entity.
A cache for make_QuadRule()
Represents a Quadrature Rule over one of the Reference Elements.
const Eigen::VectorXd & Weights() const
All quadrature weights as a vector.
const Eigen::MatrixXd & Points() const
All quadrature points as column vectors.
base::size_type NumPoints() const
Return the total number of quadrature points (num of columns of points/weights)
Concept which is fulfilled if a type T is a scalar type, i.e. if it is a "field" in the mathematical ...
A MeshFunction is a function object that can be evaluated at any point on the mesh.
unsigned int size_type
general type for variables related to size of arrays
Collects data structures and algorithms designed for scalar finite element methods primarily meant fo...
std::shared_ptr< spdlog::logger > & MassElementMatrixProviderLogger()
logger for MassElementMatrixProvider
std::shared_ptr< spdlog::logger > & ScalarLoadElementVectorProviderLogger()
logger used by ScalarLoadElementVectorProvider
ScalarLoadElementVectorProvider(PTR fe_space, MESH_FUNCTION mf) -> ScalarLoadElementVectorProvider< typename PTR::element_type::Scalar, MESH_FUNCTION >
ScalarLoadEdgeVectorProvider(PTR, FUNCTOR, EDGESELECTOR=base::PredicateTrue{}) -> ScalarLoadEdgeVectorProvider< typename PTR::element_type::Scalar, FUNCTOR, EDGESELECTOR >
std::shared_ptr< spdlog::logger > & DiffusionElementMatrixProviderLogger()
logger for DiffusionElementMatrixProvider
std::shared_ptr< spdlog::logger > & MassEdgeMatrixProviderLogger()
logger for MassEdgeMatrixProvider
MassEdgeMatrixProvider(PTR, COEFF coeff, EDGESELECTOR edge_predicate=base::PredicateTrue{}) -> MassEdgeMatrixProvider< typename PTR::element_type::Scalar, COEFF, EDGESELECTOR >
MassElementMatrixProvider(PTR fe_space, REACTION_COEFF gamma) -> MassElementMatrixProvider< typename PTR::element_type::Scalar, REACTION_COEFF >
lf::assemble::dim_t dim_t
DiffusionElementMatrixProvider(PTR fe_space, DIFF_COEFF alpha) -> DiffusionElementMatrixProvider< typename PTR::element_type::Scalar, DIFF_COEFF >
std::shared_ptr< spdlog::logger > & ScalarLoadEdgeVectorProviderLogger()
logger for ScalarLoadEdgeVectorProvider class template.
internal::VectorElement_t< internal::MeshFunctionReturnType_t< R > > MeshFunctionReturnType
Determine the type of objects returned by a MeshFunction.