Feel++ 0.111.0-preview.14
Finite Element Embedded Library in C++
/data/cemosis/github-actions-runner/actions-runner-feelpp-1/_work/feelpp/feelpp/feelpp/feel/feeldiscr/concepts.hpp

A Feel++ function space.

A Feel++ function space Function spaces are the fundamental discretization concept in Feel++. They define the approximation space for finite element methods.

Requirements:

template <FunctionSpace SpaceT>
auto project(VfExpr auto&& expr, std::shared_ptr<SpaceT> space) {
auto u = space->element();
// project expr onto u
return u;
}
FunctionSpaceType::element_type project(std::shared_ptr< FunctionSpaceType > const &__functionspace, IteratorRange const &range_it, Expr< ExprT > const &__expr, GeomapStrategyType geomap=GeomapStrategyType::GEOMAP_HO)
nodal projection of __expr onto the subspace of __functionspace described by the range range_it
Definition: projectors.hpp:217
/* -*- mode: c++; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; show-trailing-whitespace: t -*- vim:fenc=utf-8:ft=cpp:et:sw=4:ts=4:sts=4
This file is part of the Feel library
Author(s): Christophe Prud'homme <christophe.prudhomme@feelpp.org>
Date: 2026-01-02
Copyright (C) 2026 Feel++ Consortium
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FEELPP_FEELDISCR_CONCEPTS_HPP
#define FEELPP_FEELDISCR_CONCEPTS_HPP 1
#include <concepts>
#include <memory>
namespace Feel
{
//
// Function Space Concepts
//
template <typename T>
concept FunctionSpace = requires(T t) {
typename T::value_type;
typename T::mesh_type;
typename T::element_type;
{ t.element() } -> std::same_as<typename T::element_type>;
};
template <typename T>
concept FunctionSpacePtr = requires {
requires (std::is_pointer_v<T> && FunctionSpace<std::remove_pointer_t<T>>)
|| (SharedPtr<T> && FunctionSpace<typename T::element_type>);
};
template <typename T>
concept FunctionSpaceElement = requires(T t) {
typename T::value_type;
requires FunctionSpace<typename T::functionspace_type>;
};
template <typename T>
concept ProductSpace = requires(T t) {
typename T::spaces_tuple_type;
{ t.numberOfSpaces() } -> std::convertible_to<int>;
};
template <typename T>
concept ProductSpaces = ProductSpace<T> && requires {
typename T::spaces_array_type;
};
//
// Mesh Concepts
//
template <typename T>
concept Mesh = requires(T t) {
typename T::shape_type;
typename T::element_type;
typename T::face_type;
{ t.numElements() } -> std::convertible_to<size_t>;
};
template <typename T>
concept MeshPtr = requires {
requires (std::is_pointer_v<T> && Mesh<std::remove_pointer_t<T>>)
|| (SharedPtr<T> && Mesh<typename T::element_type>);
};
//
// DOF Concepts
//
template <typename T>
concept DofType = requires(T t) {
{ t.index() } -> std::convertible_to<size_t>;
{ t.sign() } -> std::convertible_to<int>;
};
template <typename T>
concept DofTable = requires(T t) {
typename T::dof_type;
requires DofType<typename T::dof_type>;
};
//
// Geometric Mapping Concepts
//
template <typename T>
concept GeometricMapping = requires {
typename T::gm_type;
{ T::nDim } -> std::convertible_to<int>;
{ T::nRealDim } -> std::convertible_to<int>;
};
template <typename T>
concept GeometricMappingContext = requires(T t) {
typename T::gm_type;
requires GeometricMapping<typename T::gm_type>;
};
//
// Basis Function Concepts
//
template <typename T>
concept Basis = requires {
typename T::value_type;
{ T::nDof } -> std::convertible_to<int>;
{ T::nLocalDof } -> std::convertible_to<int>;
};
template <typename T>
concept BasisContext = requires(T t) {
typename T::basis_type;
requires Basis<typename T::basis_type>;
};
//
// Interpolation Concepts
//
template <typename T, typename SpaceT>
concept Interpolable = requires(T t, SpaceT space) {
requires FunctionSpace<SpaceT>;
// Can be evaluated to produce values
};
//
// Operator Concepts
//
template <typename T>
concept LinearOperator = requires(T t) {
typename T::domain_space_type;
typename T::dual_image_space_type;
requires FunctionSpace<typename T::domain_space_type>;
requires FunctionSpace<typename T::dual_image_space_type>;
};
template <typename T>
concept Preconditioner = requires(T t) {
typename T::operator_type;
{ t.setOperator(std::declval<typename T::operator_type>()) };
};
//
// Mesh Entity Type Concepts
//
template <typename T, typename M>
concept MeshEntityElement = requires {
typename std::decay_t<M>::element_type;
requires std::is_same_v<std::decay_t<T>, typename std::decay_t<M>::element_type>;
};
template <typename T, typename M>
concept MeshEntityFace = requires {
typename std::decay_t<M>::face_type;
requires std::is_same_v<std::decay_t<T>, typename std::decay_t<M>::face_type>;
};
template <typename T, typename M>
concept MeshEntityEdge = requires {
typename std::decay_t<M>::edge_type;
requires std::is_same_v<std::decay_t<T>, typename std::decay_t<M>::edge_type>;
};
template <typename T, typename M>
concept MeshEntityPoint = requires {
typename std::decay_t<M>::point_type;
requires std::is_same_v<std::decay_t<T>, typename std::decay_t<M>::point_type>;
};
//
// Dimension Concepts
//
template <typename T, int D>
concept ShapeWithDim = requires {
{ T::nDim } -> std::convertible_to<int>;
requires (T::nDim == D);
};
template <typename T>
concept Shape0D = ShapeWithDim<T, 0>;
template <typename T>
concept Shape1D = ShapeWithDim<T, 1>;
template <typename T>
concept Shape2D = ShapeWithDim<T, 2>;
template <typename T>
concept Shape3D = ShapeWithDim<T, 3>;
//
// Function Space Property Concepts
//
template <typename T>
concept CompositeSpace = FunctionSpace<T> && requires {
{ T::is_composite } -> std::convertible_to<bool>;
requires (T::is_composite == true);
};
template <typename T>
concept NonCompositeSpace = FunctionSpace<T> && requires {
{ T::is_composite } -> std::convertible_to<bool>;
requires (T::is_composite == false);
};
template <typename T>
concept ModalBasisSpace = requires {
{ T::is_modal } -> std::convertible_to<bool>;
requires (T::is_modal == true);
};
template <typename T>
concept NodalBasisSpace = requires {
{ T::is_modal } -> std::convertible_to<bool>;
requires (T::is_modal == false);
};
//
// Field Type Concepts
//
// Forward declarations for base types (defined in feelpoly/traits.hpp)
struct ScalarBase;
struct VectorialBase;
struct Tensor2Base;
struct Tensor2SymmBase;
template <typename T>
concept ScalarField = std::is_base_of_v<ScalarBase, std::decay_t<T>>;
template <typename T>
concept VectorialField = std::is_base_of_v<VectorialBase, std::decay_t<T>>;
template <typename T>
concept Tensor2Field = std::is_base_of_v<Tensor2Base, std::decay_t<T>>;
template <typename T>
concept Tensor2SymmField = std::is_base_of_v<Tensor2SymmBase, std::decay_t<T>>;
template <typename T>
concept MatrixField = Tensor2Field<T> || Tensor2SymmField<T>;
//
// Range Entity Concepts
//
template <typename T>
concept RangeOnElements = requires {
{ T::isOnElements() } -> std::convertible_to<bool>;
requires T::isOnElements();
};
template <typename T>
concept RangeOnFaces = requires {
{ T::isOnFaces() } -> std::convertible_to<bool>;
requires T::isOnFaces();
};
template <typename T>
concept RangeOnEdges = requires {
{ T::isOnEdges() } -> std::convertible_to<bool>;
requires T::isOnEdges();
};
template <typename T>
concept RangeOnPoints = requires {
{ T::isOnPoints() } -> std::convertible_to<bool>;
requires T::isOnPoints();
};
//
// Interpolation Entity Concepts
//
// Forward declaration for ElementsType enum
enum class ElementsType;
template <typename T>
concept InterpolationOnElements = requires {
{ T::onEntity() };
// Note: Compile-time check depends on ElementsType enum definition
};
template <typename T>
concept InterpolationOnFaces = requires {
{ T::onEntity() };
};
template <typename T>
concept InterpolationOnEdges = requires {
{ T::onEntity() };
};
//
// Conformity Concepts
//
template <typename T>
concept HdivConforming = requires {
{ T::is_hdiv_conforming } -> std::convertible_to<bool>;
requires (T::is_hdiv_conforming == true);
};
template <typename T>
concept HcurlConforming = requires {
{ T::is_hcurl_conforming } -> std::convertible_to<bool>;
requires (T::is_hcurl_conforming == true);
};
template <typename T>
concept H1Conforming = requires {
{ T::is_continuous } -> std::convertible_to<bool>;
requires (T::is_continuous == true);
};
//
// Expression Concepts
//
// Forward declaration for ExprBase (defined in feelvf)
struct ExprBase;
template <typename T>
concept VfExpr = std::is_base_of_v<ExprBase, std::decay_t<T>>;
//
// Backward Compatibility Bridges
//
#ifdef FEELPP_ENABLE_CONCEPT_COMPATIBILITY
// Bridge old is_functionspace trait to new concept
template <typename T>
constexpr bool is_functionspace_v = FunctionSpace<T>;
template <typename T>
constexpr bool is_functionspace_element_v = FunctionSpaceElement<T>;
template <typename T>
constexpr bool is_product_space_v = ProductSpace<T>;
// Field type concept bridges
template <typename T>
constexpr bool is_scalar_field_concept_v = ScalarField<T>;
template <typename T>
constexpr bool is_vector_field_concept_v = VectorialField<T>;
template <typename T>
constexpr bool is_tensor2_field_concept_v = Tensor2Field<T>;
template <typename T>
constexpr bool is_matrix_field_concept_v = MatrixField<T>;
// Mesh entity concept bridges
template <typename T, typename M>
constexpr bool is_mesh_element_type_v = MeshEntityElement<T, M>;
template <typename T, typename M>
constexpr bool is_mesh_face_type_v = MeshEntityFace<T, M>;
template <typename T, typename M>
constexpr bool is_mesh_edge_type_v = MeshEntityEdge<T, M>;
// Dimension concept bridges
template <typename T>
constexpr bool is_shape_0d_v = Shape0D<T>;
template <typename T>
constexpr bool is_shape_1d_v = Shape1D<T>;
template <typename T>
constexpr bool is_shape_2d_v = Shape2D<T>;
template <typename T>
constexpr bool is_shape_3d_v = Shape3D<T>;
// Function space property bridges
template <typename T>
constexpr bool is_composite_space_v = CompositeSpace<T>;
template <typename T>
constexpr bool is_modal_basis_v = ModalBasisSpace<T>;
template <typename T>
constexpr bool is_nodal_basis_v = NodalBasisSpace<T>;
// Conformity concept bridges
template <typename T>
constexpr bool is_hdiv_conforming_concept_v = HdivConforming<T>;
template <typename T>
constexpr bool is_hcurl_conforming_concept_v = HcurlConforming<T>;
template <typename T>
constexpr bool is_h1_conforming_concept_v = H1Conforming<T>;
// VfExpr concept bridge
template <typename T>
constexpr bool is_vf_expr_concept_v = VfExpr<T>;
#endif // FEELPP_ENABLE_CONCEPT_COMPATIBILITY
} // namespace Feel
#endif /* FEELPP_FEELDISCR_CONCEPTS_HPP */
Definition: test_factory.cpp:67
A shared_ptr to any type.
Definition: concepts.hpp:202
C++20 concepts for Feel++ core types.
constexpr bool is_functionspace_v
helper variable template for is_functionspace
Definition: traits.hpp:147
constexpr bool is_functionspace_element_v
helper variable template for is_functionspace_element
Definition: traits.hpp:171
typename mpl::if_< is_functionspace< decay_type< FESpace > >, mpl::identity< decay_type< FESpace > >, mpl::identity< void > >::type::type functionspace_type
provides the function space type if FESpace is a shared_ptr of a function space then provides the fun...
Definition: traits.hpp:157
-*- mode: c++; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; show-trailing-w...
Definition: about.cpp:37
ElementsType
entity identifier for mesh iterators
Definition: enums.hpp:40