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"
58template <
typename SCALAR,
typename DIFF_COEFF>
60 static_assert(mesh::utils::isMeshFunction<DIFF_COEFF>);
68 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>())
::Scalar;
69 using ElemMat = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
97 std::shared_ptr<const
ScalarFESpace<SCALAR>> fe_space, DIFF_COEFF alpha);
102 bool isActive(const
lf::mesh::Entity & )
const {
return true; }
142template <
class PTR,
class DIFF_COEFF>
148template <
typename SCALAR,
typename DIFF_COEFF>
152 : alpha_(std::move(alpha)), fe_space_(std::move(fe_space)) {}
157template <
typename SCALAR,
typename DIFF_COEFF>
163 LF_ASSERT_MSG(geo_ptr !=
nullptr,
"Invalid geometry!");
164 LF_ASSERT_MSG((geo_ptr->
DimLocal() == 2),
165 "Only 2D implementation available!");
167 "{}, shape = \n{}", cell.
RefEl(),
173 const auto sfl = fe_space_->ShapeFunctionLayout(cell);
179 "Mismatch " << determinants.size() <<
" <-> " << qr.
NumPoints());
182 LF_ASSERT_MSG(JinvT.cols() == 2 * qr.
NumPoints(),
183 "Mismatch " << JinvT.cols() <<
" <-> " << 2 * qr.
NumPoints());
184 LF_ASSERT_MSG(JinvT.rows() == world_dim,
185 "Mismatch " << JinvT.rows() <<
" <-> " << world_dim);
187 auto alphaval = alpha_(cell, qr.
Points());
190 ElemMat mat(sfl->NumRefShapeFunctions(), sfl->NumRefShapeFunctions());
194 const auto grsf = sfl->GradientsReferenceShapeFunctions(qr.
Points());
197 const double w = qr.
Weights()[k] * determinants[k];
199 const auto trf_grad(JinvT.block(0, 2 * k, world_dim, 2) *
200 grsf.block(0, 2 * k, mat.rows(), 2).transpose());
202 mat += w * trf_grad.adjoint() * (alphaval[k] * trf_grad);
237template <
typename SCALAR,
typename REACTION_COEFF>
239 static_assert(mesh::utils::isMeshFunction<REACTION_COEFF>);
247 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>())
::Scalar;
248 using ElemMat = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
273 REACTION_COEFF gamma);
279 bool isActive(const
lf::mesh::Entity & )
const {
return true; }
319template <
class PTR,
class REACTION_COEFF>
325template <
typename SCALAR,
typename REACTION_COEFF>
328 : gamma_(std::move(gamma)), fe_space_(std::move(fe_space)) {}
333template <
typename SCALAR,
typename REACTION_COEFF>
339 LF_ASSERT_MSG(geo_ptr !=
nullptr,
"Invalid geometry!");
340 LF_ASSERT_MSG((geo_ptr->
DimLocal() == 2),
341 "Only 2D implementation available!");
348 const auto sfl = fe_space_->ShapeFunctionLayout(cell);
354 "Mismatch " << determinants.size() <<
" <-> " << qr.
NumPoints());
356 auto gammaval = gamma_(cell, qr.
Points());
358 ElemMat mat(sfl->NumRefShapeFunctions(), sfl->NumRefShapeFunctions());
361 const auto rsf = sfl->EvalReferenceShapeFunctions(qr.
Points());
364 const double w = qr.
Weights()[k] * determinants[k];
365 mat += w * ((gammaval[k] * rsf.col(k)) * (rsf.col(k).adjoint()));
391template <
typename SCALAR,
typename COEFF,
typename EDGE
SELECTOR>
396 using ElemMat = Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>;
419 EDGESELECTOR edge_selector = base::PredicateTrue{})
420 :
gamma_(std::move(gamma)),
432 "Wrong type for an edge");
470template <
class PTR,
class COEFF,
class EDGE
SELECTOR = base::PredicateTrue>
481template <
class SCALAR,
class COEFF,
class EDGE
SELECTOR>
487 const auto sfl = fe_space_->ShapeFunctionLayout(edge);
494 "Mismatch " << determinants.size() <<
" <-> " << qr.
NumPoints());
497 ElemMat mat(sfl->NumRefShapeFunctions(), sfl->NumRefShapeFunctions());
500 auto gammaval = gamma_(edge, qr.
Points());
503 const auto rsf = sfl->EvalReferenceShapeFunctions(qr.
Points());
505 for (
long k = 0; k < determinants.size(); ++k) {
508 const auto w = (qr.
Weights()[k] * determinants[k]) * gammaval[k];
509 mat += ((rsf.col(k)) * (rsf.col(k).adjoint())) * w;
539template <
typename SCALAR,
typename MESH_FUNCTION>
541 static_assert(mesh::utils::isMeshFunction<MESH_FUNCTION>);
546 using ElemVec = Eigen::Matrix<scalar_t, Eigen::Dynamic, 1>;
569 std::shared_ptr<const
ScalarFESpace<SCALAR>> fe_space, MESH_FUNCTION f);
571 bool isActive(const
lf::mesh::Entity & )
const {
return true; }
595extern std::shared_ptr<spdlog::logger>
599template <
class PTR,
class MESH_FUNCTION>
605template <
typename SCALAR,
typename MESH_FUNCTION>
609 : f_(std::move(f)), fe_space_(std::move(fe_space)) {}
614template <
typename SCALAR,
typename MESH_FUNCTION>
622 const auto sfl = fe_space_->ShapeFunctionLayout(cell);
629 LF_ASSERT_MSG(geo_ptr !=
nullptr,
"Invalid geometry!");
630 LF_ASSERT_MSG((geo_ptr->
DimLocal() == 2),
631 "Only 2D implementation available!");
633 "{}, shape = \n{}", cell.
RefEl(),
640 "Mismatch " << determinants.size() <<
" <-> " << qr.
NumPoints());
642 "LOCVEC({}): Metric factors :\n{}", cell.
RefEl(),
643 determinants.transpose());
645 ElemVec vec(sfl->NumRefShapeFunctions());
648 auto fval = f_(cell, qr.
Points());
651 const auto rsf = sfl->EvalReferenceShapeFunctions(qr.
Points());
654 for (
long k = 0; k < determinants.size(); ++k) {
656 "LOCVEC: [{}] -> [weight = {}]",
660 (qr.
Weights()[k] * determinants[k] * fval[k]) * rsf.col(k).conjugate();
664 "LOCVEC = \n{}", vec.transpose());
700template <
class SCALAR,
class FUNCTOR,
class EDGE
SELECTOR = base::PredicateTrue>
703 static_assert(mesh::utils::isMeshFunction<FUNCTOR>,
704 "FUNCTOR does not fulfill the concept of a mesh function.");
707 using ElemVec = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
731 std::shared_ptr<const
ScalarFESpace<SCALAR>> fe_space, FUNCTOR g,
732 EDGESELECTOR edge_sel = base::PredicateTrue{})
762template <
class PTR,
class FUNCTOR,
class EDGE
SELECTOR = base::PredicateTrue>
771template <
class SCALAR,
class FUNCTOR,
class EDGE
SELECTOR>
777 LF_ASSERT_MSG(geo_ptr !=
nullptr,
"Invalid geometry!");
778 LF_ASSERT_MSG(geo_ptr->
DimLocal() == 1,
"The passed entity is not an edge!");
781 const auto sfl = fe_space_->ShapeFunctionLayout(edge);
790 "Mismatch " << determinants.size() <<
" <-> " << qr.
NumPoints());
793 ElemVec vec(sfl->NumRefShapeFunctions());
796 auto g_vals = g_(edge, qr.
Points());
799 const auto rsf = sfl->EvalReferenceShapeFunctions(qr.
Points());
804 const auto w = (qr.
Weights()[k] * determinants[k]) * g_vals[k];
805 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
main 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_
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
decltype(SCALAR(0) *mesh::utils::MeshFunctionReturnType< COEFF >(0)) scalar_t
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_
typename decltype(mesh::utils::MeshFunctionReturnType< REACTION_COEFF >() *Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 >())::Scalar Scalar
type of returned element matrix
std::shared_ptr< const ScalarFESpace< SCALAR > > fe_space_
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 hybrid 2D 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
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > ElemVec
decltype(SCALAR(0) *mesh::utils::MeshFunctionReturnType< FUNCTOR >(0)) Scalar
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(SCALAR(0) *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)
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 > mass_element_matrix_provider_logger
logger for MassElementMatrixProvider
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 >
lf::assemble::dim_t dim_t
std::shared_ptr< spdlog::logger > diffusion_element_matrix_provider_logger
logger for DiffusionElementMatrixProvider
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 >
std::shared_ptr< spdlog::logger > mass_edge_matrix_provider_logger
logger for MassEdgeMatrixProvider
DiffusionElementMatrixProvider(PTR fe_space, DIFF_COEFF alpha) -> DiffusionElementMatrixProvider< typename PTR::element_type::Scalar, DIFF_COEFF >
std::shared_ptr< spdlog::logger > scalar_load_edge_vector_provider_logger
logger for ScalarLoadEdgeVectorProvider class template.
std::shared_ptr< spdlog::logger > scalar_load_element_vector_provider_logger
logger used by ScalarLoadElementVectorProvider
internal::VectorElement_t< internal::MeshFunctionReturnType_t< R > > MeshFunctionReturnType
Determine the type of objects returned by a MeshFunction.