From e00cd0e8497054d39e06c3f13ed3b0d892c973e6 Mon Sep 17 00:00:00 2001 From: Santiago Ospina De Los Rios Date: Tue, 19 May 2020 02:53:37 +0200 Subject: [PATCH 1/7] Add grid C++20 concepts * Add Intersection C++20 concept * Add Intersection iterator C++20 concept * Add IndexSet C++20 concept * Add IdSet C++20 concept * Add GridView C++20 concept * Add Grid C++20 concept * Add recursive Grid concept for different codim concepts in fallback implementation * Add documentation for concepts & clean-up * Use C++20 concepts only --- doc/doxygen/Doxylocal | 1 + dune/grid/CMakeLists.txt | 1 + dune/grid/concepts/CMakeLists.txt | 11 ++ dune/grid/concepts/entity.hh | 106 ++++++++++++++++++ dune/grid/concepts/entityiterator.hh | 23 ++++ dune/grid/concepts/entityset.hh | 67 ++++++++++++ dune/grid/concepts/geometry.hh | 40 +++++++ dune/grid/concepts/grid.hh | 112 ++++++++++++++++++++ dune/grid/concepts/gridview.hh | 59 +++++++++++ dune/grid/concepts/indexset.hh | 90 ++++++++++++++++ dune/grid/concepts/intersection.hh | 50 +++++++++ dune/grid/concepts/intersectioniterator.hh | 23 ++++ dune/grid/test/checkentitylifetime.hh | 19 +++- dune/grid/test/checkintersectionlifetime.hh | 24 +++++ dune/grid/test/test-concepts.cc | 72 +++++++++++++ 15 files changed, 697 insertions(+), 1 deletion(-) create mode 100644 dune/grid/concepts/CMakeLists.txt create mode 100644 dune/grid/concepts/entity.hh create mode 100644 dune/grid/concepts/entityiterator.hh create mode 100644 dune/grid/concepts/entityset.hh create mode 100644 dune/grid/concepts/geometry.hh create mode 100644 dune/grid/concepts/grid.hh create mode 100644 dune/grid/concepts/gridview.hh create mode 100644 dune/grid/concepts/indexset.hh create mode 100644 dune/grid/concepts/intersection.hh create mode 100644 dune/grid/concepts/intersectioniterator.hh create mode 100644 dune/grid/test/test-concepts.cc diff --git a/doc/doxygen/Doxylocal b/doc/doxygen/Doxylocal index 09b12c773..1f38c1a31 100644 --- a/doc/doxygen/Doxylocal +++ b/doc/doxygen/Doxylocal @@ -9,6 +9,7 @@ INPUT += @srcdir@/mainpage.txt \ @top_srcdir@/dune/grid/albertagrid \ @top_srcdir@/dune/grid/albertagrid.hh \ @top_srcdir@/dune/grid/common \ + @top_srcdir@/dune/grid/concepts \ @top_srcdir@/dune/grid/geometrygrid.hh \ @top_srcdir@/dune/grid/geometrygrid \ @top_srcdir@/dune/grid/identitygrid.hh \ diff --git a/dune/grid/CMakeLists.txt b/dune/grid/CMakeLists.txt index 0a7ecfb86..793a567a5 100644 --- a/dune/grid/CMakeLists.txt +++ b/dune/grid/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(albertagrid) add_subdirectory(common) +add_subdirectory(concepts) add_subdirectory(geometrygrid) add_subdirectory(identitygrid) add_subdirectory(io) diff --git a/dune/grid/concepts/CMakeLists.txt b/dune/grid/concepts/CMakeLists.txt new file mode 100644 index 000000000..f35e471f3 --- /dev/null +++ b/dune/grid/concepts/CMakeLists.txt @@ -0,0 +1,11 @@ +install(FILES + entity.hh + entityiterator.hh + entityset.hh + geometry.hh + grid.hh + gridview.hh + indexset.hh + intersection.hh + intersectioniterator.hh + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/grid/concepts) diff --git a/dune/grid/concepts/entity.hh b/dune/grid/concepts/entity.hh new file mode 100644 index 000000000..66a478018 --- /dev/null +++ b/dune/grid/concepts/entity.hh @@ -0,0 +1,106 @@ +#ifndef DUNE_GRID_CONCEPT_ENTITY_HH +#define DUNE_GRID_CONCEPT_ENTITY_HH + + +#include + +#include + +#include + +namespace Dune::Concept { + +/** + * @brief Model of an entity seed + * @ingroup GridConcepts + * @details Dune::EntitySeed is a template for this model + */ +template +concept EntitySeed = requires(S seed) +{ + requires std::default_initializable; + { S::codimension } -> std::convertible_to; + { seed.isValid() } -> std::convertible_to; +}; + +/** + * @brief Model of a grid entity for any codimension + * @ingroup GridConcepts + * @details Dune::Entity is a template for this model. + */ +template +concept EntityGeneral = requires(E e, unsigned int codim) +{ + requires Geometry; + requires EntitySeed; + requires E::mydimension == (E::dimension - E::codimension); + { e.level() } -> std::convertible_to; + { e.partitionType() } -> std::convertible_to; + { e.geometry() } -> std::convertible_to; + { e.type() } -> std::convertible_to; + { e.subEntities(codim) } -> std::convertible_to; + { e.seed() } -> std::convertible_to; + { e==e } -> std::convertible_to; + { e!=e } -> std::convertible_to; + requires std::default_initializable; + requires std::copyable; +}; + + +namespace Impl +{ + template + concept EntityCodimExtended = requires(E e, int subEntity) + { + { e.template subEntity(subEntity) } -> EntityGeneral; + }; + + template + concept AllEntityCodimsExtended = requires(std::make_index_sequence codims) + { + [](std::index_sequence) + requires (Impl::EntityCodimExtended &&...) {} (codims); + }; +} + +/** + * @brief Model of a grid entity with extended requirements for codimension 0 + * @ingroup GridConcepts + * @details Dune::Entity of codimension 0 is a template for this model. + */ +template +concept EntityExtended = requires(E e) +{ + requires (E::codimension == 0); + requires EntityGeneral; + requires Geometry; + { e.father() } -> std::convertible_to; + { e.hasFather() } -> std::convertible_to; + { e.isLeaf() } -> std::convertible_to; + { e.isRegular() } -> std::convertible_to; + { e.geometryInFather() } -> std::convertible_to; + { e.hbegin(/*maxLevel*/ int{}) } -> std::convertible_to; + { e.hend(/*maxLevel*/ int{}) } -> std::convertible_to; + { e.isNew() } -> std::convertible_to; + { e.mightVanish() } -> std::convertible_to; + { e.hasBoundaryIntersections() } -> std::convertible_to; + requires Impl::AllEntityCodimsExtended; + requires std::same_as::Entity>; +}; + +/** + * @brief Model of a grid entity + * @ingroup GridConcepts + * @details Codimension 0 entities are required to have an extended interface. + * Dune::Entity is a template for this model. + */ +template +concept Entity = requires { + requires EntityGeneral; + requires (E::codimension != 0) || EntityExtended; +}; + +} // end namespace Dune::Concept + + +#endif // DUNE_GRID_CONCEPT_ENTITY_HH diff --git a/dune/grid/concepts/entityiterator.hh b/dune/grid/concepts/entityiterator.hh new file mode 100644 index 000000000..1ecf1886e --- /dev/null +++ b/dune/grid/concepts/entityiterator.hh @@ -0,0 +1,23 @@ +#ifndef DUNE_GRID_CONCEPTS_ENTITY_ITERATOR_HH +#define DUNE_GRID_CONCEPTS_ENTITY_ITERATOR_HH + +#include + +namespace Dune::Concept { + +/** + * @brief Model of an entity iterator + * @ingroup GridConcepts + * @details Dune::EntityIterator is a template for this model + */ +template +concept EntityIterator = requires(It it) +{ + requires Entity; + requires std::forward_iterator; + requires std::default_initializable; +}; + +} // end namespace Dune::Concept + +#endif // DUNE_GRID_CONCEPTS_ENTITY_ITERATOR_HH diff --git a/dune/grid/concepts/entityset.hh b/dune/grid/concepts/entityset.hh new file mode 100644 index 000000000..e0b14fb6d --- /dev/null +++ b/dune/grid/concepts/entityset.hh @@ -0,0 +1,67 @@ +#ifndef DUNE_GRID_CONCEPTS_ENTITY_SET_HH +#define DUNE_GRID_CONCEPTS_ENTITY_SET_HH + +#include +#include +#include +#include +#include +#include + +#include + +namespace Dune::Concept { + +namespace Impl { + + template + concept EntitySetEssentials = requires(ES es, Dune::GeometryType type, int codim) + { + typename ES::Traits; + typename ES::ctype; + requires IndexSet; + requires Intersection; + requires IntersectionIterator; + { ES::conforming } -> std::convertible_to< bool >; + { ES::dimension } -> std::convertible_to< int >; + { ES::dimensionworld } -> std::convertible_to< int >; + { es.grid() } -> std::convertible_to< const typename ES::Grid& >; + { es.indexSet() } -> std::convertible_to< const typename ES::IndexSet& >; + { es.size(codim) } -> std::convertible_to< int >; + { es.size(type) } -> std::convertible_to< int >; + { es.comm() } -> std::convertible_to< typename ES::CollectiveCommunication >; + { es.overlapSize(codim) } -> std::convertible_to< int >; + { es.ghostSize(codim) } -> std::convertible_to< int >; + //! gv.communicate(std::declval(),std::declval(), std::declval()), // FIXME use a default handler to instantiate this function + requires std::copy_constructible; + }; + +} + +/** + * @brief Model of an entity set + * @ingroup GridConcepts + * @details An entity set is an iterable set of entities whose index set can + * contiguously index all the iterated entities. A Dune::GridView is a + * template for this model, but not necessarily the only one. In particular, + * entity sets are used to enumerate sub-ranges of entities contained in the + * grid view. + */ +template +concept EntitySet = requires(ES es, Dune::GeometryType type, const typename ES::template Codim::Entity& entity) +{ + requires Impl::EntitySetEssentials; + requires (codim != 0) || requires { + { es.ibegin(entity) } -> std::convertible_to< typename ES::IntersectionIterator>; + { es.iend(entity) } -> std::convertible_to< typename ES::IntersectionIterator>; + }; + requires Geometry::Geometry>; + requires Geometry::LocalGeometry>; + requires EntityIterator::Iterator>; + { es.template begin() } -> std::convertible_to< typename ES::template Codim::Iterator>; + { es.template end() } -> std::convertible_to< typename ES::template Codim::Iterator>; +}; + +} // end namespace Dune::Concept + +#endif // DUNE_GRID_CONCEPTS_ENTITY_SET_HH diff --git a/dune/grid/concepts/geometry.hh b/dune/grid/concepts/geometry.hh new file mode 100644 index 000000000..c81a86f20 --- /dev/null +++ b/dune/grid/concepts/geometry.hh @@ -0,0 +1,40 @@ +#ifndef DUNE_GRID_CONCEPTS_GEOMETRY_HH +#define DUNE_GRID_CONCEPTS_GEOMETRY_HH + +#include + +namespace Dune::Concept { + +template +concept ReferenceElement = true; + +/** + * @brief Model of a geometry object + * @ingroup GridConcepts + * @details Dune::Geometry is a template for this model + */ +template +concept Geometry = requires(const G& g, typename G::GlobalCoordinate global, typename G::LocalCoordinate local) +{ + typename G::ctype; + { G::mydimension } -> std::convertible_to; + { G::coorddimension } -> std::convertible_to; + { g.type() } -> std::convertible_to; + { g.affine() } -> std::convertible_to; + { g.corners() } -> std::convertible_to; + { g.corner(/*i*/ int{}) } -> std::convertible_to; + { g.global(local) } -> std::convertible_to; + { g.local(global) } -> std::convertible_to; + { g.integrationElement(local) } -> std::convertible_to; + { g.volume() } -> std::convertible_to; + { g.center() } -> std::convertible_to; + { g.jacobian(local) } -> std::convertible_to; + { g.jacobianInverse(local) } -> std::convertible_to; + { g.jacobianTransposed(local) } -> std::convertible_to; + { g.jacobianInverseTransposed(local) } -> std::convertible_to; + { referenceElement(g) } -> ReferenceElement; +}; + +} // end namespace Dune::Concept + +#endif // DUNE_GRID_CONCEPTS_GEOMETRY_HH diff --git a/dune/grid/concepts/grid.hh b/dune/grid/concepts/grid.hh new file mode 100644 index 000000000..d6090d78a --- /dev/null +++ b/dune/grid/concepts/grid.hh @@ -0,0 +1,112 @@ +#ifndef DUNE_GRID_CONCEPTS_GRID_HH +#define DUNE_GRID_CONCEPTS_GRID_HH + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +/*!@defgroup GridConcepts Grid Concepts + * @{ + * @par Description + * This group gathers several concepts related to grids. + * @} + */ + +namespace Dune::Concept { + namespace Impl { + + template + concept GridCodim = requires(G g, const typename G::template Codim::EntitySeed& seed) + { + requires Entity< typename G::template Codim::Entity>; + requires EntitySeed< typename G::template Codim::EntitySeed>; + requires Geometry< typename G::template Codim::Geometry>; + requires Geometry< typename G::template Codim::LocalGeometry>; + requires EntityIterator< typename G::template Codim::template Partition::LevelIterator>; + requires EntityIterator< typename G::template Codim::template Partition::LeafIterator>; + requires EntityIterator< typename G::template Codim::template Partition::LevelIterator>; + requires EntityIterator< typename G::template Codim::template Partition::LeafIterator>; + requires EntityIterator< typename G::template Codim::template Partition::LevelIterator>; + requires EntityIterator< typename G::template Codim::template Partition::LeafIterator>; + requires EntityIterator< typename G::template Codim::template Partition::LevelIterator>; + requires EntityIterator< typename G::template Codim::template Partition::LeafIterator>; + requires EntityIterator< typename G::template Codim::template Partition::LevelIterator>; + requires EntityIterator< typename G::template Codim::template Partition::LeafIterator>; + requires EntityIterator< typename G::template Codim::template Partition::LevelIterator>; + requires EntityIterator< typename G::template Codim::template Partition::LeafIterator>; + requires EntityIterator< typename G::template Codim::LevelIterator>; + requires EntityIterator< typename G::template Codim::LeafIterator>; + { g.entity(seed) } -> std::convertible_to::Entity >; + }; + + + template + concept AllGridCodims = requires(std::make_index_sequence codims) + { + [](std::index_sequence) + requires (GridCodim &&...) {} (codims); + }; +} + +/** + * @brief Model of a grid + * @ingroup GridConcepts + * @details Dune::Grid is a template for this model + */ +template +concept Grid = requires(G g, int level, int codim, int refCount, Dune::GeometryType type, const typename G::template Codim<0>::Entity& entity) +{ + { G::dimension } -> std::convertible_to; + { G::dimensionworld } -> std::convertible_to; + requires GridView< typename G::LeafGridView>; + requires GridView< typename G::LevelGridView>; + requires Intersection< typename G::LeafIntersection>; + requires Intersection< typename G::LevelIntersection>; + requires IntersectionIterator< typename G::LeafIntersectionIterator>; + requires IntersectionIterator< typename G::LevelIntersectionIterator>; + requires IndexSet< typename G::LevelIndexSet>; + requires IndexSet< typename G::LeafIndexSet>; + requires IdSet< typename G::GlobalIdSet>; + requires IdSet< typename G::LocalIdSet>; + requires std::is_same::value; + requires std::is_same::value; + requires Impl::AllGridCodims; + typename G::ctype; + typename G::HierarchicIterator; + { g.maxLevel() } -> std::convertible_to< int >; + { g.size(level, codim) } -> std::convertible_to< int >; + { g.size(codim) } -> std::convertible_to< int >; + { g.size(level, type) } -> std::convertible_to< int >; + { g.size(type) } -> std::convertible_to< int >; + { g.numBoundarySegments() } -> std::convertible_to< std::size_t >; + { g.levelGridView(level) } -> std::convertible_to< typename G::LevelGridView >; + { g.leafGridView() } -> std::convertible_to< typename G::LeafGridView >; + { g.globalIdSet() } -> std::convertible_to< const typename G::GlobalIdSet& >; + { g.localIdSet() } -> std::convertible_to< const typename G::LocalIdSet& >; + { g.levelIndexSet(level) } -> std::convertible_to< const typename G::LevelIndexSet& >; + { g.leafIndexSet() } -> std::convertible_to< const typename G::LeafIndexSet& >; + { g.mark(refCount,entity) } -> std::convertible_to< bool >; + { g.getMark(entity) } -> std::convertible_to< int >; + { g.preAdapt() } -> std::convertible_to< bool >; + { g.adapt() } -> std::convertible_to< bool >; + { g.comm() } -> std::convertible_to< typename G::CollectiveCommunication >; + { g.loadBalance() } -> std::convertible_to< bool >; + //! requireConvertible(g.loadBalance(/*data*/ std::declval())) // FIXME use a default handler to instantiate this function + g.globalRefine(refCount); + g.postAdapt(); +}; + +} // end namespace Dune::Concept + +#endif // DUNE_GRID_CONCEPTS_GRID_HH diff --git a/dune/grid/concepts/gridview.hh b/dune/grid/concepts/gridview.hh new file mode 100644 index 000000000..4b6ace6c1 --- /dev/null +++ b/dune/grid/concepts/gridview.hh @@ -0,0 +1,59 @@ +#ifndef DUNE_GRID_CONCEPTS_GRIDVIEW_HH +#define DUNE_GRID_CONCEPTS_GRIDVIEW_HH + +#include + +#include + +#include + +namespace Dune::Concept { + +namespace Impl { + + template + concept EntityPartitionSpan = requires(ES es) { + requires EntityIterator::template Partition::Iterator>; + { es.template begin() } -> std::convertible_to< typename ES::template Codim::template Partition::Iterator>; + { es.template end() } -> std::convertible_to< typename ES::template Codim::template Partition::Iterator>; + }; + + + template + concept EntitySetAllPartitions = requires(ES es) { + requires EntitySet; + requires EntityPartitionSpan; + requires EntityPartitionSpan; + requires EntityPartitionSpan; + requires EntityPartitionSpan; + requires EntityPartitionSpan; + }; + + template + requires Dune::Capabilities::hasEntityIterator::v + void requireEntitySetAllPartitions() + requires EntitySetAllPartitions {} + + template + requires (not Dune::Capabilities::hasEntityIterator::v) + void requireEntitySetAllPartitions() {} + +} + +/** + * @brief Model of a grid view + * @ingroup GridConcepts + * @details Dune::GridView is a template for this model + */ +template +concept GridView = requires(std::make_integer_sequence dims) +{ + requires EntitySet; + + [](std::integer_sequence) requires + requires { (Impl::requireEntitySetAllPartitions(),...); }{} (dims); +}; + +} // end namespace Dune::Concept + +#endif // DUNE_GRID_CONCEPTS_GRIDVIEW_HH diff --git a/dune/grid/concepts/indexset.hh b/dune/grid/concepts/indexset.hh new file mode 100644 index 000000000..7c4fdd5be --- /dev/null +++ b/dune/grid/concepts/indexset.hh @@ -0,0 +1,90 @@ +#ifndef DUNE_GRID_CONCEPTS_INDEX_SET_HH +#define DUNE_GRID_CONCEPTS_INDEX_SET_HH + +#include + +#include + +#include + +#include + +namespace Dune::Concept { + +namespace Impl { + + template + concept IndexSetEntityCodim = requires(IS is, int i, unsigned int sub_codim, const typename IS::template Codim::Entity& entity) + { + requires Entity::Entity>; + { is.template index(entity) } -> std::convertible_to; + { is.index(entity) } -> std::convertible_to; + { is.template subIndex(entity, i, sub_codim ) } -> std::convertible_to; + { is.subIndex(entity, i, sub_codim ) } -> std::convertible_to; + { is.contains(entity) } -> std::convertible_to; + }; + + template + concept AllIndexSetEntityCodims = requires(std::make_index_sequence codims) + { + [](std::index_sequence) + requires (IndexSetEntityCodim &&...) {} (codims); + }; + +} + +/** + * @brief Model of an index set + * @ingroup GridConcepts + * @details Dune::Grid::LevelIndexSet and Dune::Grid::LeafIndexSet are templates + * for this model + */ +template +concept IndexSet = requires(IS is, Dune::GeometryType type, int sub_codim) +{ + { IS::dimension } -> std::convertible_to< int >; + { is.types(sub_codim) } -> std::convertible_to< typename IS::Types >; + { is.size(type) } -> std::convertible_to< typename IS::IndexType >; + { is.size(sub_codim) } -> std::convertible_to< typename IS::IndexType >; + requires std::is_integral::value; + requires (not std::is_copy_constructible::value); + requires (not std::is_copy_assignable::value); + typename IS::Types; + requires Impl::AllIndexSetEntityCodims; +}; + +namespace Impl { + + template + concept IdSetEntityCodim = requires(IS is, const typename IS::template Codim::Entity& entity) + { + requires Entity::Entity>; + { is.template id(entity) } -> std::convertible_to; + { is.id(entity) } -> std::convertible_to; + }; + + template + concept AllIdSetEntityCodims = requires(std::make_index_sequence codims) + { + [](std::index_sequence) + requires (IdSetEntityCodim &&...) {} (codims); + }; + +} + +/** + * @brief Model of an id set + * @ingroup GridConcepts + * @details Dune::Grid::GlobalIdSet and Dune::Grid::LocalIdSet are templates + * for this model + */ +template +concept IdSet = requires(IS is, const typename IS::template Codim<0>::Entity& entity, int i, unsigned int codim) +{ + { is.subId(entity,i,codim) } -> std::convertible_to; + requires Impl::AllIdSetEntityCodims; +}; + +} // end namespace Dune::Concept + +#endif // DUNE_GRID_CONCEPTS_INDEX_SET_HH diff --git a/dune/grid/concepts/intersection.hh b/dune/grid/concepts/intersection.hh new file mode 100644 index 000000000..88af9bb1f --- /dev/null +++ b/dune/grid/concepts/intersection.hh @@ -0,0 +1,50 @@ +#ifndef DUNE_GRID_CONCEPTS_INTERSECTION_HH +#define DUNE_GRID_CONCEPTS_INTERSECTION_HH + +#include +#include + +namespace Dune::Concept { + +/** + * @brief Model of an intersection + * @ingroup GridConcepts + * @details Dune::Grid::Intersection is a template for this model + */ +template +concept Intersection = requires(I i, typename I::LocalCoordinate local) +{ + requires EntityGeneral; + requires Geometry; + requires Geometry; + typename I::ctype; + { I::mydimension } -> std::convertible_to; + { I::dimensionworld } -> std::convertible_to; + { i.boundary() } -> std::convertible_to; + { i.boundarySegmentIndex() } -> std::convertible_to; + { i.neighbor() } -> std::convertible_to; + { i.inside() } -> std::convertible_to; + { i.outside() } -> std::convertible_to; + { i.conforming() } -> std::convertible_to; + { i.geometryInInside() } -> std::convertible_to; + { i.geometryInOutside() } -> std::convertible_to; + { i.geometry() } -> std::convertible_to; + { i.type() } -> std::convertible_to; + { i.indexInInside() } -> std::convertible_to; + { i.indexInOutside() } -> std::convertible_to; + { i.outerNormal(local) } -> std::convertible_to; + { i.integrationOuterNormal(local) } -> std::convertible_to; + { i.unitOuterNormal(local) } -> std::convertible_to; + { i.centerUnitOuterNormal() } -> std::convertible_to; + { i==i } -> std::convertible_to; + { i!=i } -> std::convertible_to; + requires std::default_initializable; + requires std::copy_constructible; + requires std::move_constructible; + i = i; + i = std::move(i); +}; + +} // end namespace Dune::Concept + +#endif // DUNE_GRID_CONCEPTS_INTERSECTION_HH diff --git a/dune/grid/concepts/intersectioniterator.hh b/dune/grid/concepts/intersectioniterator.hh new file mode 100644 index 000000000..e04189c65 --- /dev/null +++ b/dune/grid/concepts/intersectioniterator.hh @@ -0,0 +1,23 @@ +#ifndef DUNE_GRID_CONCEPTS_INTERSECTION_ITERATOR_HH +#define DUNE_GRID_CONCEPTS_INTERSECTION_ITERATOR_HH + +#include + +namespace Dune::Concept { + +/** + * @brief Model of an intersection iterator + * @ingroup GridConcepts + * @details Dune::IntersectionIterator is a template for this model + */ +template +concept IntersectionIterator = requires(It it) +{ + requires Intersection; + requires std::forward_iterator; + requires std::default_initializable; +}; + +} // end namespace Dune::Concept + +#endif // DUNE_GRID_CONCEPTS_INTERSECTION_ITERATOR_HH diff --git a/dune/grid/test/checkentitylifetime.hh b/dune/grid/test/checkentitylifetime.hh index 8a9bc3fab..44ebdaf98 100644 --- a/dune/grid/test/checkentitylifetime.hh +++ b/dune/grid/test/checkentitylifetime.hh @@ -19,6 +19,10 @@ #include #include +#if __cpp_concepts > 202002L && __cpp_lib_concepts > 202002L +#include +#endif + #if not defined(DUNE_ENTITY_LIFETIME_CHECK_ELEMENT_COUNT) #define DUNE_ENTITY_LIFETIME_CHECK_ELEMENT_COUNT 32 #endif @@ -38,9 +42,10 @@ bool checkEntityLifetimeForCodim(GV gv, std::size_t check_element_count, Dune::C << " entities" << std::endl; check_element_count = gv.size(codim); } - + using Iterator = typename GV::template Codim::Iterator; auto& index_set = gv.indexSet(); auto& id_set = gv.grid().localIdSet(); + Iterator entity_iterator = gv.template begin(); std::vector indices; std::vector ids; @@ -52,6 +57,9 @@ bool checkEntityLifetimeForCodim(GV gv, std::size_t check_element_count, Dune::C std::size_t i = 0; for (const auto& e : entities(gv,Dune::Codim())) { +#if __cpp_concepts > 202002L && __cpp_lib_concepts > 202002L + static_assert(Dune::Concept::Entity>); +#endif if (++i > check_element_count) break; indices.push_back(index_set.index(e)); @@ -81,6 +89,15 @@ bool checkEntityLifetimeForCodim(GV gv, std::size_t check_element_count, Dune::C " (" << entity_list[i].geometry().corner(0) << " != " << coords[i] << ")"); } +#if __cpp_concepts > 202002L && __cpp_lib_concepts > 202002L + static_assert(Dune::Concept::GridView); + static_assert(Dune::Concept::IndexSet); + static_assert(Dune::Concept::IdSet); + static_assert(Dune::Concept::IdSet); + static_assert(Dune::Concept::EntityIterator); + static_assert(Dune::Concept::Grid); +#endif + return true; } diff --git a/dune/grid/test/checkintersectionlifetime.hh b/dune/grid/test/checkintersectionlifetime.hh index 741c9413e..8040a242b 100644 --- a/dune/grid/test/checkintersectionlifetime.hh +++ b/dune/grid/test/checkintersectionlifetime.hh @@ -17,6 +17,13 @@ #include +#if __cpp_concepts > 202002L && __cpp_lib_concepts > 202002L +#include +#include +#include +#include +#endif + template void checkIntersectionLifetime(GV gv, std::size_t check_element_count = 32) { @@ -40,6 +47,17 @@ void checkIntersectionLifetime(GV gv, std::size_t check_element_count = 32) std::vector > intersection_list; std::vector > coords; + auto entity_iterator = gv.template begin<0>(); + + auto intersection_iterator = gv.ibegin(*entity_iterator); + +#if __cpp_concepts > 202002L && __cpp_lib_concepts > 202002L + static_assert(Dune::Concept::EntityIterator); + static_assert(Dune::Concept::IntersectionIterator); + static_assert(Dune::Concept::Entity>); + static_assert(Dune::Concept::Intersection>); +#endif + // store indices + entities + intersections + coordinates { std::size_t i = 0; @@ -53,6 +71,12 @@ void checkIntersectionLifetime(GV gv, std::size_t check_element_count = 32) coords.push_back({}); for (const auto& is : intersections(gv,e)) { + +#if __cpp_concepts > 202002L && __cpp_lib_concepts > 202002L + static_assert(Dune::Concept::Entity>); + static_assert(Dune::Concept::Intersection>); +#endif + indices.back().push_back(is.indexInInside()); intersection_list.back().push_back(is); coords.back().push_back(is.geometry().corner(0)); diff --git a/dune/grid/test/test-concepts.cc b/dune/grid/test/test-concepts.cc new file mode 100644 index 000000000..7ee276fb9 --- /dev/null +++ b/dune/grid/test/test-concepts.cc @@ -0,0 +1,72 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifdef HAVE_CONFIG_H +#include +#endif + +// check whether c++20 concept can be used +#if DUNE_HAVE_CXX_UNEVALUATED_CONTEXT_LAMBDA + #if __has_include() && __has_include() + #include + #if __cpp_concepts >= 201907L && __cpp_lib_concepts >= 202002L + #define DUNE_ENABLE_CONCEPTS 1 + #endif + #endif +#endif + +#if DUNE_ENABLE_CONCEPTS + +#include +#include +#include +#include + +#if HAVE_ALBERTA +#include +#endif + +#if HAVE_UG +#include +#endif + +#include + +int main ( int argc, char **argv ) +{ + Dune::MPIHelper::instance( argc, argv ); + + static_assert(Dune::Concept::Grid< Dune::OneDGrid >); + + static_assert(Dune::Concept::Grid< Dune::YaspGrid<1> >); + static_assert(Dune::Concept::Grid< Dune::YaspGrid<2> >); + static_assert(Dune::Concept::Grid< Dune::YaspGrid<3> >); + +#if HAVE_ALBERTA + static_assert(Dune::Concept::Grid< Dune::AlbertaGrid<1,1> >); + static_assert(Dune::Concept::Grid< Dune::AlbertaGrid<1,2> >); + static_assert(Dune::Concept::Grid< Dune::AlbertaGrid<1,3> >); + static_assert(Dune::Concept::Grid< Dune::AlbertaGrid<2,2> >); + static_assert(Dune::Concept::Grid< Dune::AlbertaGrid<2,3> >); + static_assert(Dune::Concept::Grid< Dune::AlbertaGrid<3,3> >); +#endif + +#if HAVE_UG + static_assert(Dune::Concept::Grid< Dune::UGGrid<1> >); + static_assert(Dune::Concept::Grid< Dune::UGGrid<2> >); + static_assert(Dune::Concept::Grid< Dune::UGGrid<3> >); +#endif + + // check grid wrappers + static_assert(Dune::Concept::Grid< Dune::GeometryGrid< Dune::YaspGrid<1> > >); + static_assert(Dune::Concept::Grid< Dune::IdentityGrid< Dune::YaspGrid<1> > >); + +} + +#else // DUNE_ENABLE_CONCEPTS + +int main() +{ + return 77; +} + +#endif // DUNE_ENABLE_CONCEPTS -- GitLab From 2f86b09cc498bd15dede518e65143be00ca7337f Mon Sep 17 00:00:00 2001 From: Santiago Ospina De Los Rios Date: Mon, 25 Apr 2022 17:33:40 +0200 Subject: [PATCH 2/7] Add convenience header to include all concepts Conditionally define DUNE_GRID_HAVE_CONCEPTS Add requirements explanation in the main concepts header --- CHANGELOG.md | 4 ++ dune/grid/concepts.hh | 46 +++++++++++++++++++++ dune/grid/test/checkentitylifetime.hh | 9 ++-- dune/grid/test/checkintersectionlifetime.hh | 11 ++--- 4 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 dune/grid/concepts.hh diff --git a/CHANGELOG.md b/CHANGELOG.md index bc1688bc7..cb01f55db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception # Master (will become release 2.9) - UGGrid is now thread safe on the grid view. + +- Grid concepts are here! A `Grid` can now be inspected and extended + at compilation time using concepts. + - The `Geometry` interface was extended by methods `jacobian(local)` and `jacobianInverse(local)` and corresponding typedefs `Jacobian` and `JacobianInverse`. All grid implementations need to provide the new interface. For transition, the methods and typedefs are default-implemented diff --git a/dune/grid/concepts.hh b/dune/grid/concepts.hh new file mode 100644 index 000000000..d6ac3fe1d --- /dev/null +++ b/dune/grid/concepts.hh @@ -0,0 +1,46 @@ +#ifndef DUNE_GRID_CONCEPTS_HH +#define DUNE_GRID_CONCEPTS_HH + +/** + * This file contains a convenience definition that checks if concepts are available + * If DUNE_GRID_HAVE_CONCEPTS is true, the dune-grid concepts are available and + * have been included. + * + * In order to enable these concepts, you need the following: + * (i) A C++20 compiler with concepts (i.e. __cpp_concepts >= 201907L) + * (ii) The concepts in the standard library (i.e. __cpp_lib_concepts >= 202002L) + * (iii) A C++ compiler that supports unevaluated context lambdas (i.e. + * can compile `using = decltype([]{})`). This is automatically tested by + * CMake and exposed as a macro definition + * `DUNE_HAVE_CXX_UNEVALUATED_CONTEXT_LAMBDA`. + * + * - `gcc>=9` and `clang>=12` are known to fulfill (i) and (iii). + * - `libstdc++>10` and `libc++>=13` are known to fulfill (ii). + */ + +// check whether c++20 concept can be used +#if __has_include() && __has_include() + #include + #if __cpp_concepts >= 201907L && __cpp_lib_concepts >= 202002L && DUNE_HAVE_CXX_UNEVALUATED_CONTEXT_LAMBDA + #ifndef DUNE_GRID_HAVE_CONCEPTS + #define DUNE_GRID_HAVE_CONCEPTS 1 + #endif + #endif +#endif + +//! Grid concepts are available +#if DUNE_GRID_HAVE_CONCEPTS + +// Include all concept headers +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // DUNE_GRID_HAVE_CONCEPTS + +#endif // DUNE_GRID_CONCEPTS_HH diff --git a/dune/grid/test/checkentitylifetime.hh b/dune/grid/test/checkentitylifetime.hh index 44ebdaf98..c80886005 100644 --- a/dune/grid/test/checkentitylifetime.hh +++ b/dune/grid/test/checkentitylifetime.hh @@ -18,10 +18,7 @@ #include #include #include - -#if __cpp_concepts > 202002L && __cpp_lib_concepts > 202002L -#include -#endif +#include #if not defined(DUNE_ENTITY_LIFETIME_CHECK_ELEMENT_COUNT) #define DUNE_ENTITY_LIFETIME_CHECK_ELEMENT_COUNT 32 @@ -57,7 +54,7 @@ bool checkEntityLifetimeForCodim(GV gv, std::size_t check_element_count, Dune::C std::size_t i = 0; for (const auto& e : entities(gv,Dune::Codim())) { -#if __cpp_concepts > 202002L && __cpp_lib_concepts > 202002L +#if DUNE_GRID_HAVE_CONCEPTS static_assert(Dune::Concept::Entity>); #endif if (++i > check_element_count) @@ -89,7 +86,7 @@ bool checkEntityLifetimeForCodim(GV gv, std::size_t check_element_count, Dune::C " (" << entity_list[i].geometry().corner(0) << " != " << coords[i] << ")"); } -#if __cpp_concepts > 202002L && __cpp_lib_concepts > 202002L +#if DUNE_GRID_HAVE_CONCEPTS static_assert(Dune::Concept::GridView); static_assert(Dune::Concept::IndexSet); static_assert(Dune::Concept::IdSet); diff --git a/dune/grid/test/checkintersectionlifetime.hh b/dune/grid/test/checkintersectionlifetime.hh index 8040a242b..97e41cae2 100644 --- a/dune/grid/test/checkintersectionlifetime.hh +++ b/dune/grid/test/checkintersectionlifetime.hh @@ -17,12 +17,7 @@ #include -#if __cpp_concepts > 202002L && __cpp_lib_concepts > 202002L -#include -#include -#include -#include -#endif +#include template void checkIntersectionLifetime(GV gv, std::size_t check_element_count = 32) @@ -51,7 +46,7 @@ void checkIntersectionLifetime(GV gv, std::size_t check_element_count = 32) auto intersection_iterator = gv.ibegin(*entity_iterator); -#if __cpp_concepts > 202002L && __cpp_lib_concepts > 202002L +#if DUNE_GRID_HAVE_CONCEPTS static_assert(Dune::Concept::EntityIterator); static_assert(Dune::Concept::IntersectionIterator); static_assert(Dune::Concept::Entity>); @@ -72,7 +67,7 @@ void checkIntersectionLifetime(GV gv, std::size_t check_element_count = 32) for (const auto& is : intersections(gv,e)) { -#if __cpp_concepts > 202002L && __cpp_lib_concepts > 202002L +#if DUNE_GRID_HAVE_CONCEPTS static_assert(Dune::Concept::Entity>); static_assert(Dune::Concept::Intersection>); #endif -- GitLab From 6ffc4f9a3332486d85fe9b48c142b834f63980f1 Mon Sep 17 00:00:00 2001 From: Simon Praetorius Date: Fri, 21 Oct 2022 10:45:46 +0200 Subject: [PATCH 3/7] Add test for grid concepts --- dune/grid/test/CMakeLists.txt | 2 ++ dune/grid/test/test-concepts.cc | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dune/grid/test/CMakeLists.txt b/dune/grid/test/CMakeLists.txt index 8cc87bf5f..d38627508 100644 --- a/dune/grid/test/CMakeLists.txt +++ b/dune/grid/test/CMakeLists.txt @@ -3,6 +3,8 @@ add_subdirectory(yasp) +dune_add_test(SOURCES test-concepts.cc) + dune_add_test(SOURCES geometrygrid-coordfunction-copyconstructor.cc) dune_add_test(NAME test-geogrid-yaspgrid diff --git a/dune/grid/test/test-concepts.cc b/dune/grid/test/test-concepts.cc index 7ee276fb9..0551bbeef 100644 --- a/dune/grid/test/test-concepts.cc +++ b/dune/grid/test/test-concepts.cc @@ -36,7 +36,6 @@ int main ( int argc, char **argv ) Dune::MPIHelper::instance( argc, argv ); static_assert(Dune::Concept::Grid< Dune::OneDGrid >); - static_assert(Dune::Concept::Grid< Dune::YaspGrid<1> >); static_assert(Dune::Concept::Grid< Dune::YaspGrid<2> >); static_assert(Dune::Concept::Grid< Dune::YaspGrid<3> >); -- GitLab From 9c67b53b3432dd34100a212305f85c567dadaf52 Mon Sep 17 00:00:00 2001 From: Simon Praetorius Date: Fri, 21 Oct 2022 12:20:00 +0200 Subject: [PATCH 4/7] Add copyright headers --- dune/grid/concepts.hh | 6 +++++- dune/grid/concepts/CMakeLists.txt | 3 +++ dune/grid/concepts/entity.hh | 4 ++++ dune/grid/concepts/entityiterator.hh | 4 ++++ dune/grid/concepts/entityset.hh | 4 ++++ dune/grid/concepts/geometry.hh | 4 ++++ dune/grid/concepts/grid.hh | 4 ++++ dune/grid/concepts/gridview.hh | 4 ++++ dune/grid/concepts/indexset.hh | 4 ++++ dune/grid/concepts/intersection.hh | 4 ++++ dune/grid/concepts/intersectioniterator.hh | 4 ++++ dune/grid/test/test-concepts.cc | 19 ++++++------------- 12 files changed, 50 insertions(+), 14 deletions(-) diff --git a/dune/grid/concepts.hh b/dune/grid/concepts.hh index d6ac3fe1d..5ab86c66a 100644 --- a/dune/grid/concepts.hh +++ b/dune/grid/concepts.hh @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: #ifndef DUNE_GRID_CONCEPTS_HH #define DUNE_GRID_CONCEPTS_HH @@ -43,4 +47,4 @@ #endif // DUNE_GRID_HAVE_CONCEPTS -#endif // DUNE_GRID_CONCEPTS_HH +#endif // DUNE_GRID_CONCEPTS_HH \ No newline at end of file diff --git a/dune/grid/concepts/CMakeLists.txt b/dune/grid/concepts/CMakeLists.txt index f35e471f3..dc5096cfd 100644 --- a/dune/grid/concepts/CMakeLists.txt +++ b/dune/grid/concepts/CMakeLists.txt @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +# SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception + install(FILES entity.hh entityiterator.hh diff --git a/dune/grid/concepts/entity.hh b/dune/grid/concepts/entity.hh index 66a478018..457373c14 100644 --- a/dune/grid/concepts/entity.hh +++ b/dune/grid/concepts/entity.hh @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: #ifndef DUNE_GRID_CONCEPT_ENTITY_HH #define DUNE_GRID_CONCEPT_ENTITY_HH diff --git a/dune/grid/concepts/entityiterator.hh b/dune/grid/concepts/entityiterator.hh index 1ecf1886e..09e677297 100644 --- a/dune/grid/concepts/entityiterator.hh +++ b/dune/grid/concepts/entityiterator.hh @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: #ifndef DUNE_GRID_CONCEPTS_ENTITY_ITERATOR_HH #define DUNE_GRID_CONCEPTS_ENTITY_ITERATOR_HH diff --git a/dune/grid/concepts/entityset.hh b/dune/grid/concepts/entityset.hh index e0b14fb6d..205d07db3 100644 --- a/dune/grid/concepts/entityset.hh +++ b/dune/grid/concepts/entityset.hh @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: #ifndef DUNE_GRID_CONCEPTS_ENTITY_SET_HH #define DUNE_GRID_CONCEPTS_ENTITY_SET_HH diff --git a/dune/grid/concepts/geometry.hh b/dune/grid/concepts/geometry.hh index c81a86f20..4929996cd 100644 --- a/dune/grid/concepts/geometry.hh +++ b/dune/grid/concepts/geometry.hh @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: #ifndef DUNE_GRID_CONCEPTS_GEOMETRY_HH #define DUNE_GRID_CONCEPTS_GEOMETRY_HH diff --git a/dune/grid/concepts/grid.hh b/dune/grid/concepts/grid.hh index d6090d78a..2d3e6db74 100644 --- a/dune/grid/concepts/grid.hh +++ b/dune/grid/concepts/grid.hh @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: #ifndef DUNE_GRID_CONCEPTS_GRID_HH #define DUNE_GRID_CONCEPTS_GRID_HH diff --git a/dune/grid/concepts/gridview.hh b/dune/grid/concepts/gridview.hh index 4b6ace6c1..a6d48c05a 100644 --- a/dune/grid/concepts/gridview.hh +++ b/dune/grid/concepts/gridview.hh @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: #ifndef DUNE_GRID_CONCEPTS_GRIDVIEW_HH #define DUNE_GRID_CONCEPTS_GRIDVIEW_HH diff --git a/dune/grid/concepts/indexset.hh b/dune/grid/concepts/indexset.hh index 7c4fdd5be..b398ede0b 100644 --- a/dune/grid/concepts/indexset.hh +++ b/dune/grid/concepts/indexset.hh @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: #ifndef DUNE_GRID_CONCEPTS_INDEX_SET_HH #define DUNE_GRID_CONCEPTS_INDEX_SET_HH diff --git a/dune/grid/concepts/intersection.hh b/dune/grid/concepts/intersection.hh index 88af9bb1f..65061a780 100644 --- a/dune/grid/concepts/intersection.hh +++ b/dune/grid/concepts/intersection.hh @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: #ifndef DUNE_GRID_CONCEPTS_INTERSECTION_HH #define DUNE_GRID_CONCEPTS_INTERSECTION_HH diff --git a/dune/grid/concepts/intersectioniterator.hh b/dune/grid/concepts/intersectioniterator.hh index e04189c65..fff8b9e4a 100644 --- a/dune/grid/concepts/intersectioniterator.hh +++ b/dune/grid/concepts/intersectioniterator.hh @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: #ifndef DUNE_GRID_CONCEPTS_INTERSECTION_ITERATOR_HH #define DUNE_GRID_CONCEPTS_INTERSECTION_ITERATOR_HH diff --git a/dune/grid/test/test-concepts.cc b/dune/grid/test/test-concepts.cc index 0551bbeef..4cac2b0cb 100644 --- a/dune/grid/test/test-concepts.cc +++ b/dune/grid/test/test-concepts.cc @@ -1,20 +1,14 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- // vi: set et ts=4 sw=2 sts=2: #ifdef HAVE_CONFIG_H #include #endif -// check whether c++20 concept can be used -#if DUNE_HAVE_CXX_UNEVALUATED_CONTEXT_LAMBDA - #if __has_include() && __has_include() - #include - #if __cpp_concepts >= 201907L && __cpp_lib_concepts >= 202002L - #define DUNE_ENABLE_CONCEPTS 1 - #endif - #endif -#endif +#include -#if DUNE_ENABLE_CONCEPTS +#if DUNE_GRID_HAVE_CONCEPTS #include #include @@ -29,7 +23,6 @@ #include #endif -#include int main ( int argc, char **argv ) { @@ -61,11 +54,11 @@ int main ( int argc, char **argv ) } -#else // DUNE_ENABLE_CONCEPTS +#else // DUNE_GRID_HAVE_CONCEPTS int main() { return 77; } -#endif // DUNE_ENABLE_CONCEPTS +#endif // DUNE_GRID_HAVE_CONCEPTS -- GitLab From bcfe50a3655e8badee3826a72b48559ba5962d4c Mon Sep 17 00:00:00 2001 From: Santiago Ospina De Los Rios Date: Fri, 21 Oct 2022 16:24:38 +0200 Subject: [PATCH 5/7] Use data handle archetype to check communication concept --- dune/grid/concepts/CMakeLists.txt | 3 ++ dune/grid/concepts/archetypes/CMakeLists.txt | 9 ++++ dune/grid/concepts/archetypes/datahandle.hh | 34 ++++++++++++ dune/grid/concepts/archetypes/entity.hh | 51 ++++++++++++++++++ dune/grid/concepts/archetypes/geometry.hh | 54 +++++++++++++++++++ .../grid/concepts/archetypes/messagebuffer.hh | 20 +++++++ dune/grid/concepts/datahandle.hh | 35 ++++++++++++ dune/grid/concepts/entity.hh | 10 +++- dune/grid/concepts/entityset.hh | 8 ++- dune/grid/concepts/geometry.hh | 8 +++ dune/grid/concepts/grid.hh | 12 ++++- dune/grid/concepts/messagebuffer.hh | 31 +++++++++++ 12 files changed, 270 insertions(+), 5 deletions(-) create mode 100644 dune/grid/concepts/archetypes/CMakeLists.txt create mode 100644 dune/grid/concepts/archetypes/datahandle.hh create mode 100644 dune/grid/concepts/archetypes/entity.hh create mode 100644 dune/grid/concepts/archetypes/geometry.hh create mode 100644 dune/grid/concepts/archetypes/messagebuffer.hh create mode 100644 dune/grid/concepts/datahandle.hh create mode 100644 dune/grid/concepts/messagebuffer.hh diff --git a/dune/grid/concepts/CMakeLists.txt b/dune/grid/concepts/CMakeLists.txt index dc5096cfd..eed3319ef 100644 --- a/dune/grid/concepts/CMakeLists.txt +++ b/dune/grid/concepts/CMakeLists.txt @@ -2,6 +2,7 @@ # SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception install(FILES + datahandle.hh entity.hh entityiterator.hh entityset.hh @@ -12,3 +13,5 @@ install(FILES intersection.hh intersectioniterator.hh DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/grid/concepts) + +add_subdirectory(archetypes) \ No newline at end of file diff --git a/dune/grid/concepts/archetypes/CMakeLists.txt b/dune/grid/concepts/archetypes/CMakeLists.txt new file mode 100644 index 000000000..bd6d5e44b --- /dev/null +++ b/dune/grid/concepts/archetypes/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +# SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception + +install(FILES + datahandle.hh + entity.hh + geometry.hh + messagebuffer.hh + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/grid/concepts/archetypes) diff --git a/dune/grid/concepts/archetypes/datahandle.hh b/dune/grid/concepts/archetypes/datahandle.hh new file mode 100644 index 000000000..67d384d93 --- /dev/null +++ b/dune/grid/concepts/archetypes/datahandle.hh @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifndef DUNE_GRID_CONCEPTS_ARCHETYPES_DATAHANDLE_HH +#define DUNE_GRID_CONCEPTS_ARCHETYPES_DATAHANDLE_HH + +#include +#include + +namespace Dune::Concept::Archetypes { + +template +struct CommDataHandle : public Dune::CommDataHandleIF, Data> +{ + using DataType = Data; + + bool contains (int dim, int codim) const; + bool fixedSize (int dim, int codim) const; + + template + std::size_t size (const Entity& entity) const; + + template + void gather (Buffer& buffer, const Entity& entity) const; + + template + void scatter (Buffer& buffer, const Entity& entity, std::size_t size); +}; + +} // end namespace Dune::Concept::Archetypes + + +#endif // DUNE_GRID_CONCEPTS_ARCHETYPES_DATAHANDLE_HH diff --git a/dune/grid/concepts/archetypes/entity.hh b/dune/grid/concepts/archetypes/entity.hh new file mode 100644 index 000000000..6d6b468db --- /dev/null +++ b/dune/grid/concepts/archetypes/entity.hh @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifndef DUNE_GRID_CONCEPT_ARCHETYPES_ENTITY_HH +#define DUNE_GRID_CONCEPT_ARCHETYPES_ENTITY_HH + + +#include +#include +#include +#include + +namespace Dune::Concept::Archetypes { + +template +struct EntitySeed +{ + static constexpr int codimension = codim; + bool isValid() const { return true; } +}; + + +template +struct Entity +{ + static constexpr int dimension = dim; + static constexpr int codimension = codim; + static constexpr int mydimension = dim - codim; + + using Geometry = Archetypes::Geometry; + using EntitySeed = Archetypes::EntitySeed; + + int level () const; + Dune::PartitionType partitionType () const; + Geometry geometry() const; + Dune::GeometryType type() const; + unsigned int subEntities(int cd) const; + EntitySeed seed() const; + + template + Archetypes::Entity subEntity(int i) const; + + bool operator==(Entity const&) const; + bool operator!=(Entity const&) const; +}; + +} // end namespace Dune::Concept::Archetypes + + +#endif // DUNE_GRID_CONCEPT_ARCHETYPES_ENTITY_HH diff --git a/dune/grid/concepts/archetypes/geometry.hh b/dune/grid/concepts/archetypes/geometry.hh new file mode 100644 index 000000000..771a1d8d9 --- /dev/null +++ b/dune/grid/concepts/archetypes/geometry.hh @@ -0,0 +1,54 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifndef DUNE_GRID_CONCEPTS_ARCHETYPES_GEOMETRY_HH +#define DUNE_GRID_CONCEPTS_ARCHETYPES_GEOMETRY_HH + +#include +#include +#include + +namespace Dune::Concept::Archetypes { + +struct ReferenceElement {}; + +template +struct Geometry +{ + static constexpr int mydimension = mydim; + static constexpr int coorddimension = cdim; + + using ctype = double; + using LocalCoordinate = Dune::FieldVector; + using GlobalCoordinate = Dune::FieldVector; + using Volume = ctype; + using Jacobian = Dune::FieldMatrix; + using JacobianTransposed = Dune::FieldMatrix; + using JacobianInverse = Dune::FieldMatrix; + using JacobianInverseTransposed = Dune::FieldMatrix; + + Dune::GeometryType type () const; + bool affine () const; + int corners() const; + + GlobalCoordinate corner(int i) const; + GlobalCoordinate global(const LocalCoordinate&) const; + LocalCoordinate local(const GlobalCoordinate&) const; + GlobalCoordinate center() const; + + Volume integrationElement(const LocalCoordinate&) const; + Volume volume() const; + + Jacobian jacobian(const LocalCoordinate&) const; + JacobianTransposed jacobianTransposed(const LocalCoordinate&) const; + JacobianInverse jacobianInverse(const LocalCoordinate&) const; + JacobianInverseTransposed jacobianInverseTransposed(const LocalCoordinate&) const; + + friend Archetypes::ReferenceElement referenceElement(const Geometry&) { return Archetypes::ReferenceElement{}; } +}; + +} // end namespace Dune::Concept::Archetypes + + +#endif // DUNE_GRID_CONCEPTS_ARCHETYPES_GEOMETRY_HH diff --git a/dune/grid/concepts/archetypes/messagebuffer.hh b/dune/grid/concepts/archetypes/messagebuffer.hh new file mode 100644 index 000000000..339dddc05 --- /dev/null +++ b/dune/grid/concepts/archetypes/messagebuffer.hh @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifndef DUNE_GRID_CONCEPTS_ARCHETYPES_MESSAGEBUFFER_HH +#define DUNE_GRID_CONCEPTS_ARCHETYPES_MESSAGEBUFFER_HH + +namespace Dune::Concept::Archetypes { + +template +struct MessageBuffer +{ + void write(const DataType& data); + void read(DataType& data); +}; + +} // end namespace Dune::Concept::Archetypes + + +#endif // DUNE_GRID_CONCEPTS_ARCHETYPES_MESSAGEBUFFER_HH diff --git a/dune/grid/concepts/datahandle.hh b/dune/grid/concepts/datahandle.hh new file mode 100644 index 000000000..70aefe550 --- /dev/null +++ b/dune/grid/concepts/datahandle.hh @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifndef DUNE_GRID_CONCEPTS_DATAHANDLE_HH +#define DUNE_GRID_CONCEPTS_DATAHANDLE_HH + +#include +#include +#include + +namespace Dune::Concept { + +template +concept CommDataHandle = requires(DH handle, const Archetypes::Entity<2,0>& entity) +{ + typename DH::DataType; + + { handle.contains(/*dim*/ 0, /*codim*/ 0) } -> std::convertible_to; + { handle.fixedSize(/*dim*/ 0, /*codim*/ 0) } -> std::convertible_to; + { handle.size(entity) } -> std::integral; + + requires requires(Archetypes::MessageBuffer buffer) + { + handle.gather(buffer, entity); + handle.scatter(buffer, entity, /*size*/ 0u); + } +}; + +static_assert(CommDataHandle< Archetypes::CommDataHandle >); + +} // end namespace Dune::Concept + + +#endif // DUNE_GRID_CONCEPTS_DATAHANDLE_HH diff --git a/dune/grid/concepts/entity.hh b/dune/grid/concepts/entity.hh index 457373c14..f44f4b711 100644 --- a/dune/grid/concepts/entity.hh +++ b/dune/grid/concepts/entity.hh @@ -6,9 +6,10 @@ #define DUNE_GRID_CONCEPT_ENTITY_HH -#include - #include +#include +#include +#include #include @@ -27,6 +28,9 @@ concept EntitySeed = requires(S seed) { seed.isValid() } -> std::convertible_to; }; +static_assert(EntitySeed< Archetypes::EntitySeed<0> >); + + /** * @brief Model of a grid entity for any codimension * @ingroup GridConcepts @@ -50,6 +54,8 @@ concept EntityGeneral = requires(E e, unsigned int codim) requires std::copyable; }; +static_assert(EntityGeneral< Archetypes::Entity<2,0> >); + namespace Impl { diff --git a/dune/grid/concepts/entityset.hh b/dune/grid/concepts/entityset.hh index 205d07db3..7b28764ca 100644 --- a/dune/grid/concepts/entityset.hh +++ b/dune/grid/concepts/entityset.hh @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -36,7 +37,12 @@ namespace Impl { { es.comm() } -> std::convertible_to< typename ES::CollectiveCommunication >; { es.overlapSize(codim) } -> std::convertible_to< int >; { es.ghostSize(codim) } -> std::convertible_to< int >; - //! gv.communicate(std::declval(),std::declval(), std::declval()), // FIXME use a default handler to instantiate this function + + requires requires(Archetypes::CommDataHandle& handle, + InterfaceType iface, CommunicationDirection dir) + { + es.communicate(handle, iface, dir); + }; requires std::copy_constructible; }; diff --git a/dune/grid/concepts/geometry.hh b/dune/grid/concepts/geometry.hh index 4929996cd..3a79975fb 100644 --- a/dune/grid/concepts/geometry.hh +++ b/dune/grid/concepts/geometry.hh @@ -5,13 +5,19 @@ #ifndef DUNE_GRID_CONCEPTS_GEOMETRY_HH #define DUNE_GRID_CONCEPTS_GEOMETRY_HH +#include +#include #include +#include namespace Dune::Concept { template concept ReferenceElement = true; +static_assert(ReferenceElement< Archetypes::ReferenceElement >); + + /** * @brief Model of a geometry object * @ingroup GridConcepts @@ -39,6 +45,8 @@ concept Geometry = requires(const G& g, typename G::GlobalCoordinate global, typ { referenceElement(g) } -> ReferenceElement; }; +static_assert(Geometry< Archetypes::Geometry<2,3> >); + } // end namespace Dune::Concept #endif // DUNE_GRID_CONCEPTS_GEOMETRY_HH diff --git a/dune/grid/concepts/grid.hh b/dune/grid/concepts/grid.hh index 2d3e6db74..73bff031a 100644 --- a/dune/grid/concepts/grid.hh +++ b/dune/grid/concepts/grid.hh @@ -13,6 +13,8 @@ #include #include +#include + #include #include @@ -69,7 +71,9 @@ namespace Dune::Concept { * @details Dune::Grid is a template for this model */ template -concept Grid = requires(G g, int level, int codim, int refCount, Dune::GeometryType type, const typename G::template Codim<0>::Entity& entity) +concept Grid = requires(G g, int level, int codim, int refCount, + Dune::GeometryType type, + const typename G::template Codim<0>::Entity& entity) { { G::dimension } -> std::convertible_to; { G::dimensionworld } -> std::convertible_to; @@ -106,7 +110,11 @@ concept Grid = requires(G g, int level, int codim, int refCount, Dune::GeometryT { g.adapt() } -> std::convertible_to< bool >; { g.comm() } -> std::convertible_to< typename G::CollectiveCommunication >; { g.loadBalance() } -> std::convertible_to< bool >; - //! requireConvertible(g.loadBalance(/*data*/ std::declval())) // FIXME use a default handler to instantiate this function + requires requires(Archetypes::CommDataHandle& handle, + InterfaceType iface, CommunicationDirection dir) + { + { g.loadBalance(handle) } -> std::convertible_to< bool >; + }; g.globalRefine(refCount); g.postAdapt(); }; diff --git a/dune/grid/concepts/messagebuffer.hh b/dune/grid/concepts/messagebuffer.hh new file mode 100644 index 000000000..8ce267f5f --- /dev/null +++ b/dune/grid/concepts/messagebuffer.hh @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifndef DUNE_GRID_CONCEPT_MESSAGEBUFFER_HH +#define DUNE_GRID_CONCEPT_MESSAGEBUFFER_HH + +#include + +namespace Dune::Concept { + +/** + * @brief Model of a message buffer + * @ingroup GridConcepts + */ +template +concept MessageBuffer = requires(MB mb, T& val) +{ + mb.write(val); + mb.read(val); +}; + +static_assert(Concept::MessageBuffer, unsigned char>); + +} // namespace Archetypes + + +} // end namespace Dune::Concept + + +#endif // DUNE_GRID_CONCEPT_MESSAGEBUFFER_HH -- GitLab From ea6340b8a99c912b830d0cee5af7ab930dc97ed5 Mon Sep 17 00:00:00 2001 From: Santiago Ospina De Los Rios Date: Fri, 21 Oct 2022 16:52:43 +0200 Subject: [PATCH 6/7] Cleanup of concept definitions * Check const correctness * Check communicate capability * Check communicate on all codimensions * Hide archetype classes from doxygen * Fix capability access * Use HAVE_DUNE_UGGRID instead of HAVE_UG in test-concepts --- dune/grid/concepts.hh | 11 +- dune/grid/concepts/CMakeLists.txt | 3 +- dune/grid/concepts/archetypes/datahandle.hh | 10 +- dune/grid/concepts/archetypes/entity.hh | 20 +-- dune/grid/concepts/archetypes/geometry.hh | 32 ++-- .../grid/concepts/archetypes/messagebuffer.hh | 3 +- dune/grid/concepts/datahandle.hh | 16 +- dune/grid/concepts/entity.hh | 68 ++++--- dune/grid/concepts/entityiterator.hh | 7 +- dune/grid/concepts/entityset.hh | 51 +++--- dune/grid/concepts/geometry.hh | 36 ++-- dune/grid/concepts/grid.hh | 169 ++++++++++-------- dune/grid/concepts/gridview.hh | 27 +-- dune/grid/concepts/indexidset.hh | 93 ++++++++++ dune/grid/concepts/indexset.hh | 94 ---------- dune/grid/concepts/intersection.hh | 49 +++-- dune/grid/concepts/intersectioniterator.hh | 7 +- dune/grid/concepts/messagebuffer.hh | 11 +- dune/grid/test/test-concepts.cc | 5 +- 19 files changed, 368 insertions(+), 344 deletions(-) create mode 100644 dune/grid/concepts/indexidset.hh delete mode 100644 dune/grid/concepts/indexset.hh diff --git a/dune/grid/concepts.hh b/dune/grid/concepts.hh index 5ab86c66a..cc7b2d13e 100644 --- a/dune/grid/concepts.hh +++ b/dune/grid/concepts.hh @@ -36,14 +36,17 @@ #if DUNE_GRID_HAVE_CONCEPTS // Include all concept headers +#include #include #include -#include -#include +#include #include -#include -#include #include +#include +#include +#include +#include +#include #endif // DUNE_GRID_HAVE_CONCEPTS diff --git a/dune/grid/concepts/CMakeLists.txt b/dune/grid/concepts/CMakeLists.txt index eed3319ef..d26a98d2b 100644 --- a/dune/grid/concepts/CMakeLists.txt +++ b/dune/grid/concepts/CMakeLists.txt @@ -9,9 +9,10 @@ install(FILES geometry.hh grid.hh gridview.hh - indexset.hh + indexidset.hh intersection.hh intersectioniterator.hh + messagebuffer.hh DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/grid/concepts) add_subdirectory(archetypes) \ No newline at end of file diff --git a/dune/grid/concepts/archetypes/datahandle.hh b/dune/grid/concepts/archetypes/datahandle.hh index 67d384d93..6a123f32a 100644 --- a/dune/grid/concepts/archetypes/datahandle.hh +++ b/dune/grid/concepts/archetypes/datahandle.hh @@ -2,12 +2,14 @@ // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- // vi: set et ts=4 sw=2 sts=2: -#ifndef DUNE_GRID_CONCEPTS_ARCHETYPES_DATAHANDLE_HH -#define DUNE_GRID_CONCEPTS_ARCHETYPES_DATAHANDLE_HH +#ifndef DUNE_GRID_CONCEPTS_ARCHETYPES_COMMDATAHANDLE_HH +#define DUNE_GRID_CONCEPTS_ARCHETYPES_COMMDATAHANDLE_HH #include + #include +#ifndef DOXYGEN namespace Dune::Concept::Archetypes { template @@ -29,6 +31,6 @@ struct CommDataHandle : public Dune::CommDataHandleIF, Data }; } // end namespace Dune::Concept::Archetypes +#endif // DOXYGEN - -#endif // DUNE_GRID_CONCEPTS_ARCHETYPES_DATAHANDLE_HH +#endif // DUNE_GRID_CONCEPTS_ARCHETYPES_COMMDATAHANDLE_HH diff --git a/dune/grid/concepts/archetypes/entity.hh b/dune/grid/concepts/archetypes/entity.hh index 6d6b468db..76680e2a3 100644 --- a/dune/grid/concepts/archetypes/entity.hh +++ b/dune/grid/concepts/archetypes/entity.hh @@ -5,19 +5,19 @@ #ifndef DUNE_GRID_CONCEPT_ARCHETYPES_ENTITY_HH #define DUNE_GRID_CONCEPT_ARCHETYPES_ENTITY_HH - #include #include #include #include +#ifndef DOXYGEN namespace Dune::Concept::Archetypes { template struct EntitySeed { static constexpr int codimension = codim; - bool isValid() const { return true; } + bool isValid () const; }; @@ -33,19 +33,19 @@ struct Entity int level () const; Dune::PartitionType partitionType () const; - Geometry geometry() const; - Dune::GeometryType type() const; - unsigned int subEntities(int cd) const; - EntitySeed seed() const; + Geometry geometry () const; + Dune::GeometryType type () const; + unsigned int subEntities (int cd) const; + EntitySeed seed () const; template - Archetypes::Entity subEntity(int i) const; + Archetypes::Entity subEntity (int i) const; - bool operator==(Entity const&) const; - bool operator!=(Entity const&) const; + bool operator== (Entity const& entity) const; + bool operator!= (Entity const& entity) const; }; } // end namespace Dune::Concept::Archetypes - +#endif // DOXYGEN #endif // DUNE_GRID_CONCEPT_ARCHETYPES_ENTITY_HH diff --git a/dune/grid/concepts/archetypes/geometry.hh b/dune/grid/concepts/archetypes/geometry.hh index 771a1d8d9..443eb5796 100644 --- a/dune/grid/concepts/archetypes/geometry.hh +++ b/dune/grid/concepts/archetypes/geometry.hh @@ -9,6 +9,7 @@ #include #include +#ifndef DOXYGEN namespace Dune::Concept::Archetypes { struct ReferenceElement {}; @@ -20,9 +21,9 @@ struct Geometry static constexpr int coorddimension = cdim; using ctype = double; + using Volume = ctype; using LocalCoordinate = Dune::FieldVector; using GlobalCoordinate = Dune::FieldVector; - using Volume = ctype; using Jacobian = Dune::FieldMatrix; using JacobianTransposed = Dune::FieldMatrix; using JacobianInverse = Dune::FieldMatrix; @@ -30,25 +31,26 @@ struct Geometry Dune::GeometryType type () const; bool affine () const; - int corners() const; - - GlobalCoordinate corner(int i) const; - GlobalCoordinate global(const LocalCoordinate&) const; - LocalCoordinate local(const GlobalCoordinate&) const; - GlobalCoordinate center() const; + int corners () const; - Volume integrationElement(const LocalCoordinate&) const; - Volume volume() const; + GlobalCoordinate corner (int i) const; + GlobalCoordinate global (const LocalCoordinate& local) const; + LocalCoordinate local (const GlobalCoordinate& global) const; + GlobalCoordinate center () const; - Jacobian jacobian(const LocalCoordinate&) const; - JacobianTransposed jacobianTransposed(const LocalCoordinate&) const; - JacobianInverse jacobianInverse(const LocalCoordinate&) const; - JacobianInverseTransposed jacobianInverseTransposed(const LocalCoordinate&) const; + Volume integrationElement (const LocalCoordinate& local) const; + Volume volume () const; - friend Archetypes::ReferenceElement referenceElement(const Geometry&) { return Archetypes::ReferenceElement{}; } + Jacobian jacobian (const LocalCoordinate& local) const; + JacobianTransposed jacobianTransposed (const LocalCoordinate& local) const; + JacobianInverse jacobianInverse (const LocalCoordinate& local) const; + JacobianInverseTransposed jacobianInverseTransposed (const LocalCoordinate& local) const; }; -} // end namespace Dune::Concept::Archetypes +template +Archetypes::ReferenceElement referenceElement (const Geometry& g); +} // end namespace Dune::Concept::Archetypes +#endif // DOXYGEN #endif // DUNE_GRID_CONCEPTS_ARCHETYPES_GEOMETRY_HH diff --git a/dune/grid/concepts/archetypes/messagebuffer.hh b/dune/grid/concepts/archetypes/messagebuffer.hh index 339dddc05..0d4fa1097 100644 --- a/dune/grid/concepts/archetypes/messagebuffer.hh +++ b/dune/grid/concepts/archetypes/messagebuffer.hh @@ -5,6 +5,7 @@ #ifndef DUNE_GRID_CONCEPTS_ARCHETYPES_MESSAGEBUFFER_HH #define DUNE_GRID_CONCEPTS_ARCHETYPES_MESSAGEBUFFER_HH +#ifndef DOXYGEN namespace Dune::Concept::Archetypes { template @@ -15,6 +16,6 @@ struct MessageBuffer }; } // end namespace Dune::Concept::Archetypes - +#endif // DOXYGEN #endif // DUNE_GRID_CONCEPTS_ARCHETYPES_MESSAGEBUFFER_HH diff --git a/dune/grid/concepts/datahandle.hh b/dune/grid/concepts/datahandle.hh index 70aefe550..614ef61d9 100644 --- a/dune/grid/concepts/datahandle.hh +++ b/dune/grid/concepts/datahandle.hh @@ -5,26 +5,28 @@ #ifndef DUNE_GRID_CONCEPTS_DATAHANDLE_HH #define DUNE_GRID_CONCEPTS_DATAHANDLE_HH +#include + #include -#include #include +#include namespace Dune::Concept { template -concept CommDataHandle = requires(DH handle, const Archetypes::Entity<2,0>& entity) +concept CommDataHandle = requires(const DH chandle, const Archetypes::Entity<2,0>& entity) { typename DH::DataType; - { handle.contains(/*dim*/ 0, /*codim*/ 0) } -> std::convertible_to; - { handle.fixedSize(/*dim*/ 0, /*codim*/ 0) } -> std::convertible_to; - { handle.size(entity) } -> std::integral; + { chandle.contains(/*dim*/ 0, /*codim*/ 0) } -> std::convertible_to; + { chandle.fixedSize(/*dim*/ 0, /*codim*/ 0) } -> std::convertible_to; + { chandle.size(entity) } -> std::integral; - requires requires(Archetypes::MessageBuffer buffer) + requires requires(DH handle, Archetypes::MessageBuffer buffer) { handle.gather(buffer, entity); handle.scatter(buffer, entity, /*size*/ 0u); - } + }; }; static_assert(CommDataHandle< Archetypes::CommDataHandle >); diff --git a/dune/grid/concepts/entity.hh b/dune/grid/concepts/entity.hh index f44f4b711..840c5c2d8 100644 --- a/dune/grid/concepts/entity.hh +++ b/dune/grid/concepts/entity.hh @@ -5,14 +5,15 @@ #ifndef DUNE_GRID_CONCEPT_ENTITY_HH #define DUNE_GRID_CONCEPT_ENTITY_HH +#include +#include +#include #include #include #include #include -#include - namespace Dune::Concept { /** @@ -21,7 +22,7 @@ namespace Dune::Concept { * @details Dune::EntitySeed is a template for this model */ template -concept EntitySeed = requires(S seed) +concept EntitySeed = requires(const S seed) { requires std::default_initializable; { S::codimension } -> std::convertible_to; @@ -37,41 +38,38 @@ static_assert(EntitySeed< Archetypes::EntitySeed<0> >); * @details Dune::Entity is a template for this model. */ template -concept EntityGeneral = requires(E e, unsigned int codim) +concept EntityGeneral = std::regular && requires(const E e, unsigned int codim) { requires Geometry; requires EntitySeed; requires E::mydimension == (E::dimension - E::codimension); - { e.level() } -> std::convertible_to; - { e.partitionType() } -> std::convertible_to; - { e.geometry() } -> std::convertible_to; - { e.type() } -> std::convertible_to; - { e.subEntities(codim) } -> std::convertible_to; - { e.seed() } -> std::convertible_to; - { e==e } -> std::convertible_to; - { e!=e } -> std::convertible_to; - requires std::default_initializable; - requires std::copyable; + { e.level() } -> std::convertible_to; + { e.partitionType() } -> std::convertible_to; + { e.geometry() } -> std::convertible_to; + { e.type() } -> std::convertible_to; + { e.subEntities(codim) } -> std::convertible_to; + { e.seed() } -> std::convertible_to; }; static_assert(EntityGeneral< Archetypes::Entity<2,0> >); -namespace Impl -{ +namespace Impl { + template - concept EntityCodimExtended = requires(E e, int subEntity) + concept EntityCodimExtended = requires(const E e, int subEntity) { { e.template subEntity(subEntity) } -> EntityGeneral; }; - template - concept AllEntityCodimsExtended = requires(std::make_index_sequence codims) + template + concept AllEntityCodimsExtended = requires(std::make_integer_sequence codims) { - [](std::index_sequence) + [](std::integer_sequence) requires (Impl::EntityCodimExtended &&...) {} (codims); }; -} + +} // end namespace Impl /** * @brief Model of a grid entity with extended requirements for codimension 0 @@ -79,21 +77,20 @@ namespace Impl * @details Dune::Entity of codimension 0 is a template for this model. */ template -concept EntityExtended = requires(E e) +concept EntityExtended = EntityGeneral && requires(const E e, int maxLevel) { requires (E::codimension == 0); - requires EntityGeneral; requires Geometry; - { e.father() } -> std::convertible_to; - { e.hasFather() } -> std::convertible_to; - { e.isLeaf() } -> std::convertible_to; - { e.isRegular() } -> std::convertible_to; - { e.geometryInFather() } -> std::convertible_to; - { e.hbegin(/*maxLevel*/ int{}) } -> std::convertible_to; - { e.hend(/*maxLevel*/ int{}) } -> std::convertible_to; - { e.isNew() } -> std::convertible_to; - { e.mightVanish() } -> std::convertible_to; - { e.hasBoundaryIntersections() } -> std::convertible_to; + { e.father() } -> std::convertible_to; + { e.hasFather() } -> std::convertible_to; + { e.isLeaf() } -> std::convertible_to; + { e.isRegular() } -> std::convertible_to; + { e.geometryInFather() } -> std::convertible_to; + { e.hbegin(maxLevel) } -> std::convertible_to; + { e.hend(maxLevel) } -> std::convertible_to; + { e.isNew() } -> std::convertible_to; + { e.mightVanish() } -> std::convertible_to; + { e.hasBoundaryIntersections() } -> std::convertible_to; requires Impl::AllEntityCodimsExtended; requires std::same_as::Entity>; }; @@ -105,10 +102,7 @@ concept EntityExtended = requires(E e) * Dune::Entity is a template for this model. */ template -concept Entity = requires { - requires EntityGeneral; - requires (E::codimension != 0) || EntityExtended; -}; +concept Entity = EntityGeneral && ((E::codimension != 0) || EntityExtended); } // end namespace Dune::Concept diff --git a/dune/grid/concepts/entityiterator.hh b/dune/grid/concepts/entityiterator.hh index 09e677297..3a33dc34e 100644 --- a/dune/grid/concepts/entityiterator.hh +++ b/dune/grid/concepts/entityiterator.hh @@ -5,6 +5,9 @@ #ifndef DUNE_GRID_CONCEPTS_ENTITY_ITERATOR_HH #define DUNE_GRID_CONCEPTS_ENTITY_ITERATOR_HH +#include +#include + #include namespace Dune::Concept { @@ -15,11 +18,9 @@ namespace Dune::Concept { * @details Dune::EntityIterator is a template for this model */ template -concept EntityIterator = requires(It it) +concept EntityIterator = std::forward_iterator && std::default_initializable && requires { requires Entity; - requires std::forward_iterator; - requires std::default_initializable; }; } // end namespace Dune::Concept diff --git a/dune/grid/concepts/entityset.hh b/dune/grid/concepts/entityset.hh index 7b28764ca..e3f638735 100644 --- a/dune/grid/concepts/entityset.hh +++ b/dune/grid/concepts/entityset.hh @@ -5,48 +5,49 @@ #ifndef DUNE_GRID_CONCEPTS_ENTITY_SET_HH #define DUNE_GRID_CONCEPTS_ENTITY_SET_HH +#include + +#include +#include #include #include +#include +#include #include #include -#include -#include #include -#include namespace Dune::Concept { - namespace Impl { template - concept EntitySetEssentials = requires(ES es, Dune::GeometryType type, int codim) + concept EntitySetEssentials = std::copyable && requires(const ES es, Dune::GeometryType type, int codim) { typename ES::Traits; typename ES::ctype; requires IndexSet; requires Intersection; requires IntersectionIterator; - { ES::conforming } -> std::convertible_to< bool >; - { ES::dimension } -> std::convertible_to< int >; - { ES::dimensionworld } -> std::convertible_to< int >; - { es.grid() } -> std::convertible_to< const typename ES::Grid& >; - { es.indexSet() } -> std::convertible_to< const typename ES::IndexSet& >; - { es.size(codim) } -> std::convertible_to< int >; - { es.size(type) } -> std::convertible_to< int >; - { es.comm() } -> std::convertible_to< typename ES::CollectiveCommunication >; - { es.overlapSize(codim) } -> std::convertible_to< int >; - { es.ghostSize(codim) } -> std::convertible_to< int >; + { ES::conforming } -> std::convertible_to; + { ES::dimension } -> std::convertible_to; + { ES::dimensionworld } -> std::convertible_to; + { es.grid() } -> std::convertible_to; + { es.indexSet() } -> std::convertible_to; + { es.size(codim) } -> std::convertible_to; + { es.size(type) } -> std::convertible_to; + { es.comm() } -> std::convertible_to; + { es.overlapSize(codim) } -> std::convertible_to; + { es.ghostSize(codim) } -> std::convertible_to; - requires requires(Archetypes::CommDataHandle& handle, + requires requires(Archetypes::CommDataHandle& handle, InterfaceType iface, CommunicationDirection dir) { es.communicate(handle, iface, dir); }; - requires std::copy_constructible; }; -} +} // end namespace Impl /** * @brief Model of an entity set @@ -58,18 +59,18 @@ namespace Impl { * grid view. */ template -concept EntitySet = requires(ES es, Dune::GeometryType type, const typename ES::template Codim::Entity& entity) +concept EntitySet = Impl::EntitySetEssentials && requires(const ES es) { - requires Impl::EntitySetEssentials; - requires (codim != 0) || requires { - { es.ibegin(entity) } -> std::convertible_to< typename ES::IntersectionIterator>; - { es.iend(entity) } -> std::convertible_to< typename ES::IntersectionIterator>; + requires (codim != 0) || requires(const typename ES::template Codim::Entity& entity) + { + { es.ibegin(entity) } -> std::convertible_to; + { es.iend(entity) } -> std::convertible_to; }; requires Geometry::Geometry>; requires Geometry::LocalGeometry>; requires EntityIterator::Iterator>; - { es.template begin() } -> std::convertible_to< typename ES::template Codim::Iterator>; - { es.template end() } -> std::convertible_to< typename ES::template Codim::Iterator>; + { es.template begin() } -> std::convertible_to::Iterator>; + { es.template end() } -> std::convertible_to::Iterator>; }; } // end namespace Dune::Concept diff --git a/dune/grid/concepts/geometry.hh b/dune/grid/concepts/geometry.hh index 3a79975fb..2793528c9 100644 --- a/dune/grid/concepts/geometry.hh +++ b/dune/grid/concepts/geometry.hh @@ -5,6 +5,8 @@ #ifndef DUNE_GRID_CONCEPTS_GEOMETRY_HH #define DUNE_GRID_CONCEPTS_GEOMETRY_HH +#include + #include #include #include @@ -24,25 +26,25 @@ static_assert(ReferenceElement< Archetypes::ReferenceElement >); * @details Dune::Geometry is a template for this model */ template -concept Geometry = requires(const G& g, typename G::GlobalCoordinate global, typename G::LocalCoordinate local) +concept Geometry = requires(const G g, typename G::GlobalCoordinate global, typename G::LocalCoordinate local) { typename G::ctype; - { G::mydimension } -> std::convertible_to; - { G::coorddimension } -> std::convertible_to; - { g.type() } -> std::convertible_to; - { g.affine() } -> std::convertible_to; - { g.corners() } -> std::convertible_to; - { g.corner(/*i*/ int{}) } -> std::convertible_to; - { g.global(local) } -> std::convertible_to; - { g.local(global) } -> std::convertible_to; - { g.integrationElement(local) } -> std::convertible_to; - { g.volume() } -> std::convertible_to; - { g.center() } -> std::convertible_to; - { g.jacobian(local) } -> std::convertible_to; - { g.jacobianInverse(local) } -> std::convertible_to; - { g.jacobianTransposed(local) } -> std::convertible_to; - { g.jacobianInverseTransposed(local) } -> std::convertible_to; - { referenceElement(g) } -> ReferenceElement; + { G::mydimension } -> std::convertible_to; + { G::coorddimension } -> std::convertible_to; + { g.type() } -> std::convertible_to; + { g.affine() } -> std::convertible_to; + { g.corners() } -> std::convertible_to; + { g.corner(/*i*/ int{}) } -> std::convertible_to; + { g.global(local) } -> std::convertible_to; + { g.local(global) } -> std::convertible_to; + { g.integrationElement(local) } -> std::convertible_to; + { g.volume() } -> std::convertible_to; + { g.center() } -> std::convertible_to; + { g.jacobian(local) } -> std::convertible_to; + { g.jacobianInverse(local) } -> std::convertible_to; + { g.jacobianTransposed(local) } -> std::convertible_to; + { g.jacobianInverseTransposed(local) } -> std::convertible_to; + { referenceElement(g) } -> ReferenceElement; }; static_assert(Geometry< Archetypes::Geometry<2,3> >); diff --git a/dune/grid/concepts/grid.hh b/dune/grid/concepts/grid.hh index 73bff031a..7bc15e00f 100644 --- a/dune/grid/concepts/grid.hh +++ b/dune/grid/concepts/grid.hh @@ -5,22 +5,24 @@ #ifndef DUNE_GRID_CONCEPTS_GRID_HH #define DUNE_GRID_CONCEPTS_GRID_HH +#include +#include +#include +#include + +#include +#include +#include +#include #include #include -#include -#include #include -#include #include - +#include +#include +#include #include -#include - -#include - -#include -#include /*!@defgroup GridConcepts Grid Concepts * @{ @@ -30,40 +32,56 @@ */ namespace Dune::Concept { - namespace Impl { +namespace Impl { - template - concept GridCodim = requires(G g, const typename G::template Codim::EntitySeed& seed) + template, + class Interior = typename Traits::template Partition, + class IBorder = typename Traits::template Partition, + class Overlap = typename Traits::template Partition, + class OFront = typename Traits::template Partition, + class All = typename Traits::template Partition, + class Ghost = typename Traits::template Partition> + concept GridCodim = requires(const G cg, const typename Traits::EntitySeed& seed) { - requires Entity< typename G::template Codim::Entity>; - requires EntitySeed< typename G::template Codim::EntitySeed>; - requires Geometry< typename G::template Codim::Geometry>; - requires Geometry< typename G::template Codim::LocalGeometry>; - requires EntityIterator< typename G::template Codim::template Partition::LevelIterator>; - requires EntityIterator< typename G::template Codim::template Partition::LeafIterator>; - requires EntityIterator< typename G::template Codim::template Partition::LevelIterator>; - requires EntityIterator< typename G::template Codim::template Partition::LeafIterator>; - requires EntityIterator< typename G::template Codim::template Partition::LevelIterator>; - requires EntityIterator< typename G::template Codim::template Partition::LeafIterator>; - requires EntityIterator< typename G::template Codim::template Partition::LevelIterator>; - requires EntityIterator< typename G::template Codim::template Partition::LeafIterator>; - requires EntityIterator< typename G::template Codim::template Partition::LevelIterator>; - requires EntityIterator< typename G::template Codim::template Partition::LeafIterator>; - requires EntityIterator< typename G::template Codim::template Partition::LevelIterator>; - requires EntityIterator< typename G::template Codim::template Partition::LeafIterator>; - requires EntityIterator< typename G::template Codim::LevelIterator>; - requires EntityIterator< typename G::template Codim::LeafIterator>; - { g.entity(seed) } -> std::convertible_to::Entity >; + requires Geometry; + requires Geometry; + requires EntityIterator; + requires EntityIterator; + requires EntityIterator; + requires EntityIterator; + requires EntityIterator; + requires EntityIterator; + requires EntityIterator; + requires EntityIterator; + requires EntityIterator; + requires EntityIterator; + requires EntityIterator; + requires EntityIterator; + requires EntityIterator; + requires EntityIterator; + + requires Entity; + requires EntitySeed; + { cg.entity(seed) } -> std::convertible_to; + + requires (not Dune::Capabilities::canCommunicate::v) || + requires(G g, Archetypes::CommDataHandle& handle) + { + { g.loadBalance(handle) } -> std::convertible_to; + }; }; - template - concept AllGridCodims = requires(std::make_index_sequence codims) + template + concept AllGridCodims = requires(std::make_integer_sequence codims) { - [](std::index_sequence) + [](std::integer_sequence) requires (GridCodim &&...) {} (codims); }; -} + +} // end namespace Impl + /** * @brief Model of a grid @@ -71,52 +89,55 @@ namespace Dune::Concept { * @details Dune::Grid is a template for this model */ template -concept Grid = requires(G g, int level, int codim, int refCount, - Dune::GeometryType type, - const typename G::template Codim<0>::Entity& entity) +concept Grid = requires(const G cg, int level, int codim, Dune::GeometryType type) { + // static constants { G::dimension } -> std::convertible_to; { G::dimensionworld } -> std::convertible_to; - requires GridView< typename G::LeafGridView>; - requires GridView< typename G::LevelGridView>; - requires Intersection< typename G::LeafIntersection>; - requires Intersection< typename G::LevelIntersection>; - requires IntersectionIterator< typename G::LeafIntersectionIterator>; - requires IntersectionIterator< typename G::LevelIntersectionIterator>; - requires IndexSet< typename G::LevelIndexSet>; - requires IndexSet< typename G::LeafIndexSet>; - requires IdSet< typename G::GlobalIdSet>; - requires IdSet< typename G::LocalIdSet>; - requires std::is_same::value; - requires std::is_same::value; + + // type and concepts requirements + requires GridView; + requires GridView; + requires Intersection; + requires Intersection; + requires IntersectionIterator; + requires IntersectionIterator; + requires IndexSet; + requires IndexSet; + requires IdSet; + requires IdSet; + requires std::same_as; + requires std::same_as; requires Impl::AllGridCodims; typename G::ctype; typename G::HierarchicIterator; - { g.maxLevel() } -> std::convertible_to< int >; - { g.size(level, codim) } -> std::convertible_to< int >; - { g.size(codim) } -> std::convertible_to< int >; - { g.size(level, type) } -> std::convertible_to< int >; - { g.size(type) } -> std::convertible_to< int >; - { g.numBoundarySegments() } -> std::convertible_to< std::size_t >; - { g.levelGridView(level) } -> std::convertible_to< typename G::LevelGridView >; - { g.leafGridView() } -> std::convertible_to< typename G::LeafGridView >; - { g.globalIdSet() } -> std::convertible_to< const typename G::GlobalIdSet& >; - { g.localIdSet() } -> std::convertible_to< const typename G::LocalIdSet& >; - { g.levelIndexSet(level) } -> std::convertible_to< const typename G::LevelIndexSet& >; - { g.leafIndexSet() } -> std::convertible_to< const typename G::LeafIndexSet& >; - { g.mark(refCount,entity) } -> std::convertible_to< bool >; - { g.getMark(entity) } -> std::convertible_to< int >; - { g.preAdapt() } -> std::convertible_to< bool >; - { g.adapt() } -> std::convertible_to< bool >; - { g.comm() } -> std::convertible_to< typename G::CollectiveCommunication >; - { g.loadBalance() } -> std::convertible_to< bool >; - requires requires(Archetypes::CommDataHandle& handle, - InterfaceType iface, CommunicationDirection dir) + + // const methods + { cg.maxLevel() } -> std::convertible_to; + { cg.size(level, codim) } -> std::convertible_to; + { cg.size(codim) } -> std::convertible_to; + { cg.size(level, type) } -> std::convertible_to; + { cg.size(type) } -> std::convertible_to; + { cg.numBoundarySegments() } -> std::convertible_to; + { cg.levelGridView(level) } -> std::convertible_to; + { cg.leafGridView() } -> std::convertible_to; + { cg.globalIdSet() } -> std::convertible_to; + { cg.localIdSet() } -> std::convertible_to; + { cg.levelIndexSet(level) } -> std::convertible_to; + { cg.leafIndexSet() } -> std::convertible_to; + { cg.comm() } -> std::convertible_to; + + // mutable methods + requires requires(G g, int refCount, const typename G::template Codim<0>::Entity& entity) { - { g.loadBalance(handle) } -> std::convertible_to< bool >; + { g.mark(refCount,entity) } -> std::convertible_to; + { g.getMark(entity) } -> std::convertible_to; + { g.preAdapt() } -> std::convertible_to; + { g.adapt() } -> std::convertible_to; + { g.loadBalance() } -> std::convertible_to; + g.globalRefine(refCount); + g.postAdapt(); }; - g.globalRefine(refCount); - g.postAdapt(); }; } // end namespace Dune::Concept diff --git a/dune/grid/concepts/gridview.hh b/dune/grid/concepts/gridview.hh index a6d48c05a..af20d4fd5 100644 --- a/dune/grid/concepts/gridview.hh +++ b/dune/grid/concepts/gridview.hh @@ -5,27 +5,30 @@ #ifndef DUNE_GRID_CONCEPTS_GRIDVIEW_HH #define DUNE_GRID_CONCEPTS_GRIDVIEW_HH -#include +#include #include +#include +#include #include namespace Dune::Concept { - namespace Impl { - template - concept EntityPartitionSpan = requires(ES es) { - requires EntityIterator::template Partition::Iterator>; - { es.template begin() } -> std::convertible_to< typename ES::template Codim::template Partition::Iterator>; - { es.template end() } -> std::convertible_to< typename ES::template Codim::template Partition::Iterator>; + template::template Partition::Iterator> + concept EntityPartitionSpan = requires(const ES es) + { + requires EntityIterator; + { es.template begin() } -> std::convertible_to; + { es.template end() } -> std::convertible_to; }; template - concept EntitySetAllPartitions = requires(ES es) { - requires EntitySet; + concept EntitySetAllPartitions = EntitySet && requires + { requires EntityPartitionSpan; requires EntityPartitionSpan; requires EntityPartitionSpan; @@ -42,7 +45,7 @@ namespace Impl { requires (not Dune::Capabilities::hasEntityIterator::v) void requireEntitySetAllPartitions() {} -} +} // end namespace Impl /** * @brief Model of a grid view @@ -50,10 +53,8 @@ namespace Impl { * @details Dune::GridView is a template for this model */ template -concept GridView = requires(std::make_integer_sequence dims) +concept GridView = EntitySet && requires(std::make_integer_sequence dims) { - requires EntitySet; - [](std::integer_sequence) requires requires { (Impl::requireEntitySetAllPartitions(),...); }{} (dims); }; diff --git a/dune/grid/concepts/indexidset.hh b/dune/grid/concepts/indexidset.hh new file mode 100644 index 000000000..e152b9130 --- /dev/null +++ b/dune/grid/concepts/indexidset.hh @@ -0,0 +1,93 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifndef DUNE_GRID_CONCEPTS_INDEX_SET_HH +#define DUNE_GRID_CONCEPTS_INDEX_SET_HH + +#include +#include + +#include +#include +#include + +namespace Dune::Concept { +namespace Impl { + + template::Entity> + concept IndexSetEntityCodim = requires(const IS is, int i, unsigned int sub_codim, const E& entity) + { + requires Entity; + { is.template index(entity) } -> std::convertible_to; + { is.index(entity) } -> std::convertible_to; + { is.template subIndex(entity, i, sub_codim) } -> std::convertible_to; + { is.subIndex(entity, i, sub_codim) } -> std::convertible_to; + { is.contains(entity) } -> std::convertible_to; + }; + + template + concept AllIndexSetEntityCodims = requires(std::make_integer_sequence codims) + { + [](std::integer_sequence) + requires (IndexSetEntityCodim &&...) {} (codims); + }; + +} // end namespace Impl + +/** + * @brief Model of an index set + * @ingroup GridConcepts + * @details Dune::Grid::LevelIndexSet and Dune::Grid::LeafIndexSet are templates + * for this model + */ +template +concept IndexSet = requires(const IS is, Dune::GeometryType type, int sub_codim) +{ + { IS::dimension } -> std::convertible_to; + { is.types(sub_codim) } -> std::convertible_to; + { is.size(type) } -> std::convertible_to; + { is.size(sub_codim) } -> std::convertible_to; + requires std::integral; + typename IS::Types; + requires Impl::AllIndexSetEntityCodims; +}; + + +namespace Impl { + + template::Entity> + concept IdSetEntityCodim = requires(const IS is, const E& entity) + { + requires Entity; + { is.template id(entity) } -> std::convertible_to; + { is.id(entity) } -> std::convertible_to; + }; + + template + concept AllIdSetEntityCodims = requires(std::make_integer_sequence codims) + { + [](std::integer_sequence) + requires (IdSetEntityCodim &&...) {} (codims); + }; + +} // end namespace Impl + +/** + * @brief Model of an id set + * @ingroup GridConcepts + * @details Dune::Grid::GlobalIdSet and Dune::Grid::LocalIdSet are templates + * for this model + */ +template +concept IdSet = requires(const IS is, const typename IS::template Codim<0>::Entity& entity, int i, unsigned int codim) +{ + { is.subId(entity,i,codim) } -> std::convertible_to; + requires Impl::AllIdSetEntityCodims; +}; + +} // end namespace Dune::Concept + +#endif // DUNE_GRID_CONCEPTS_INDEX_SET_HH diff --git a/dune/grid/concepts/indexset.hh b/dune/grid/concepts/indexset.hh deleted file mode 100644 index b398ede0b..000000000 --- a/dune/grid/concepts/indexset.hh +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root -// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception -// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -// vi: set et ts=4 sw=2 sts=2: -#ifndef DUNE_GRID_CONCEPTS_INDEX_SET_HH -#define DUNE_GRID_CONCEPTS_INDEX_SET_HH - -#include - -#include - -#include - -#include - -namespace Dune::Concept { - -namespace Impl { - - template - concept IndexSetEntityCodim = requires(IS is, int i, unsigned int sub_codim, const typename IS::template Codim::Entity& entity) - { - requires Entity::Entity>; - { is.template index(entity) } -> std::convertible_to; - { is.index(entity) } -> std::convertible_to; - { is.template subIndex(entity, i, sub_codim ) } -> std::convertible_to; - { is.subIndex(entity, i, sub_codim ) } -> std::convertible_to; - { is.contains(entity) } -> std::convertible_to; - }; - - template - concept AllIndexSetEntityCodims = requires(std::make_index_sequence codims) - { - [](std::index_sequence) - requires (IndexSetEntityCodim &&...) {} (codims); - }; - -} - -/** - * @brief Model of an index set - * @ingroup GridConcepts - * @details Dune::Grid::LevelIndexSet and Dune::Grid::LeafIndexSet are templates - * for this model - */ -template -concept IndexSet = requires(IS is, Dune::GeometryType type, int sub_codim) -{ - { IS::dimension } -> std::convertible_to< int >; - { is.types(sub_codim) } -> std::convertible_to< typename IS::Types >; - { is.size(type) } -> std::convertible_to< typename IS::IndexType >; - { is.size(sub_codim) } -> std::convertible_to< typename IS::IndexType >; - requires std::is_integral::value; - requires (not std::is_copy_constructible::value); - requires (not std::is_copy_assignable::value); - typename IS::Types; - requires Impl::AllIndexSetEntityCodims; -}; - -namespace Impl { - - template - concept IdSetEntityCodim = requires(IS is, const typename IS::template Codim::Entity& entity) - { - requires Entity::Entity>; - { is.template id(entity) } -> std::convertible_to; - { is.id(entity) } -> std::convertible_to; - }; - - template - concept AllIdSetEntityCodims = requires(std::make_index_sequence codims) - { - [](std::index_sequence) - requires (IdSetEntityCodim &&...) {} (codims); - }; - -} - -/** - * @brief Model of an id set - * @ingroup GridConcepts - * @details Dune::Grid::GlobalIdSet and Dune::Grid::LocalIdSet are templates - * for this model - */ -template -concept IdSet = requires(IS is, const typename IS::template Codim<0>::Entity& entity, int i, unsigned int codim) -{ - { is.subId(entity,i,codim) } -> std::convertible_to; - requires Impl::AllIdSetEntityCodims; -}; - -} // end namespace Dune::Concept - -#endif // DUNE_GRID_CONCEPTS_INDEX_SET_HH diff --git a/dune/grid/concepts/intersection.hh b/dune/grid/concepts/intersection.hh index 65061a780..72e81089f 100644 --- a/dune/grid/concepts/intersection.hh +++ b/dune/grid/concepts/intersection.hh @@ -5,6 +5,10 @@ #ifndef DUNE_GRID_CONCEPTS_INTERSECTION_HH #define DUNE_GRID_CONCEPTS_INTERSECTION_HH +#include +#include + +#include #include #include @@ -16,37 +20,30 @@ namespace Dune::Concept { * @details Dune::Grid::Intersection is a template for this model */ template -concept Intersection = requires(I i, typename I::LocalCoordinate local) +concept Intersection = std::regular && requires(const I i, typename I::LocalCoordinate local) { requires EntityGeneral; requires Geometry; requires Geometry; typename I::ctype; - { I::mydimension } -> std::convertible_to; - { I::dimensionworld } -> std::convertible_to; - { i.boundary() } -> std::convertible_to; - { i.boundarySegmentIndex() } -> std::convertible_to; - { i.neighbor() } -> std::convertible_to; - { i.inside() } -> std::convertible_to; - { i.outside() } -> std::convertible_to; - { i.conforming() } -> std::convertible_to; - { i.geometryInInside() } -> std::convertible_to; - { i.geometryInOutside() } -> std::convertible_to; - { i.geometry() } -> std::convertible_to; - { i.type() } -> std::convertible_to; - { i.indexInInside() } -> std::convertible_to; - { i.indexInOutside() } -> std::convertible_to; - { i.outerNormal(local) } -> std::convertible_to; - { i.integrationOuterNormal(local) } -> std::convertible_to; - { i.unitOuterNormal(local) } -> std::convertible_to; - { i.centerUnitOuterNormal() } -> std::convertible_to; - { i==i } -> std::convertible_to; - { i!=i } -> std::convertible_to; - requires std::default_initializable; - requires std::copy_constructible; - requires std::move_constructible; - i = i; - i = std::move(i); + { I::mydimension } -> std::convertible_to; + { I::dimensionworld } -> std::convertible_to; + { i.boundary() } -> std::convertible_to; + { i.boundarySegmentIndex() } -> std::convertible_to; + { i.neighbor() } -> std::convertible_to; + { i.inside() } -> std::convertible_to; + { i.outside() } -> std::convertible_to; + { i.conforming() } -> std::convertible_to; + { i.geometryInInside() } -> std::convertible_to; + { i.geometryInOutside() } -> std::convertible_to; + { i.geometry() } -> std::convertible_to; + { i.type() } -> std::convertible_to; + { i.indexInInside() } -> std::convertible_to; + { i.indexInOutside() } -> std::convertible_to; + { i.outerNormal(local) } -> std::convertible_to; + { i.integrationOuterNormal(local) } -> std::convertible_to; + { i.unitOuterNormal(local) } -> std::convertible_to; + { i.centerUnitOuterNormal() } -> std::convertible_to; }; } // end namespace Dune::Concept diff --git a/dune/grid/concepts/intersectioniterator.hh b/dune/grid/concepts/intersectioniterator.hh index fff8b9e4a..966ed0eab 100644 --- a/dune/grid/concepts/intersectioniterator.hh +++ b/dune/grid/concepts/intersectioniterator.hh @@ -5,6 +5,9 @@ #ifndef DUNE_GRID_CONCEPTS_INTERSECTION_ITERATOR_HH #define DUNE_GRID_CONCEPTS_INTERSECTION_ITERATOR_HH +#include +#include + #include namespace Dune::Concept { @@ -15,11 +18,9 @@ namespace Dune::Concept { * @details Dune::IntersectionIterator is a template for this model */ template -concept IntersectionIterator = requires(It it) +concept IntersectionIterator = std::forward_iterator && std::default_initializable && requires { requires Intersection; - requires std::forward_iterator; - requires std::default_initializable; }; } // end namespace Dune::Concept diff --git a/dune/grid/concepts/messagebuffer.hh b/dune/grid/concepts/messagebuffer.hh index 8ce267f5f..a42d9f7d5 100644 --- a/dune/grid/concepts/messagebuffer.hh +++ b/dune/grid/concepts/messagebuffer.hh @@ -13,18 +13,15 @@ namespace Dune::Concept { * @brief Model of a message buffer * @ingroup GridConcepts */ -template -concept MessageBuffer = requires(MB mb, T& val) +template +concept MessageBuffer = requires(MB mb, DataType& data) { - mb.write(val); - mb.read(val); + mb.write(data); + mb.read(data); }; static_assert(Concept::MessageBuffer, unsigned char>); -} // namespace Archetypes - - } // end namespace Dune::Concept diff --git a/dune/grid/test/test-concepts.cc b/dune/grid/test/test-concepts.cc index 4cac2b0cb..de77b1cfc 100644 --- a/dune/grid/test/test-concepts.cc +++ b/dune/grid/test/test-concepts.cc @@ -19,7 +19,7 @@ #include #endif -#if HAVE_UG +#if HAVE_DUNE_UGGRID #include #endif @@ -42,8 +42,7 @@ int main ( int argc, char **argv ) static_assert(Dune::Concept::Grid< Dune::AlbertaGrid<3,3> >); #endif -#if HAVE_UG - static_assert(Dune::Concept::Grid< Dune::UGGrid<1> >); +#if HAVE_DUNE_UGGRID static_assert(Dune::Concept::Grid< Dune::UGGrid<2> >); static_assert(Dune::Concept::Grid< Dune::UGGrid<3> >); #endif -- GitLab From f8c3aabf0fc6c1b2fb50f68df79c572f6c750cc6 Mon Sep 17 00:00:00 2001 From: Santiago Ospina De Los Rios Date: Fri, 22 May 2020 03:52:49 +0200 Subject: [PATCH 7/7] Add concepts implementation to CHANGELOG --- CHANGELOG.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb01f55db..e38634f23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,15 +3,17 @@ SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception --> +## Changelog + - Provide `communicate()` method in `OneDGrid` and `IdentityGrid` +- Grid concepts are here! A `Grid` can now be inspected and also its components checked for valid + interfaces at compilation time using c++20 concepts. Note, this feature is still in development and + might be subject to changes. + # Master (will become release 2.9) - UGGrid is now thread safe on the grid view. - -- Grid concepts are here! A `Grid` can now be inspected and extended - at compilation time using concepts. - - The `Geometry` interface was extended by methods `jacobian(local)` and `jacobianInverse(local)` and corresponding typedefs `Jacobian` and `JacobianInverse`. All grid implementations need to provide the new interface. For transition, the methods and typedefs are default-implemented -- GitLab