Liebe Gitlab-Nutzer, lieber Gitlab-Nutzer, es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Ein Anmelden über dieses erzeugt ein neues Konto. Das alte Konto ist über den Reiter "Standard" erreichbar. Die Administratoren

Dear Gitlab user, it is now possible to log in to our service using the ZIH login/LDAP. Logging in via this will create a new account. The old account can be accessed via the "Standard" tab. The administrators

Commit d6b07d78 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

resolved a merge conflict

parents 42349adf f1028dc2
set(modules "DuneMultimeshMacros.cmake")
install(FILES ${modules} DESTINATION ${DUNE_INSTALL_MODULEDIR})
install(FILES
DuneMultimeshMacros.cmake
CXXFeatures.cmake
DESTINATION ${DUNE_INSTALL_MODULEDIR})
include(CheckCXXSourceCompiles)
# support for C++17's variant implementation
check_cxx_source_compiles("
#include <variant>
int main()
{
std::variant<int,double> a;
a = 1;
a = 2.0;
bool positive = std::visit([](auto&& x) { return x > 0; }, a);
}
" DUNE_HAVE_CXX_VARIANT )
# File for module specific CMake tests.
include(CXXFeatures)
......@@ -40,6 +40,9 @@
/* Define to the revision of dune-multimesh */
#define DUNE_MULTIMESH_VERSION_REVISION @DUNE_MULTIMESH_VERSION_REVISION@
/* some detected compiler features may be used in this module */
#cmakedefine DUNE_HAVE_CXX_VARIANT 1
/* end dune-multimesh
Everything below here will be overwritten
*/
......@@ -12,23 +12,23 @@
namespace Dune
{
template <class GridImp>
template <class HostGrid>
class MultiEntity
: public std::vector<typename GridImp::HostGridType::Traits::template Codim<0>::Entity>
: public std::vector<typename HostGrid::Traits::template Codim<0>::Entity>
{
private:
using ctype = typename GridImp::ctype;
using ctype = typename HostGrid::ctype;
public:
enum { dimension = GridImp::dimension };
enum { dimension = HostGrid::dimension };
/// The type of a local geometry
using LocalGeometry = Dune::Geometry<dimension, dimension, const GridImp, MultiMeshLocalGeometry>;
using LocalGeometry = MultiMeshLocalGeometry<dimension, dimension, HostGrid>;
using EntitySeed = typename GridImp::Traits::template Codim<0>::EntitySeed;
using EntitySeed = MultiMeshEntitySeed<0, HostGrid>;
/// Entity in the host grid
using HostGridEntity = typename GridImp::HostGridType::Traits::template Codim<0>::Entity;
using HostGridEntity = typename HostGrid::Traits::template Codim<0>::Entity;
/// Containertype
using Super = std::vector<HostGridEntity>;
......@@ -39,15 +39,13 @@ namespace Dune
/// Return a local geometry of source in target
static LocalGeometry localGeometry (HostGridEntity const& source, HostGridEntity const& target)
{
using LocalGeometryImp = MultiMeshLocalGeometry<dimension, dimension, const GridImp>;
return LocalGeometry{LocalGeometryImp{source, target}};
return {source, target};
}
/// Return a local geometry of source_i'th entity in target_t'th entity
LocalGeometry localGeometry (std::size_t source_i, std::size_t target_i) const
{
using LocalGeometryImp = MultiMeshLocalGeometry<dimension, dimension, const GridImp>;
return LocalGeometry{LocalGeometryImp{(*this)[source_i], (*this)[target_i]}};
return {(*this)[source_i], (*this)[target_i]};
}
/// Return coordinate `sourceLocal` in coordinates of target entity
......@@ -73,8 +71,7 @@ namespace Dune
**/
EntitySeed seed (std::size_t entity_i) const
{
using EntitySeedImp = MultiMeshEntitySeed<0, const GridImp>;
return EntitySeedImp{(*this)[entity_i], entity_i};
return {(*this)[entity_i], entity_i};
}
/// Return the entity with maximal level
......
......@@ -9,23 +9,23 @@
namespace Dune
{
template <int mydim, int coorddim, class GridImp>
template <int mydim, int coorddim, class HostGrid>
class MultiMeshLocalGeometry
: public GeometryDefaultImplementation<mydim, coorddim, GridImp, MultiMeshLocalGeometry>
: public GeometryDefaultImplementation<mydim, coorddim, HostGrid, MultiMeshLocalGeometry>
{
private:
using ctype = typename GridImp::ctype;
using ctype = typename HostGrid::ctype;
public:
// The codimension of this entitypointer wrt the host grid
enum { codimension = GridImp::HostGridType::dimension - mydim };
enum { dimensionworld = GridImp::HostGridType::dimensionworld };
enum { codimension = HostGrid::dimension - mydim };
enum { dimensionworld = HostGrid::dimensionworld };
// select appropriate hostgrid geometry via typeswitch
using HostLocalGeometry = typename GridImp::HostGridType::Traits::template Codim<codimension>::LocalGeometry;
using HostLocalGeometry = typename HostGrid::Traits::template Codim<codimension>::LocalGeometry;
/// entity in the host grid
using HostGridEntity = typename GridImp::HostGridType::Traits::template Codim<codimension>::Entity;
using HostGridEntity = typename HostGrid::Traits::template Codim<codimension>::Entity;
//! type of jacobian transposed
using JacobianInverseTransposed = typename HostLocalGeometry::JacobianInverseTransposed;
......
......@@ -5,8 +5,10 @@
#include <numeric>
#include <stack>
#include <variant>
#include <dune/common/iteratorfacades.hh>
#include <dune/common/std/type_traits.hh>
#include <dune/grid/common/exceptions.hh>
#include <dune/grid/common/gridenums.hh>
......@@ -14,10 +16,15 @@
namespace Dune
{
namespace tag
{
struct with_gridview {};
}
/** \brief Iterator over all entities of a given codimension and level of a grid.
* \ingroup MultiMesh
*/
template <int codim, PartitionIteratorType pitype, class GridImp>
template <int codim, PartitionIteratorType pitype, class HostGrid>
class MultiMeshIterator
{
public:
......@@ -35,18 +42,20 @@ namespace Dune
// Implemented for codim 0 entities only
template <PartitionIteratorType pitype, class GridImp>
class MultiMeshIterator<0, pitype, GridImp>
: public ForwardIteratorFacade<MultiMeshIterator<0,pitype,GridImp>,
MultiEntity<GridImp>,
MultiEntity<GridImp> const&>
template <PartitionIteratorType pitype, class HostGrid>
class MultiMeshIterator<0, pitype, HostGrid>
: public ForwardIteratorFacade<MultiMeshIterator<0,pitype,HostGrid>,
MultiEntity<HostGrid>,
MultiEntity<HostGrid> const&>
{
private:
// LevelIterator to the equivalent entity in the host grid
using HostGridLevelIterator =
typename GridImp::HostGridType::template Codim<0>::template Partition<pitype>::LevelIterator;
typename HostGrid::template Codim<0>::template Partition<pitype>::LevelIterator;
using HostEntity = typename GridImp::HostGridType::template Codim<0>::Entity;
using HostEntity = typename HostGrid::template Codim<0>::Entity;
using EntityTest = std::function<bool(HostEntity)>;
struct EntityStackEntry
{
......@@ -88,21 +97,23 @@ namespace Dune
public:
/// Constructor. Stores a pointer to the grid
explicit MultiMeshIterator (const GridImp* multiMesh, int level)
: multiMesh_(multiMesh)
, incrementAllowed_(multiMesh->size(), true)
, level_(level)
template <class GridImp>
MultiMeshIterator (const GridImp* multiMesh, int level)
: incrementAllowed_(multiMesh->size(), true)
, contains_(multiMesh->size(), EntityTest{[level](const HostEntity& entity) { return entity.level() == level; }})
, maxLevel_(multiMesh->size(), level)
, multiEntity_(multiMesh->size())
{
for (auto const& grid : multiMesh_->grids_) {
for (auto const& grid : multiMesh->grids_) {
macroIterators_.push_back(grid->levelGridView(0).template begin<0,pitype>());
macroEndIterators_.push_back(grid->levelGridView(0).template end<0,pitype>());
}
// go to first leaf entity on all grids
entityStacks_.reserve(multiMesh_->size());
for (std::size_t i = 0; i < multiMesh_->size(); ++i) {
entityStacks_.emplace_back((*multiMesh_)[i].maxLevel());
entityStacks_.reserve(multiMesh->size());
for (std::size_t i = 0; i < multiMesh->size(); ++i) {
maxLevel_[i] = (*multiMesh)[i].maxLevel();
entityStacks_.emplace_back((*multiMesh)[i].maxLevel());
initialIncrement(i);
}
}
......@@ -112,26 +123,84 @@ namespace Dune
* \param multiMesh Pointer to grid instance
* \param endDummy Here only to distinguish it from the other constructor
*/
template <class GridImp>
MultiMeshIterator (const GridImp* multiMesh, int level, bool endDummy)
: multiMesh_(multiMesh)
, level_(level)
{
for (auto const& grid : multiMesh_->grids_) {
for (auto const& grid : multiMesh->grids_)
macroIterators_.push_back(grid->levelGridView(0).template end<0,pitype>());
macroEndIterators_.push_back(grid->levelGridView(0).template end<0,pitype>());
}
}
/// Constructor which create the leaf-iterator
template <class GridImp>
MultiMeshIterator (const GridImp* multiMesh)
: MultiMeshIterator{multiMesh, -1}
{}
/// Constructor which create the end leaf-iterator
template <class GridImp>
MultiMeshIterator (const GridImp* multiMesh, bool endDummy)
: MultiMeshIterator{multiMesh, -1, endDummy}
{}
template <class... GridViews,
std::enable_if_t<not Std::disjunction<std::is_same<GridViews,bool>...>::value, int> = 0>
MultiMeshIterator (tag::with_gridview, GridViews const&... gridViews)
: incrementAllowed_(sizeof...(GridViews), true)
, maxLevel_{gridViews.grid().maxLevel()...}
, multiEntity_(sizeof...(GridViews))
, macroIterators_{gridViews.grid().levelGridView(0).template begin<0,pitype>()...}
, macroEndIterators_{gridViews.grid().levelGridView(0).template end<0,pitype>()...}
, entityStacks_{EntityStack{gridViews.grid().maxLevel()}...}
{
contains_.reserve(sizeof...(GridViews));
Hybrid::forEach(std::forward_as_tuple(gridViews...), [this](auto const& gv) {
contains_.emplace_back([gv](const HostEntity& entity) { return gv.contains(entity); });
});
for (std::size_t i = 0; i < sizeof...(GridViews); ++i)
initialIncrement(i);
}
template <class... GridViews>
MultiMeshIterator (tag::with_gridview, bool endDummy, GridViews const&... gridViews)
: macroIterators_{gridViews.grid().levelGridView(0).template end<0,pitype>()...}
{}
#if DUNE_HAVE_CXX_VARIANT
template <class... GV>
MultiMeshIterator (const std::vector<std::variant<GV...>>& gridViews)
: incrementAllowed_(gridViews.size(), true)
, multiEntity_(gridViews.size())
{
contains_.reserve(gridViews.size());
entityStacks_.reserve(gridViews.size());
maxLevel_.reserve(gridViews.size());
for (auto const& gvs : gridViews) {
macroIterators_.push_back(std::visit([](auto const& gv) {
return gv.grid().levelGridView(0).template begin<0,pitype>(); }, gvs));
macroEndIterators_.push_back(std::visit([](auto const& gv) {
return gv.grid().levelGridView(0).template end<0,pitype>(); }, gvs));
contains_.emplace_back(std::visit([](auto const& gv) {
return EntityTest{[gv](const HostEntity& entity) { return gv.contains(entity); }}; }, gvs));
maxLevel_.push_back(std::visit([](auto const& gv) { return gv.grid().maxLevel(); }, gvs));
entityStacks_.emplace_back(std::visit([](auto const& gv) { return gv.grid().maxLevel(); }, gvs));
}
// go to first leaf entity on all grids
for (std::size_t i = 0; i < entityStacks_.size(); ++i)
initialIncrement(i);
}
template <class... GV>
MultiMeshIterator (const std::vector<std::variant<GV...>>& gridViews, bool endDummy)
{
for (auto const& gvs : gridViews) {
macroIterators_.push_back(std::visit([](auto const& gv) {
return gv.grid().levelGridView(0).template end<0,pitype>(); }, gvs));
}
}
#endif
/// prefix increment
void increment ()
......@@ -146,7 +215,7 @@ namespace Dune
}
/// dereferencing
MultiEntity<GridImp> const& dereference () const
MultiEntity<HostGrid> const& dereference () const
{
// update entries in multiEntity that have changed
for (std::size_t i = 0; i < entityStacks_.size(); ++i) {
......@@ -189,10 +258,10 @@ namespace Dune
}
// 3. go down in tree until leaf entity
for (auto child = dereference(i); !entityTest(child);
for (auto child = dereference(i); !entityTest(i,child);
child = dereference(i)) {
entityStack.emplace(child);
assert( entityStack.size() <= (*multiMesh_)[i].maxLevel() );
assert( entityStack.size() <= maxLevel_[i] );
}
}
......@@ -218,10 +287,10 @@ namespace Dune
return;
// 2. go down in tree until leaf entity
for (auto child = dereference(i); !entityTest(child);
for (auto child = dereference(i); !entityTest(i,child);
child = dereference(i)) {
entityStack.emplace(child);
assert( entityStack.size() <= (*multiMesh_)[i].maxLevel() );
assert( entityStack.size() <= maxLevel_[i] );
}
}
......@@ -236,24 +305,35 @@ namespace Dune
}
}
bool entityTest (HostEntity const& entity)
bool entityTest (std::size_t i, HostEntity const& entity) const
{
return entity.level() == level_ || entity.isLeaf() || !entity.isRegular();
return contains_[i](entity) || entity.isLeaf() || !entity.isRegular();
}
private:
const GridImp* multiMesh_;
std::vector<bool> incrementAllowed_;
std::vector<EntityTest> contains_;
std::vector<int> maxLevel_;
mutable MultiEntity<HostGrid> multiEntity_;
std::vector<HostGridLevelIterator> macroIterators_;
std::vector<HostGridLevelIterator> macroEndIterators_;
std::vector<EntityStack> entityStacks_;
std::vector<bool> incrementAllowed_;
int level_ = -1;
mutable MultiEntity<GridImp> multiEntity_;
};
template <class> class MultiMesh;
template <class... GridViews>
inline auto multi_elements(GridViews const&... gridViews)
{
using GridView0 = std::tuple_element_t<0,std::tuple<GridViews...>>;
using Iterator = MultiMeshIterator<0,All_Partition,typename GridView0::Grid>;
using Range = IteratorRange<Iterator>;
return Range{ Iterator{tag::with_gridview{}, gridViews...},
Iterator{tag::with_gridview{}, true, gridViews...} };
}
} // end namespace Dune
#endif // DUNE_MULTIMESH_ITERATOR_HH
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_MULTI_GRIDVIEW_HH
#define DUNE_MULTI_GRIDVIEW_HH
#if ! DUNE_HAVE_CXX_VARIANT
#error "Require C++17 variant!"
#endif
#include <variant>
#include <dune/common/typetraits.hh>
#include <dune/common/exceptions.hh>
#include <dune/common/std/type_traits.hh>
#include <dune/grid/common/capabilities.hh>
#include <dune/grid/common/gridview.hh>
#include "mmiterator.hh"
#include "multiindexset.hh"
namespace Dune
{
// forward declaration
template <class HostGrid>
class MultiGridView;
template <class HostGrid>
struct MultiGridViewTraits
{
using Grid = typename std::remove_const<HostGrid>::type;
using IndexSet = MultiIndexSet<HostGrid>;
using Intersection = std::variant<
typename HostGrid::Traits::LeafIntersection, typename HostGrid::Traits::LevelIntersection>;
using IntersectionIterator = std::variant<
typename HostGrid::Traits::LeafIntersectionIterator, typename HostGrid::Traits::LevelIntersectionIterator>;
using CollectiveCommunication = typename HostGrid::Traits::CollectiveCommunication;
template <int cd>
struct Codim
{
using Entity = typename Grid::Traits::template Codim<cd>::Entity;
using Geometry = typename Grid::template Codim<cd>::Geometry;
using LocalGeometry = typename Grid::template Codim<cd>::LocalGeometry;
template <PartitionIteratorType pit>
struct Partition
{
using Iterator = MultiMeshIterator<cd,pit,HostGrid>;
};
};
enum { conforming = Capabilities::isLevelwiseConforming<HostGrid>::v };
};
template <class HostGrid>
class MultiGridView
{
public:
using Traits = MultiGridViewTraits<HostGrid>;
/// The MultiMesh GridType
using Grid = typename Traits::Grid;
using GridViewTypes = std::variant<typename HostGrid::LeafGridView, typename HostGrid::LevelGridView>;
using IndexSet = typename Traits::IndexSet;
using IndexSetTypes = typename IndexSet::IndexSetTypes;
using IntersectionIterator = typename Traits::IntersectionIterator;
using CollectiveCommunication = typename Traits::CollectiveCommunication;
template <class GV>
using IsGridView = Std::disjunction<
std::is_same<std::decay_t<GV>,typename HostGrid::LeafGridView>,
std::is_same<std::decay_t<GV>,typename HostGrid::LevelGridView> >;
template <int cd>
struct Codim : public Traits::template Codim<cd> {};
enum { dimension = HostGrid::dimension };
enum { dimensionworld = HostGrid::dimensionworld };
enum { conforming = Traits::conforming };
public:
/// Constructor.
template <class... GridViews,
std::enable_if_t<Std::conjunction<IsGridView<GridViews>...>::value, int> = 0>
MultiGridView (GridViews&&... gridViews)
: gridViews_{std::forward<GridViews>(gridViews)...}
{}
template <class GridView,
std::enable_if_t<IsGridView<GridView>::value, int> = 0>
MultiGridView (const std::vector<GridView>& gridViews)
: gridViews_(gridViews.begin(), gridViews.end())
{}
template <class Iter,
std::enable_if_t<IsGridView<typename std::iterator_traits<Iter>::value_type>::value, int> = 0>
MultiGridView (Iter first, Iter last)
: gridViews_(first, last)
{}
template <class Iter,
std::enable_if_t<IsGridView<typename std::iterator_traits<Iter>::value_type>::value, int> = 0>
MultiGridView (const IteratorRange<Iter>& gridViews)
: gridViews_(gridViews.begin(), gridViews.end())
{}
/// Obtain a const reference to the underlying hierarchic grid
const HostGrid& grid (std::size_t idx) const
{
return std::visit([](auto const& gv) { return gv.grid(); }, gridViews_[idx]);
}
/// Obtain the level-indexSet
// NOTE: IndexSet is one of {LeafIndexSet, LevelIndexSet}
// NOTE: do not return a reference, but a reference wrapper
IndexSet indexSet (std::size_t idx) const
{
return std::visit([](auto const& gv) -> IndexSetTypes { return &gv.indexSet(); }, gridViews_[idx]);
}
/// Obtain number of entities in a given codimension
int size (std::size_t idx, int codim) const
{
return std::visit([codim](auto const& gv) { return gv.size(codim); }, gridViews_[idx]);
}
/// Obtain number of entities with a given geometry type
int size (std::size_t idx, const GeometryType& type) const
{
return std::visit([&type](auto const& gv) { return gv.size(type); }, gridViews_[idx]);
}
/// Obtain begin iterator for this view
template <int cd, PartitionIteratorType pit = All_Partition>
typename Codim<cd>::template Partition<pit>::Iterator begin () const
{
static_assert(cd == 0, "Implemented for codim == 0 only");
return MultiMeshIterator<cd,pit,HostGrid>(gridViews_);
}
/// Obtain end iterator for this view
template <int cd, PartitionIteratorType pit = All_Partition>
typename Codim<cd>::template Partition<pit>::Iterator end () const
{
static_assert(cd == 0, "Implemented for codim == 0 only");
return MultiMeshIterator<cd,pit,HostGrid>(gridViews_, true);
}
/// Obtain begin intersection iterator with respect to this view
// NOTE: IntersectionIterator is one of {LeafIntersectionIterator, LevelIntersectionIterator}
IntersectionIterator ibegin (std::size_t idx, const typename Codim<0>::Entity& entity) const
{
using II = IntersectionIterator;
return std::visit([&entity](auto const& gv) -> II { return gv.ibegin(entity); }, gridViews_[idx]);
}
/// Obtain end intersection iterator with respect to this view
// NOTE: IntersectionIterator is one of {LeafIntersectionIterator, LevelIntersectionIterator}
IntersectionIterator iend (std::size_t idx, const typename Codim<0>::Entity& entity) const
{
using II = IntersectionIterator;
return std::visit([&entity](auto const& gv) -> II { return gv.iend(entity); }, gridViews_[idx]);
}
/// Obtain collective communication object
const CollectiveCommunication& comm (std::size_t idx) const
{
return std::visit([](auto const& gv) -> const auto& { return gv.comm(); }, gridViews_[idx]);
}
/// Return size of the overlap region for a given codim on the grid view.
int overlapSize (std::size_t idx, int codim) const
{
return std::visit([codim](auto const& gv) { return gv.overlapSize(codim); }, gridViews_[idx]);
}
/// Return size of the ghost region for a given codim on the grid view.
int ghostSize (std::size_t idx, int codim) const
{
return std::visit([codim](auto const& gv) { return gv.ghostSize(codim); }, gridViews_[idx]);
}
/// Communicate data on this view
template <class DataHandleImp, class DataType>
void communicate (std::size_t idx,
CommDataHandleIF<DataHandleImp, DataType>& data,
InterfaceType iftype,
CommunicationDirection dir) const
{
std::visit([&data,iftype,dir](auto const& gv) { gv.communicate(data,iftype,dir); }, gridViews_[idx]);
}
private:
std::vector<GridViewTypes> gridViews_;
};
} // end namespace Dune
#endif // DUNE_MULTI_GRIDVIEW_HH
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_MULTI_INDEXSET_HH