1#ifndef DUNE_ALUGRID_STRUCTUREDGRIDFACTORY_HH
2#define DUNE_ALUGRID_STRUCTUREDGRIDFACTORY_HH
17#include <dune/grid/common/exceptions.hh>
19#include <dune/alugrid/common/alugrid_assert.hh>
20#include <dune/alugrid/common/declaration.hh>
22#include <dune/alugrid/common/hsfc.hh>
25#include <dune/grid/io/file/dgfparser/dgfyasp.hh>
33 template<
class Gr
id >
34 class StructuredGridFactory;
41 template<
int dim,
int dimworld, ALUGr
idElementType eltype, ALUGr
idRefinementType refineType,
class Comm >
42 class StructuredGridFactory< ALUGrid< dim, dimworld, eltype, refineType, Comm > >
45 typedef ALUGrid< dim, dimworld, eltype, refineType, Comm > Grid;
46#if DUNE_VERSION_NEWER(DUNE_GRID, 2, 6)
47 typedef std::unique_ptr< Grid > SharedPtrType;
54 typedef StructuredGridFactory< Grid > This;
59 template<
class GV, PartitionIteratorType pitype,
class IS =
typename GV::IndexSet >
60 class SimplePartitioner
62 typedef SimplePartitioner< GV, pitype, IS > This;
75 typedef typename Grid::template Codim< 0 >::Entity Element;
77 typedef typename Element::Geometry::GlobalCoordinate VertexType;
80 typedef Dune :: Communication< typename MPIHelper :: MPICommunicator > Communication ;
82#ifdef USE_ALUGRID_SFC_ORDERING
83 typedef SpaceFillingCurveOrdering< VertexType > SpaceFillingCurveOrderingType;
87 SimplePartitioner (
const GridView &gridView,
const Communication& comm,
88 const VertexType& lowerLeft,
const VertexType& upperRight )
90 gridView_( gridView ),
91 indexSet_( gridView_.indexSet() ),
92 pSize_( comm_.size() ),
93 elementCuts_( pSize_, -1 ),
94#ifdef USE_ALUGRID_SFC_ORDERING
95 sfc_( SpaceFillingCurveOrderingType::ZCurve, lowerLeft, upperRight, comm_ ),
99#ifdef USE_ALUGRID_SFC_ORDERING
100 const auto end = gridView_.template end< 0 > ();
101 for(
auto it = gridView_.template begin< 0 > (); it != end; ++it )
103 VertexType center = (*it).geometry().center();
105 const double hidx = sfc_.index( center );
106 maxIndex_ = std::max( maxIndex_, hidx );
110 maxIndex_ /= indexSet_.size( 0 );
114 calculateElementCuts();
118 template<
class Entity >
119 double index(
const Entity &entity )
const
122#ifdef USE_ALUGRID_SFC_ORDERING
124 VertexType center = entity.geometry().center();
126 return sfc_.index( center );
128 return double(indexSet_.index( entity ));
132 template<
class Entity >
133 int rank(
const Entity &entity )
const
136#ifdef USE_ALUGRID_SFC_ORDERING
138 VertexType center = entity.geometry().center();
140 const double hidx = sfc_.index( center );
142 const long int index = (hidx / maxIndex_);
145 const long int index = indexSet_.index( entity );
147 return rank( index );
151 int rank(
long int index )
const
153 if( index < elementCuts_[ 0 ] )
return 0;
154 for(
int p=1; p<pSize_; ++p )
156 if( index >= elementCuts_[ p-1 ] && index < elementCuts_[ p ] )
162 void calculateElementCuts()
164 const size_t nElements = indexSet_.size( 0 );
167 const int nRanks = pSize_;
170 const size_t minPerProc = (double(nElements) / double( nRanks ));
171 size_t maxPerProc = minPerProc ;
172 if( nElements % nRanks != 0 )
177 double percentage = (double(nElements) / double( nRanks ));
178 percentage -= minPerProc ;
179 percentage *= nRanks ;
182 size_t elementCount = maxPerProc ;
183 [[maybe_unused]]
size_t elementNumber = 0;
184 size_t localElementNumber = 0;
185 const int lastRank = nRanks - 1;
187 const size_t size = indexSet_.size( 0 );
188 for(
size_t i=0; i<size; ++i )
190 if( localElementNumber >= elementCount )
192 elementCuts_[ rank ] = i ;
195 if( rank < lastRank ) ++ rank;
198 localElementNumber = 0;
201 if( elementCount == maxPerProc && rank >= percentage )
202 elementCount = minPerProc ;
207 ++localElementNumber;
211 elementCuts_[ lastRank ] = size ;
217 const Communication& comm_;
219 const GridView& gridView_;
220 const IndexSet &indexSet_;
223 std::vector< long int > elementCuts_ ;
225#ifdef USE_ALUGRID_SFC_ORDERING
227 SpaceFillingCurveOrdering< VertexType > sfc_;
237 typedef Dune :: Communication< MPICommunicatorType >
244 std::ifstream file( filename.c_str() );
247 DUNE_THROW(InvalidStateException,
"file not found " << filename );
254 const std::string& name,
258 static_assert( dim == dimworld,
"YaspGrid is used for creation of the structured grid which only supports dim == dimworld");
263 dgf::PeriodicFaceTransformationBlock trafoBlock( input, dimworld );
264 if( trafoBlock.isactive() )
267 return SharedPtrType( grid.release() );
270 Dune::dgf::IntervalBlock intervalBlock( input );
271 if( !intervalBlock.isactive() )
273 std::cerr <<
"No interval block found, using default DGF method to create ALUGrid!" << std::endl;
274 return SharedPtrType( GridPtr< Grid > (input, mpiComm ).release());
277 if( intervalBlock.numIntervals() != 1 )
279 std::cerr <<
"ALUGrid creation from YaspGrid can only handle 1 interval block, using default DGF method to create ALUGrid!" << std::endl;
280 return SharedPtrType( GridPtr< Grid > (input, mpiComm ).release());
283 if( intervalBlock.dimw() != dim )
285 std::cerr <<
"ALUGrid creation from YaspGrid only works for dim == dimworld, using default DGF method to create ALUGrid!" << std::endl;
286 return SharedPtrType( GridPtr< Grid > (input, mpiComm ).release());
289 const dgf::IntervalBlock::Interval &interval = intervalBlock.get( 0 );
295 std::array<int, dim> dims;
296 FieldVector<ctype, dimworld> lowerLeft;
297 FieldVector<ctype, dimworld> upperRight;
298 for(
int i=0; i<dim; ++i )
300 dims[ i ] = interval.n[ i ] ;
301 lowerLeft[ i ] = interval.p[ 0 ][ i ];
302 upperRight[ i ] = interval.p[ 1 ][ i ];
306 comm.broadcast( &dims[ 0 ], dim, 0 );
307 comm.broadcast( &lowerLeft [ 0 ], dim, 0 );
308 comm.broadcast( &upperRight[ 0 ], dim, 0 );
310 std::string nameYasp( name );
311 nameYasp +=
" via YaspGrid";
312 typedef StructuredGridFactory< Grid > SGF;
313 return SGF :: createCubeGridImpl( lowerLeft, upperRight, dims, comm, nameYasp );
318 const FieldVector<ctype,dimworld>& upperRight,
319 const std::array<unsigned int, dim>& elements,
323 std::stringstream dgfstream;
324 dgfstream <<
"DGF" << std::endl;
325 dgfstream <<
"Interval" << std::endl;
326 dgfstream << lowerLeft << std::endl;
327 dgfstream << upperRight << std::endl;
328 for(
int i=0; i<dim; ++ i)
329 dgfstream << elements[ i ] <<
" ";
330 dgfstream << std::endl;
331 dgfstream <<
"#" << std::endl;
332 dgfstream <<
"Cube" << std::endl;
333 dgfstream <<
"#" << std::endl;
334 dgfstream <<
"Simplex" << std::endl;
335 dgfstream <<
"#" << std::endl;
337 std::cout << dgfstream.str() << std::endl;
340 return SharedPtrType( grid.release() );
345 const FieldVector<ctype,dimworld>& upperRight,
346 const std::array<unsigned int, dim>& elements,
349 Communication comm( mpiComm );
350 std::string name(
"Cartesian ALUGrid via YaspGrid" );
351 return createCubeGridImpl( lowerLeft, upperRight, elements, comm, name );
355 template <
int codim,
class Entity>
356 int subEntities (
const Entity& entity )
const
358 return entity.subEntities( codim );
361 template <
class int_t >
363 createCubeGridImpl (
const FieldVector<ctype,dimworld>& lowerLeft,
364 const FieldVector<ctype,dimworld>& upperRight,
365 const std::array< int_t, dim>& elements,
366 const Communication& comm,
367 const std::string& name )
369 const int myrank = comm.rank();
371 typedef YaspGrid< dimworld, EquidistantOffsetCoordinates<double,dimworld> > CartesianGridType ;
372 std::array< int, dim > dims;
373 for(
int i=0; i<dim; ++i ) dims[ i ] = elements[ i ];
377 CartesianGridType sgrid( lowerLeft, upperRight, dims, std::bitset<dim>(0ULL), 1, commSelf );
379 typedef typename CartesianGridType :: LeafGridView GridView ;
382 typedef typename GridView :: template
Codim< 0 > :: Iterator ElementIterator ;
383 typedef typename ElementIterator::Entity Entity ;
387 GridView gridView = sgrid.leafGridView();
388 const IndexSet &indexSet = gridView.indexSet();
391 SimplePartitioner< GridView, InteriorBorder_Partition > partitioner( gridView, comm, lowerLeft, upperRight );
397 std::map< IndexType, unsigned int > vtxMap;
398 std::map< double, const Entity > sortedElementList;
400 const int numVertices = (1 << dim);
401 std::vector< unsigned int > vertices( numVertices );
403 const ElementIterator end = gridView.template end< 0 >();
404 for( ElementIterator it = gridView.template begin< 0 >(); it != end; ++it )
406 const Entity &entity = *it;
409 if( partitioner.rank( entity ) != myrank )
412 const double elIndex = partitioner.index( entity );
413 assert( sortedElementList.find( elIndex ) == sortedElementList.end() );
414 sortedElementList.insert( std::make_pair( elIndex, entity ) );
417 int nextElementIndex = 0;
418 const auto endSorted = sortedElementList.end();
419 for(
auto it = sortedElementList.begin(); it != endSorted; ++it )
421 const Entity &entity = (*it).second;
425 alugrid_assert( numVertices == geo.corners() );
426 for(
int i = 0; i < numVertices; ++i )
428 const IndexType vtxId = indexSet.subIndex( entity, i, dim );
430 std::pair< typename std::map< IndexType, unsigned int >::iterator,
bool > result
431 = vtxMap.insert( std::make_pair( vtxId, vtxMap.size() ) );
434 vertices[ i ] = result.first->second;
438 const int elementIndex = nextElementIndex++;
442 const IntersectionIterator iend = gridView.iend( entity );
443 for( IntersectionIterator iit = gridView.ibegin( entity ); iit != iend; ++iit )
445 const Intersection &isec = *iit;
446 const int faceNumber = isec.indexInInside();
448 if( isec.boundary() )
449 factory.insertBoundary( elementIndex, faceNumber );
451 if( isec.neighbor() && (partitioner.rank( isec.outside() ) != myrank) )
452 factory.insertProcessBorder( elementIndex, faceNumber );
458 factory.setLongestEdgeFlag(
false);
461 return SharedPtrType( factory.
createGrid(
true,
true, name ) );
GridImp::template Codim< cd >::Geometry Geometry
The corresponding geometry type.
Definition: entity.hh:100
static constexpr int codimension
Know your own codimension.
Definition: entity.hh:106
virtual void insertElement(const GeometryType &type, const std::vector< unsigned int > &vertices)
Insert an element into the coarse grid.
Definition: gridfactory.hh:346
virtual void insertVertex(const FieldVector< ctype, dimworld > &pos)
Insert a vertex into the coarse grid.
Definition: gridfactory.hh:335
virtual std::unique_ptr< GridType > createGrid()
Finalize grid creation and hand over the grid.
Definition: gridfactory.hh:372
static constexpr int dimension
The dimension of the grid.
Definition: grid.hh:387
ct ctype
Define type used for coordinates in grid module.
Definition: grid.hh:532
IndexTypeImp IndexType
The type used for the indices.
Definition: indexidset.hh:92
Dune::Intersection< GridImp, IntersectionImp > Intersection
Type of Intersection this IntersectionIterator points to.
Definition: intersectioniterator.hh:111
MPI_Comm MPICommunicator
The type of the mpi communicator.
Definition: mpihelper.hh:190
static MPICommunicator getCommunicator()
get the default communicator
Definition: mpihelper.hh:198
static MPICommunicator getLocalCommunicator()
get a local communicator
Definition: mpihelper.hh:209
static void createSimplexGrid(GridFactory< GridType > &factory, const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &elements)
insert structured simplex grid into grid factory
Definition: structuredgridfactory.hh:181
static void createCubeGrid(GridFactory< GridType > &factory, const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &elements)
insert structured cube grid into grid factory
Definition: structuredgridfactory.hh:91
A free function to provide the demangled class name of a given object or type as a string.
A few common exception classes.
Provide a generic factory class for unstructured grids.
Implements a vector constructed from a given type representing a field and a compile-time given size.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
Traits::Grid Grid
type of the grid
Definition: gridview.hh:83
Traits::IntersectionIterator IntersectionIterator
type of the intersection iterator
Definition: gridview.hh:92
Traits::IndexSet IndexSet
type of the index set
Definition: gridview.hh:86
Dune namespace.
Definition: alignedallocator.hh:13
This file implements several utilities related to std::shared_ptr.
Class for constructing grids from DGF files.
Definition: gridptr.hh:66
Various macros to work with Dune module version numbers.