Skip to content
Snippets Groups Projects
Commit f6b03197 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Merge branch 'feature/unique_border_partition' into 'master'

unique border partition DataHandle

See merge request !68
parents 98678007 fc25d768
No related branches found
No related tags found
1 merge request!68unique border partition DataHandle
......@@ -4,4 +4,5 @@ install(FILES
LocalToGlobalAdapter.hpp
MacroGridFactory.hpp
QuadratureFactory.hpp
UniqueBorderPartition.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/utility)
#pragma once
#include <cassert>
#include <set>
#include <dune/common/unused.hh>
#include <dune/grid/common/datahandleif.hh>
namespace AMDiS
{
/// \brief Determine for each border entity which processor owns it
/**
* All entities must be uniquely owned by exactly one processor, but they can
* exist on multiple processors. For interior, overlap, and ghost entities the
* assignment is trivial: interior: owner, otherwise not owner.
*
* For border entities (codim != 0) the ownership is not known a priori and must
* 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>
{
using IdSet = typename Grid::GlobalIdSet;
using IdType = typename IdSet::IdType;
public:
using EntitySet = std::set<IdType>;
public:
/// \brief Construct a UniqueBorderPartition DataHandle to be used in a GridView
/// communicator.
/**
* \param rank The own processor rank
* \param borderEntities A set of entity ids filled with all border entities
* owned by this processor after communication.
* \param idSet The id set of entity ids to store in borderEntities,
* typically the grid globalIdSet.
*
* 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)
: myrank_(rank)
, borderEntities_(&borderEntities)
, idSet_(idSet)
{}
// Communicate all entities except for grid elements
bool contains(int /*dim*/, int codim) const { return codim != 0; }
// communicate exactly one integer, the rank
bool fixedSize(int /*dim*/, int /*codim*/) const { return true; }
// Always contains one int, the rank
template <class Entity>
std::size_t size(Entity const& e) const { return 1; }
template <class MessageBuffer, class Entity>
void gather(MessageBuffer& buff, Entity const& e) const
{
buff.write(myrank_);
// insert all border entities
borderEntities_->insert(idSet_.id(e));
}
template <class MessageBuffer, class Entity>
void scatter(MessageBuffer& buff, Entity const& e, std::size_t n)
{
DUNE_UNUSED_PARAMETER(n); // n == 1
assert(n == 1);
int rank = 0;
buff.read(rank);
// remove all border entities with rank < myrank_
if (rank < myrank_)
borderEntities_->erase(idSet_.id(e));
}
private:
int myrank_;
EntitySet* borderEntities_;
IdSet const& idSet_;
};
} // end namespace AMDiS
......@@ -97,3 +97,9 @@ dune_add_test(SOURCES TreeContainerTest.cpp
dune_add_test(SOURCES TypeTraitsTest.cpp
LINK_LIBRARIES amdis)
dune_add_test(SOURCES UniqueBorderPartitionTest.cpp
LINK_LIBRARIES amdis
MPI_RANKS 2
TIMEOUT 300
CMAKE_GUARD MPI_FOUND)
#include <amdis/AMDiS.hpp>
#include <amdis/utility/UniqueBorderPartition.hpp>
#include <dune/grid/yaspgrid.hh>
#include "Tests.hpp"
using namespace AMDiS;
template <class GridView>
void test(GridView const& gv)
{
using Grid = typename GridView::Grid;
using DataHandle = UniqueBorderPartitionDataHandle<Grid>;
using EntitySet = typename DataHandle::EntitySet;
EntitySet borderEntities;
DataHandle handle(gv.comm().rank(), borderEntities, gv.grid().globalIdSet());
gv.communicate(handle,
Dune::InterfaceType::InteriorBorder_InteriorBorder_Interface,
Dune::CommunicationDirection::ForwardCommunication);
msg("#borderEntities = {}", borderEntities.size());
}
int main(int argc, char** argv)
{
Environment env(argc, argv);
Dune::YaspGrid<2> grid1({1.0, 1.0}, {8,8}, 0, 0); // no overlap
Dune::YaspGrid<2> grid2({1.0, 1.0}, {8,8}, 0, 1); // overlap = 1
Dune::YaspGrid<3> grid3({1.0, 1.0, 1.0}, {8,8,8}, 0, 1); // overlap = 1
test(grid1.leafGridView());
test(grid2.leafGridView());
test(grid3.leafGridView());
return report_errors();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment