Commit c7b26f0a authored by Praetorius, Simon's avatar Praetorius, Simon

cleanup of the code

parent 87233e85
#pragma once
#include <tuple>
#include <type_traits>
#include <utility>
namespace AMDiS
{
......@@ -10,13 +8,6 @@ namespace AMDiS
{
namespace Impl_
{
template <class Functor, class Tuple, std::size_t... I>
constexpr decltype(auto) apply_impl(Functor&& f, Tuple&& t, std::index_sequence<I...>)
{
using std::get;
return f(get<I>(std::forward<Tuple>(t))...);
}
template <class Functor, std::size_t I0, std::size_t... I>
constexpr decltype(auto) apply_indices_impl(Functor&& f, std::integral_constant<std::size_t, I0>, std::index_sequence<I...>)
{
......@@ -24,38 +15,11 @@ namespace AMDiS
}
} // namespace Impl_
template <class Functor, class Tuple>
constexpr decltype(auto) apply(Functor&& f, Tuple&& t)
{
return Impl_::apply_impl(std::forward<Functor>(f), std::forward<Tuple>(t),
std::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
}
template <class Functor, class... Args>
constexpr decltype(auto) apply_variadic(Functor&& f, Args&&... args)
{
return apply(std::forward<Functor>(f), std::forward_as_tuple(args...));
}
template <std::size_t N, class Functor>
constexpr decltype(auto) apply_indices(Functor&& f)
{
return Impl_::apply_indices_impl(std::forward<Functor>(f), std::integral_constant<std::size_t, 0>{},
std::make_index_sequence<N>{});
}
template <class Functor, std::size_t N>
constexpr decltype(auto) apply_indices(Functor&& f, std::integral_constant<std::size_t, N>)
{
return Impl_::apply_indices_impl(std::forward<Functor>(f), std::integral_constant<std::size_t, 0>{},
std::make_index_sequence<N>{});
}
template <class Functor, std::size_t I0, std::size_t I1>
constexpr decltype(auto) apply_indices(Functor&& f, std::integral_constant<std::size_t, I0>, std::integral_constant<std::size_t, I1>)
{
return Impl_::apply_indices_impl(std::forward<Functor>(f), std::integral_constant<std::size_t, I0>{},
std::make_index_sequence<I1-I0>{});
}
}
} // end namespace AMDiS
......@@ -5,5 +5,5 @@ install(FILES
GlobalBasisIdSet.hpp
Nodes.hpp
TupleUtilites.hpp
UniqueBorderPartitionDataHandle.hpp
UniqueBorderPartition.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/amg_error)
......@@ -3,7 +3,6 @@
#include <initializer_list>
#include <tuple>
#include <type_traits>
#include <utility>
namespace AMDiS
{
......@@ -15,12 +14,6 @@ namespace AMDiS
void ignored_evaluation(std::initializer_list<T>&&) { /* do nothing */ }
}
template <class Functor, class... Args>
constexpr void for_variadic(Functor&& f, Args&&... args)
{
Impl_::ignored_evaluation<int>({0, (f(std::forward<Args>(args)), 0)...});
}
template <std::size_t... I, class Tuple, class Functor>
constexpr void for_each(std::index_sequence<I...>, Tuple&& tuple, Functor&& f)
{
......@@ -41,18 +34,6 @@ namespace AMDiS
Impl_::ignored_evaluation<int>({0, (f(std::integral_constant<std::size_t, I0+I>{}), 0)...});
}
template <std::size_t I0, std::size_t I1, class Functor>
constexpr void for_range(std::integral_constant<std::size_t, I0> i0, std::integral_constant<std::size_t, I1> i1, Functor&& f)
{
Tools::for_range<I0>(std::make_index_sequence<std::size_t(I1-I0)>{}, std::forward<Functor>(f));
}
template <std::size_t N, class Functor>
constexpr void for_range(std::integral_constant<std::size_t, N>, Functor&& f)
{
Tools::for_range(std::make_index_sequence<N>{}, std::forward<Functor>(f));
}
template <std::size_t I0, std::size_t I1, class Functor>
constexpr void for_range(Functor&& f)
{
......
......@@ -49,7 +49,7 @@ namespace AMDiS
template <class PreBasis, class TP>
class NodeIdSet;
/// \brief PRovide global ids for all DOFs in a global basis
/// \brief Provide global ids for all DOFs in a global basis
/**
* A GlobalBasisIdSet provides and interface to retrieve unique IDs
* (over all partitions) for all DOFs in the basis. It is implemented
......@@ -68,7 +68,6 @@ namespace AMDiS
idSet.unbind();
}
* ```
*
**/
template <class GB>
class GlobalBasisIdSet
......@@ -198,7 +197,7 @@ namespace AMDiS
using GridView = typename PreBasis::GridView;
using size_type = std::size_t;
static_assert(Node::isLeaf, "Generic NodeIdSet implemented for LeafNodes only. Provide a spcialization for your node!");
static_assert(Node::isLeaf, "Generic NodeIdSet implemented for LeafNodes only. Provide a specialization for your node!");
private:
static constexpr int dim = GridView::template Codim<0>::Entity::mydimension;
......@@ -242,8 +241,10 @@ namespace AMDiS
if (!(c == GridView::dimension || c == 0 || idx == 0))
DUNE_THROW(Dune::NotImplemented, "Bases with more then one DoF per subentity are not supported.");
// DofId = {EntityId, LocalDofIndex}
it->first = {gridIdSet.subId(node_->element(), s, c), shift + idx};
// Dof-PartitionType
it->second = Dune::Hybrid::switchCases(std::make_index_sequence<dim+1>{}, c,
[&](auto codim) { return node_->element().template subEntity<codim>(s).partitionType(); },
[&]() {
......@@ -351,7 +352,7 @@ namespace AMDiS
public:
NodeIdSet(GridView const& gridView)
: idsTuple_(Tools::apply_indices<children>([&](auto... i) {
return std::make_tuple(SubNodeIdSet<VALUE(i)>(gridView)...);
return std::make_tuple(SubNodeIdSet<i>(gridView)...);
}))
{}
......@@ -360,7 +361,7 @@ namespace AMDiS
{
node_ = &node;
Tools::for_range<0,children>([&](auto i) {
std::get<VALUE(i)>(idsTuple_).bind(node.child(i));
std::get<i>(idsTuple_).bind(node.child(i));
});
}
......@@ -528,5 +529,4 @@ namespace AMDiS
size_type size_ = 0;
};
} // end namespace AMDiS
......@@ -2,36 +2,9 @@
#include <tuple>
#include <type_traits>
#include <utility>
#include <dune/common/hash.hh>
namespace AMDiS
{
namespace Impl
{
// Recursive template code derived from Matthieu M.
template <class Tuple, std::size_t I = std::tuple_size<Tuple>::value - 1>
struct HashTupleImpl
{
static void apply(size_t& seed, Tuple const& tuple)
{
HashTupleImpl<Tuple, I-1>::apply(seed, tuple);
Dune::hash_combine(seed, std::get<I>(tuple));
}
};
template <class Tuple>
struct HashTupleImpl<Tuple, 0>
{
static void apply(std::size_t& seed, Tuple const& tuple)
{
Dune::hash_combine(seed, std::get<0>(tuple));
}
};
} // end namespace Impl
template <class Tuple, template <class> class Map>
struct MapTuple;
......@@ -44,6 +17,7 @@ namespace AMDiS
using type = std::tuple<Map<T>...>;
};
template <class Indices, template <std::size_t> class Map>
struct IndexMapTuple;
......
......@@ -18,8 +18,8 @@ namespace AMDiS
* be communicated. Here we assign the entity to the processor with the lowest rank.
**/
template <class Grid>
class UniqueBorderPartitionDataHandle
: public Dune::CommDataHandleIF<UniqueBorderPartitionDataHandle<Grid>, int>
class UniqueBorderPartition
: public Dune::CommDataHandleIF<UniqueBorderPartition<Grid>, int>
{
using IdSet = typename Grid::GlobalIdSet;
using IdType = typename IdSet::IdType;
......@@ -40,9 +40,8 @@ namespace AMDiS
* NOTE: Since idSet is stored by reference it must not go out of scope
* until all calls to \ref gather and \ref scatter are finished.
**/
UniqueBorderPartitionDataHandle(int rank, EntitySet& borderEntities, IdSet const& idSet)
UniqueBorderPartition(int rank, IdSet const& idSet)
: myrank_(rank)
, borderEntities_(&borderEntities)
, idSet_(idSet)
{}
......@@ -61,7 +60,7 @@ namespace AMDiS
{
buff.write(myrank_);
// insert all border entities
borderEntities_->insert(idSet_.id(e));
borderEntities_.insert(idSet_.id(e));
}
template <class MessageBuffer, class Entity>
......@@ -74,12 +73,18 @@ namespace AMDiS
buff.read(rank);
// remove all border entities with rank < myrank_
if (rank < myrank_)
borderEntities_->erase(idSet_.id(e));
borderEntities_.erase(idSet_.id(e));
}
/// Returns whether id is in EntitySet
bool contains(IdType const& id) const
{
return borderEntities_.count(id) > 0;
}
private:
int myrank_;
EntitySet* borderEntities_;
mutable EntitySet borderEntities_;
IdSet const& idSet_;
};
......
#ifndef AMG_ERROR_HH
#define AMG_ERROR_HH
// add your classes here
#endif // AMG_ERROR_HH
......@@ -68,6 +68,7 @@ void assembleLocal(LocalView const& localView, ElementMatrix& elementMatrix, Ele
}
}
template <class Basis, class Matrix, class Vector, class F>
void assemble(Basis const& basis, Matrix& mat, Vector& vec, F const& f)
{
......@@ -93,14 +94,14 @@ void assemble(Basis const& basis, Matrix& mat, Vector& vec, F const& f)
}
}
template <class Basis, class Matrix, class Vector, class G>
void fillBoundaryCondition(Basis const& basis, Matrix& mat, Vector& sol, Vector& rhs, G const& g)
{
using Dune::Functions::forEachBoundaryDOF;
using LV = typename Basis::LocalView;
using IS = typename Basis::GridView::Intersection;
std::vector<bool> nodes(basis.dimension(), false);
forEachBoundaryDOF(basis, [&](int localIndex, LV const& localView, IS const& intersection) {
forEachBoundaryDOF(basis, [&](int localIndex, LV const& localView) {
nodes[localView.index(localIndex)] = true;
});
......@@ -117,6 +118,7 @@ void fillBoundaryCondition(Basis const& basis, Matrix& mat, Vector& sol, Vector&
Dune::Functions::interpolate(basis, sol, g, nodes);
}
template <class Basis, class Matrix>
void buildMatrixPattern(Basis const& basis, Matrix& mat)
{
......@@ -137,4 +139,4 @@ void buildMatrixPattern(Basis const& basis, Matrix& mat)
localView.unbind();
}
pattern.exportIdx(mat);
}
\ No newline at end of file
}
......@@ -6,19 +6,13 @@
#include <dune/istl/owneroverlapcopy.hh>
#include <dune/amg_error/GlobalBasisIdSet.hpp>
#include <dune/amg_error/UniqueBorderPartitionDataHandle.hpp>
#include <dune/amg_error/UniqueBorderPartition.hpp>
template <class Basis, class PIS>
void buildParallelIndexSet(Basis const& basis, PIS& pis)
{
using GridView = typename Basis::GridView;
using Grid = typename GridView::Grid;
using IdSet = typename Grid::GlobalIdSet;
using IdType = typename IdSet::IdType;
using EntitySet = std::set<IdType>;
using GlobalCommIdType = typename AMDiS::GlobalBasisIdSet<Basis>::IdType;
using LocalCommIdType = typename Basis::size_type;
using Attribute = typename Dune::OwnerOverlapCopyAttributeSet::AttributeSet;
using PType = Dune::PartitionType;
......@@ -27,15 +21,12 @@ void buildParallelIndexSet(Basis const& basis, PIS& pis)
auto const& gv = basis.gridView();
// make disjoint partition of border entities
EntitySet borderEntities;
using DataHandle = AMDiS::UniqueBorderPartitionDataHandle<Grid>;
DataHandle handle(gv.comm().rank(), borderEntities, gv.grid().globalIdSet());
gv.communicate(handle,
using DataHandle = AMDiS::UniqueBorderPartition<Grid>;
DataHandle borderEntities(gv.comm().rank(), gv.grid().globalIdSet());
gv.communicate(borderEntities,
Dune::InterfaceType::InteriorBorder_InteriorBorder_Interface,
Dune::CommunicationDirection::ForwardCommunication);
assert (gv.overlapSize(0) + gv.ghostSize(0) > 0);
auto lv = basis.localView();
AMDiS::GlobalBasisIdSet<Basis> dofIdSet(basis);
......@@ -46,26 +37,26 @@ void buildParallelIndexSet(Basis const& basis, PIS& pis)
dofIdSet.bind(e);
for (std::size_t i = 0; i < dofIdSet.size(); ++i)
{
LocalCommIdType localId = lv.index(i);
GlobalCommIdType globalId = dofIdSet.id(i);
auto localIndex = lv.index(i);
auto globalId = dofIdSet.id(i);
PType attribute = dofIdSet.partitionType(i);
switch (attribute)
{
case PType::InteriorEntity:
pis.add(globalId, LI(localId, Attribute::owner, true));
pis.add(globalId, LI(localIndex, Attribute::owner, false));
break;
case PType::BorderEntity:
if (borderEntities.count(dofIdSet.entityId(i)) == 1)
pis.add(globalId, LI(localId, Attribute::owner, true));
if (borderEntities.contains(dofIdSet.entityId(i)))
pis.add(globalId, LI(localIndex, Attribute::owner, true));
else
pis.add(globalId, LI(localId, Attribute::overlap, true));
pis.add(globalId, LI(localIndex, Attribute::overlap, true));
break;
case PType::OverlapEntity:
case PType::FrontEntity:
pis.add(globalId, LI(localId, Attribute::overlap, true));
pis.add(globalId, LI(localIndex, Attribute::overlap, true));
break;
case PType::GhostEntity:
pis.add(globalId, LI(localId, Attribute::copy, true));
pis.add(globalId, LI(localIndex, Attribute::copy, true));
break;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment