Commit c3abfe0f authored by Robert K's avatar Robert K

[!62] Distributed boundary segments

Merge branch 'feature/distributed-boundary-segments' into 'master'

ref:extensions/dune-alugrid This MR implement the capability to distribute
boundary segment projections which was not possible before. This allows to
use, for example, 2nd order gmsh boundaries in parallel. This branch needs
[!325] in dune-grid to be merged.

See merge request [!62]

  [!325]: gitlab.dune-project.org/NoneNone/merge_requests/325
  [!62]: gitlab.dune-project.org/extensions/dune-alugrid/merge_requests/62
parents dfc4be44 9b7d588d
Pipeline #17611 passed with stage
in 42 minutes and 53 seconds
if("$ENV{TORTURE_TESTS}" STREQUAL "on")
set(ALUGRID_TORTURE_TESTS on CACHE BOOL "Enable Torture Tests")
message(STATUS "Enabling torture-tests")
else()
set(ALUGRID_TORTURE_TESTS off CACHE BOOL "Enable Torture Tests")
message(STATUS "Not enabling torture-tests")
endif()
......@@ -52,3 +52,6 @@ endif()
# check for phtreads
include(FindPThreads)
# torture tests for extended testing
include(AlugridTortureTests)
......@@ -39,10 +39,7 @@ namespace Dune
public:
//! type of boundary projection
typedef typename BaseType :: DuneBoundaryProjectionType DuneBoundaryProjectionType;
//! type of boundary projection
typedef typename BaseType :: DuneBoundaryProjectionVector DuneBoundaryProjectionVector;
typedef typename BaseType :: ALUGridVertexProjectionPairType ALUGridVertexProjectionPairType;
enum { dimension=BaseType::dimension, dimensionworld=BaseType::dimensionworld};
static const ALUGridRefinementType refinementType = refineType;
......@@ -70,10 +67,9 @@ namespace Dune
//! stdout.
ALUGrid(const std::string macroName,
const MPICommunicatorType mpiComm = BaseType::defaultCommunicator(),
const DuneBoundaryProjectionType* bndProject = 0,
const DuneBoundaryProjectionVector* bndVector = 0,
const ALUGridVertexProjectionPairType& bndPrj = ALUGridVertexProjectionPairType(),
const bool verb = true ) :
BaseType(macroName, mpiComm, bndProject, bndVector, refineType )
BaseType(macroName, mpiComm, bndPrj, refineType )
{
const bool verbose = verb && this->comm().rank() == 0;
if( verbose )
......@@ -105,11 +101,10 @@ namespace Dune
//! \param verb Whether to write a notice about grid creation to
//! stdout.
ALUGrid(const MPICommunicatorType mpiComm,
const DuneBoundaryProjectionType* bndProject ,
const DuneBoundaryProjectionVector* bndVector,
const ALUGridVertexProjectionPairType& bndPrj,
const std::string macroName,
const bool verb = true ) :
BaseType("", mpiComm, bndProject, bndVector, refineType )
BaseType("", mpiComm, bndPrj, refineType )
{
const bool verbose = verb && this->comm().rank() == 0;
if( verbose )
......@@ -125,10 +120,7 @@ namespace Dune
//! constructor creating empty grid, empty string creates empty grid
ALUGrid(const MPICommunicatorType mpiComm = BaseType::defaultCommunicator()) :
BaseType("", mpiComm,
(const DuneBoundaryProjectionType *) 0,
(const DuneBoundaryProjectionVector* ) 0,
refineType )
BaseType("", mpiComm, ALUGridVertexProjectionPairType(), refineType )
{
if(this->comm().rank() == 0)
{
......
......@@ -150,17 +150,17 @@ namespace Dune
int nlinks () const { return 0; }
GitterImplType *createALUGrid ( const std::string &macroName, ALU3DSPACE ProjectVertex *projection,
GitterImplType *createALUGrid ( const std::string &macroName, const ALU3DSPACE ProjectVertexPtrPair& projections,
const bool conformingRefinement )
{
GitterImplType* grid = ( macroName.empty() ) ?
new GitterImplType( dim ) : new GitterImplType ( dim, macroName.c_str(), projection );
new GitterImplType( dim ) : new GitterImplType ( dim, macroName.c_str(), projections );
// check whether conforming refinement should be enabled
checkForConformingRefinement( grid, conformingRefinement );
return grid ;
}
GitterImplType *createALUGrid ( std::istream& stream, ALU3DSPACE ProjectVertex *projection,
GitterImplType *createALUGrid ( std::istream& stream, const ALU3DSPACE ProjectVertexPtrPair& projection,
const bool conformingRefinement )
{
GitterImplType* grid = new GitterImplType ( dim, stream, projection );
......@@ -209,19 +209,19 @@ namespace Dune
int nlinks () const { return mpAccess_.sendLinks(); }
GitterImplType *createALUGrid ( const std::string &macroName, ALU3DSPACE ProjectVertex *projection,
GitterImplType *createALUGrid ( const std::string &macroName, const ALU3DSPACE ProjectVertexPtrPair& projections,
const bool conformingRefinement )
{
GitterImplType* grid = new GitterImplType( dim, macroName.c_str(), mpAccess_, projection );
GitterImplType* grid = new GitterImplType( dim, macroName.c_str(), mpAccess_, projections );
// check whether conforming refinement should be enabled
checkForConformingRefinement( grid, conformingRefinement );
return grid;
}
GitterImplType *createALUGrid ( std::istream& stream, ALU3DSPACE ProjectVertex *projection,
GitterImplType *createALUGrid ( std::istream& stream, const ALU3DSPACE ProjectVertexPtrPair& projections,
const bool conformingRefinement )
{
GitterImplType* grid = new GitterImplType ( dim, stream, mpAccess_, projection );
GitterImplType* grid = new GitterImplType ( dim, stream, mpAccess_, projections );
// check whether conforming refinement should be enabled
checkForConformingRefinement( grid, conformingRefinement );
return grid ;
......@@ -578,11 +578,13 @@ namespace Dune
//! \brief boundary projection type
typedef typename Traits::DuneBoundaryProjectionType DuneBoundaryProjectionType;
//! \brief boundary projection type
typedef typename Traits::DuneBoundaryProjectionVector DuneBoundaryProjectionVector;
//! type of ALUGrid Vertex Projection Interface
typedef ALU3DSPACE ProjectVertex ALUGridVertexProjectionType;
//! type of vertex projection
typedef ALU3DSPACE ProjectVertex ALUGridVertexProjectionType;
//! type of ALUGrid Vertex Projection Interface (shared_ptr)
typedef ALU3DSPACE ProjectVertexPtr ALUGridVertexProjectionPointerType;
typedef ALU3DSPACE ProjectVertexPtrPair ALUGridVertexProjectionPairType;
//! type of collective communication object
typedef typename Traits::CollectiveCommunication CollectiveCommunication;
......@@ -591,10 +593,6 @@ namespace Dune
typedef ALULevelCommunication< dim, dimworld, elType, Comm > LevelCommunication;
protected:
friend class ALUGridBoundaryProjection< ThisType, alu3d_ctype >;
// type of ALUGrid boundary projection wrapper
typedef ALUGridBoundaryProjection< ThisType, alu3d_ctype > ALUGridBoundaryProjectionType;
//! Type of the local id set
typedef typename GridFamily::LocalIdSetImp LocalIdSetImp;
......@@ -634,7 +632,7 @@ namespace Dune
typedef ALU3dGridCommunications< dim, dimworld, elType, Comm > Communications;
protected:
typedef ALU3dGridVertexList< Comm > VertexListType;
typedef ALU3dGridVertexList< Comm > VertexListType;
typedef ALU3dGridLeafVertexList< Comm > LeafVertexListType;
typedef DefaultBoundarySegmentIndexSet< ThisType > BoundarySegmentIndexSetType;
......@@ -644,12 +642,11 @@ namespace Dune
//! or given GridFile
ALU3dGrid ( const std::string &macroTriangFilename,
const MPICommunicatorType mpiComm,
const DuneBoundaryProjectionType *bndPrj,
const DuneBoundaryProjectionVector *bndVec,
const ALUGridVertexProjectionPairType& bndPrj,
const ALUGridRefinementType refinementType );
//! \brief Desctructor
virtual ~ALU3dGrid();
virtual ~ALU3dGrid() {}
//! \brief for grid identification
static inline std::string name ();
......@@ -862,6 +859,58 @@ namespace Dune
bool loadBalance ( GatherScatterType* lbData );
public:
/** \brief Set load balancing method and lower and upper bound for decision
on whether to load balance or not.
\note Possible choices of load balancing methods are:
\code
// no load balancing
NONE = 0
// collect all to rank 0
COLLECT = 1,
// assuming the elements to be ordered by a
// space filling curve approach
// here, the edges in the graph are neglected
// parallel version
ALUGRID_SpaceFillingCurveLinkage = 4,
// serial version that requires the whole graph to be avaiable
ALUGRID_SpaceFillingCurveSerialLinkage = 5,
// METIS method for graph partitioning (with linkage storage)
//METIS_PartGraphKwayLinkage = 6,
//METIS_PartGraphRecursiveLinkage = 7,
// ALU sfc without linkage
ALUGRID_SpaceFillingCurve = 9,
ALUGRID_SpaceFillingCurveSerial = 10,
// METIS method for graph partitioning
METIS_PartGraphKway = 11,
METIS_PartGraphRecursive = 12,
// ZOLTAN partitioning
ZOLTAN_LB_HSFC = 13 ,
ZOLTAN_LB_GraphPartitioning = 14 ,
ZOLTAN_LB_PARMETIS = 15
\endcode
*/
static void setLoadBalanceMethod( const int mthd,
const double ldbUnder = 0.0,
const double ldbOver = 1.2 )
{
using DataBase = ALU3DSPACE LoadBalancer::DataBase ;
if( mthd < int( DataBase::NONE ) && mthd > DataBase::ZOLTAN_LB_PARMETIS )
{
DUNE_THROW(InvalidStateException,"ALUGrid::setLoadBalanceMethod: wrong method passed, check documentation for correect values");
}
ALU3DSPACE ALUGridExternalParameters::setLoadBalanceParameters( mthd, ldbUnder, ldbOver );
}
/** \brief Calculates load of each process and repartition by using ALUGrid's default partitioning method.
The specific load balancing algorithm is selected from a file alugrid.cfg.
\return true if grid has changed
......@@ -1080,16 +1129,19 @@ namespace Dune
virtual GitterImplType *createALUGrid ( const std::string &macroName )
{
alugrid_assert ( communications_ );
return communications_->createALUGrid( macroName, vertexProjection(), conformingRefinement() );
return communications_->createALUGrid( macroName, vertexProjections(), conformingRefinement() );
}
virtual GitterImplType *createALUGrid ( std::istream& stream )
{
alugrid_assert ( communications_ );
return communications_->createALUGrid( stream, vertexProjection(), conformingRefinement() );
return communications_->createALUGrid( stream, vertexProjections(), conformingRefinement() );
}
ALUGridVertexProjectionType* vertexProjection() { return (ALUGridVertexProjectionType *) vertexProjection_.operator -> (); }
ALUGridVertexProjectionPairType vertexProjections() const
{
return vertexProjections_ ;
}
// return appropriate ALUGrid builder
virtual typename ALU3DSPACE Gitter::Geometric::BuilderIF &getBuilder () const
......@@ -1211,22 +1263,6 @@ namespace Dune
//! check whether macro grid has the right element type
void checkMacroGrid ();
//! return boudanry projection for given segment Id
const DuneBoundaryProjectionType* boundaryProjection(const int segmentId) const
{
if( bndPrj_ )
{
return bndPrj_;
}
else
{
// pointer can be zero (which is emulates the identity mapping then)
alugrid_assert ( bndVec_ );
alugrid_assert ( segmentId < (int) bndVec_->size() );
return (*bndVec_)[ segmentId ];
}
}
const Communications &communications () const
{
alugrid_assert ( communications_ );
......@@ -1316,14 +1352,10 @@ namespace Dune
// variable to ensure that postAdapt ist called after adapt
bool lockPostAdapt_;
// pointer to Dune boundary projection
const DuneBoundaryProjectionType* bndPrj_;
// pointer to Dune boundary projection
std::unique_ptr< const DuneBoundaryProjectionVector > bndVec_;
// boundary projection for vertices
std::unique_ptr< ALUGridBoundaryProjectionType > vertexProjection_ ;
// pair: first is globalProjection_ for boundaries
// second is surfaceProjection_ for manifolds
ALUGridVertexProjectionPairType vertexProjections_ ;
// pointer to communications object
std::unique_ptr< Communications > communications_;
......
......@@ -10,15 +10,12 @@
#include "alu3diterators_imp.cc"
#include "aluinline.hh"
// alu_inline might be defined differently
#define alu_inline_tmp alu_inline
namespace Dune
{
template< class Comm >
template< class GridType >
alu_inline_tmp
alu_inline
void ALU3dGridVertexList< Comm >::
setupVxList(const GridType & grid, int level)
{
......@@ -91,7 +88,7 @@ namespace Dune
template< class Comm >
template< class GridType >
alu_inline_tmp
alu_inline
void ALU3dGridLeafVertexList< Comm >::
setupVxList(const GridType & grid)
{
......@@ -176,7 +173,7 @@ namespace Dune
}
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp
alu_inline
void
ALU3dGrid< dim, dimworld, elType, Comm >::makeGeometries()
{
......@@ -203,7 +200,7 @@ namespace Dune
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp
alu_inline
const ALU3dGrid< dim, dimworld, elType, Comm > &
ALU3dGrid< dim, dimworld, elType, Comm >::operator= ( const ALU3dGrid< dim, dimworld, elType, Comm > &other )
{
......@@ -213,7 +210,7 @@ namespace Dune
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp
alu_inline
void ALU3dGrid< dim, dimworld, elType, Comm >::calcMaxLevel ()
{
// old fashioned way
......@@ -245,7 +242,7 @@ namespace Dune
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp bool ALU3dGrid< dim, dimworld, elType, Comm >
alu_inline bool ALU3dGrid< dim, dimworld, elType, Comm >
::writeMacroGrid ( const std::string path, const std::string name,
const ALU3DSPACE MacroFileHeader::Format format ) const
{
......@@ -266,7 +263,7 @@ namespace Dune
}
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp
alu_inline
void ALU3dGrid< dim, dimworld, elType, Comm >::
backup( std::ostream& stream, const ALU3DSPACE MacroFileHeader::Format format ) const
{
......@@ -275,7 +272,7 @@ namespace Dune
}
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp
alu_inline
void ALU3dGrid< dim, dimworld, elType, Comm >::restore( std::istream& stream )
{
// create new grid from stream
......@@ -303,7 +300,7 @@ namespace Dune
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp
alu_inline
void ALU3dGrid< dim, dimworld, elType, Comm >::checkMacroGridFile ( const std::string filename )
{
if(filename == "") return;
......@@ -342,7 +339,7 @@ namespace Dune
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp
alu_inline
void ALU3dGrid< dim, dimworld, elType, Comm >::checkMacroGrid ()
{
typedef typename ALU3dImplTraits< elType, Comm >::HElementType HElementType;
......@@ -362,7 +359,7 @@ namespace Dune
}
alu_inline_tmp
alu_inline
const char* elType2Name( ALU3dGridElementType elType )
{
switch( elType )
......@@ -375,7 +372,7 @@ namespace Dune
}
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp
alu_inline
void ALU3dGrid< dim, dimworld, elType, Comm >::finalizeGridCreation()
{
// distribute the grid
......@@ -393,7 +390,7 @@ namespace Dune
// load balance grid ( lbData might be a pointer to NULL )
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp bool ALU3dGrid< dim, dimworld, elType, Comm >::loadBalance( GatherScatterType* lbData )
alu_inline bool ALU3dGrid< dim, dimworld, elType, Comm >::loadBalance( GatherScatterType* lbData )
{
if( comm().size() <= 1 )
return false;
......@@ -428,7 +425,7 @@ namespace Dune
// post process grid
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp
alu_inline
void ALU3dGrid< dim, dimworld, elType, Comm >::postAdapt ()
{
if( lockPostAdapt_ )
......@@ -443,7 +440,7 @@ namespace Dune
// post process grid
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp
alu_inline
void ALU3dGrid< dim, dimworld, elType, Comm >::clearIsNewMarkers ()
{
// old fashioned way
......@@ -594,7 +591,6 @@ namespace Dune
#endif // #if COMPILE_ALUGRID_LIB
#undef alu_inline_tmp
} // end namespace Dune
#endif // end DUNE_ALUGRID_GRID_IMP_CC
......@@ -23,8 +23,7 @@ namespace Dune
inline ALU3dGrid< dim, dimworld, elType, Comm >
::ALU3dGrid ( const std::string &macroTriangFilename,
const MPICommunicatorType mpiComm,
const DuneBoundaryProjectionType *bndPrj,
const DuneBoundaryProjectionVector *bndVec,
const ALUGridVertexProjectionPairType& bndPrj,
const ALUGridRefinementType refinementType )
: mygrid_()
, maxlevel_( 0 )
......@@ -37,9 +36,7 @@ namespace Dune
, levelIndexVec_(1) , leafIndexSet_()
, sizeCache_ ()
, lockPostAdapt_( false )
, bndPrj_ ( bndPrj )
, bndVec_ ( (bndVec) ? (new DuneBoundaryProjectionVector( *bndVec )) : nullptr )
, vertexProjection_( (bndPrj || bndVec) ? new ALUGridBoundaryProjectionType( *this ) : nullptr )
, vertexProjections_( bndPrj )
, communications_( new Communications( mpiComm ) )
, refinementType_( refinementType )
{
......@@ -287,22 +284,6 @@ namespace Dune
}
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp
ALU3dGrid< dim, dimworld, elType, Comm >::~ALU3dGrid ()
{
if( bndVec_ )
{
const size_t bndSize = bndVec_->size();
for(size_t i=0; i<bndSize; ++i)
{
delete (*bndVec_)[i];
}
}
}
template< int dim, int dimworld, ALU3dGridElementType elType, class Comm >
alu_inline_tmp
int ALU3dGrid< dim, dimworld, elType, Comm >::size ( int level, int codim ) const
......
This diff is collapsed.
......@@ -44,9 +44,6 @@ namespace Dune
typedef typename Grid::MPICommunicatorType MPICommunicatorType;
//! \brief type of boundary projection class
typedef DuneBoundaryProjection< dimensionworld > DuneBoundaryProjectionType;
template< int codim >
struct Codim
{
......@@ -79,7 +76,11 @@ namespace Dune
"ALU3dGridFactory supports only grids containing "
"tetrahedrons or hexahedrons exclusively." );
//! \brief type of boundary projection class
typedef DuneBoundaryProjection< dimensionworld > DuneBoundaryProjectionType;
typedef Dune::BoundarySegmentWrapper< dimension, dimensionworld > BoundarySegmentWrapperType;
typedef ALUGridBoundaryProjection< Grid > ALUProjectionType;
static const unsigned int numCorners = EntityCount< elementType >::numVertices;
static const unsigned int numFaces = EntityCount< elementType >::numFaces;
......@@ -152,9 +153,10 @@ namespace Dune
private:
// return grid object
virtual Grid* createGridObj( BoundaryProjectionVector* bndProjections, const std::string& name ) const
virtual Grid* createGridObj( const std::string& name ) const
{
return new Grid( communicator_, globalProjection_, bndProjections , name, realGrid_ );
ALU3DSPACE ProjectVertexPtrPair pv = std::make_pair( globalProjection_, surfaceProjection_ );
return new Grid( communicator_, pv, name, realGrid_ );
}
protected:
......@@ -264,7 +266,7 @@ namespace Dune
*
* \param[in] bndProjection instance of an ALUGridBoundaryProjection projecting vertices to a curved
*/
virtual void insertBoundaryProjection ( const DuneBoundaryProjectionType& bndProjection, const bool projectInside = (dimension != dimensionworld) );
virtual void insertBoundaryProjection ( const DuneBoundaryProjectionType& bndProjection, const bool isSurfaceProjection = (dimension != dimensionworld) );
/** \brief add a face transformation (for periodic identification)
*
......@@ -401,8 +403,8 @@ namespace Dune
ElementVector elements_;
BoundaryIdMap boundaryIds_,insertionOrder_;
PeriodicBoundaryVector periodicBoundaries_;
bool projectInside_;
const DuneBoundaryProjectionType* globalProjection_ ;
ALU3DSPACE ProjectVertexPtr globalProjection_ ;
ALU3DSPACE ProjectVertexPtr surfaceProjection_ ;
BoundaryProjectionMap boundaryProjections_;
FaceTransformationVector faceTransformations_;
unsigned int numFacesInserted_;
......@@ -514,8 +516,8 @@ namespace Dune
:: ALU3dGridFactory ( const MPICommunicatorType &communicator,
bool removeGeneratedFile )
: rank_( ALU3dGridCommunications< ALUGrid::dimension, ALUGrid::dimensionworld, elementType, MPICommunicatorType >::getRank( communicator ) ),
projectInside_(false),
globalProjection_ ( 0 ),
surfaceProjection_ ( 0 ),
numFacesInserted_ ( 0 ),
realGrid_( true ),
allowGridGeneration_( rank_ == 0 ),
......@@ -523,7 +525,10 @@ namespace Dune
communicator_( communicator ),
curveType_( SpaceFillingCurveOrderingType :: DefaultCurve ),
markLongestEdge_( false )
{}
{
BoundarySegmentWrapperType::registerFactory();
ALUProjectionType::registerFactory();
}
template< class ALUGrid >
inline
......@@ -531,8 +536,8 @@ namespace Dune
:: ALU3dGridFactory ( const std::string &filename,
const MPICommunicatorType &communicator )
: rank_( ALU3dGridCommunications< ALUGrid::dimension, ALUGrid::dimensionworld, elementType, MPICommunicatorType >::getRank( communicator ) ),
projectInside_(false),
globalProjection_ ( 0 ),
surfaceProjection_ ( 0 ),
numFacesInserted_ ( 0 ),
realGrid_( true ),
allowGridGeneration_( rank_ == 0 ),
......@@ -540,7 +545,10 @@ namespace Dune
communicator_( communicator ),
curveType_( SpaceFillingCurveOrderingType :: DefaultCurve ),
markLongestEdge_( false )
{}
{
BoundarySegmentWrapperType::registerFactory();
ALUProjectionType::registerFactory();
}
template< class ALUGrid >
inline
......@@ -548,8 +556,8 @@ namespace Dune
:: ALU3dGridFactory ( const bool realGrid,
const MPICommunicatorType &communicator )
: rank_( ALU3dGridCommunications< ALUGrid::dimension, ALUGrid::dimensionworld, elementType, MPICommunicatorType >::getRank( communicator ) ),
projectInside_(false),
globalProjection_ ( 0 ),
surfaceProjection_ ( 0 ),
numFacesInserted_ ( 0 ),
realGrid_( realGrid ),
allowGridGeneration_( true ),
......@@ -557,7 +565,10 @@ namespace Dune
communicator_( communicator ),
curveType_( SpaceFillingCurveOrderingType :: DefaultCurve ),
markLongestEdge_( false )
{}
{
BoundarySegmentWrapperType::registerFactory();
ALUProjectionType::registerFactory();
}
template< class ALUGrid >
inline void ALU3dGridFactory< ALUGrid > ::
......
......@@ -258,7 +258,7 @@ namespace Dune
void print(std::ostream & out) const
{
out << "(" << getKey() << "," << nChild_ << "," << codimLevel_ << ")";
out << "AluGridID: (" << getKey() << "," << nChild_ << "," << codimLevel_ << ")";
}
inline friend std::size_t hash_value(const ALUGridId& arg)
......
......@@ -5,30 +5,50 @@ namespace Dune {
//! \brief ALUGrid boundary projection implementation
//! DuneBndProjection has to fulfil the DuneBoundaryProjection interface
template <class GridImp, class ctype = double >
class ALUGridBoundaryProjection
: public GridImp :: ALUGridVertexProjectionType
template < class GridImp, class ctype = double >
class ALUGridBoundaryProjection : public GridImp :: ALUGridVertexProjectionType
{
typedef typename GridImp :: ALUGridVertexProjectionType BaseType;
typedef ALUGridBoundaryProjection< GridImp, ctype > ThisType;
typedef GridImp GridType;
// type of double coordinate vector
typedef ctype coord_t[ 3 ];
protected:
//! reference to boundary projection implementation
const GridType& grid_;
typedef typename BaseType::BufferType BufferType;
public:
//! type of boundary projection
typedef typename GridType :: DuneBoundaryProjectionType DuneBoundaryProjectionType;
typedef std::unique_ptr< const DuneBoundaryProjectionType > DuneBoundaryProjectionPointerType;
// type of projection (i.e. integer identifier)
typedef typename BaseType :: ProjectionType ProjectionType;
using BaseType :: none;
using BaseType :: global;
using BaseType :: surface;
using BaseType :: segment;
protected:
DuneBoundaryProjectionPointerType projection_;
ProjectionType projectionType_;
public:
//! type of coordinate vector
typedef typename DuneBoundaryProjectionType :: CoordinateType CoordinateType;
//! constructor storing reference to boundary projection implementation
ALUGridBoundaryProjection(const GridType& grid)
: grid_( grid )
ALUGridBoundaryProjection( const DuneBoundaryProjectionType* ptr, const ProjectionType pt = BaseType::none )
: projection_( ptr ), projectionType_( (projection_) ? pt : BaseType::none )
{
}
ProjectionType projectionType() const { return projectionType_; }
//! (old) method projection vertices defaults to segment 0
int operator () (const coord_t &orig,
coord_t &prj) const
......@@ -41,21 +61,38 @@ namespace Dune {
const int segmentId,
coord_t &prj) const
{
// get boundary projection
const DuneBoundaryProjectionType* bndPrj =
grid_.boundaryProjection( segmentId );
// if pointer is zero we do nothing, i.e. identity mapping
if( bndPrj )
if( projection_ )
{
// call projection operator
reinterpret_cast<CoordinateType &> (* (&prj[0])) =
(*bndPrj)( reinterpret_cast<const CoordinateType &> (* (&orig[0])) );
(*projection_)( reinterpret_cast<const CoordinateType &> (* (&orig[0])) );
}
// return 1 for success
return 1;
}
void backup( BufferType& os ) const
{
assert( !projection_ ? (projectionType() == BaseType::none) : true );
// store whether projection is global (i.e. exists one on all cores)
if( !projection_ )
DUNE_THROW(InvalidStateException,"ALUGridBoundaryProjection::backup: pointer to projection is invalid");
projection_->toBuffer( os );
}
static void registerFactory()
{
BaseType :: setFactoryMethod( &factory );
}
static BaseType* factory( BufferType& os )
{
return new ThisType( DuneBoundaryProjectionType::restoreFromBuffer( os ).release(), segment );
}
};
} // end namespace Dune
......
......@@ -5,6 +5,7 @@
#include <vector>
#include <dune/common/version.hh>
#include <dune/common/to_unique_ptr.hh>
#include <dune/grid/common/gridfactory.hh>
#include <dune/grid/common/exceptions.hh>
......@@ -34,11 +35,17 @@ namespace Dune
protected:
typedef FromToGridFactory< Grid > This;
#if DUNE_VERSION_NEWER(DUNE_GRID, 2, 7)
typedef ToUniquePtr< Grid > GridPtrType;
#else
typedef Grid* GridPtrType;
#endif