1#ifndef DUNE_ALUGRID_DGF_HH
2#define DUNE_ALUGRID_DGF_HH
7#include <dune/alugrid/grid.hh>
8#include <dune/grid/io/file/dgfparser/dgfalu.hh>
12#include <dune/alugrid/grid.hh>
14#include <dune/grid/common/intersection.hh>
15#include <dune/grid/io/file/dgfparser/dgfparser.hh>
16#include <dune/grid/io/file/dgfparser/parser.hh>
17#include <dune/grid/io/file/dgfparser/blocks/projection.hh>
29 class GlobalVertexIndexBlock
30 :
public dgf::BasicBlock
35 GlobalVertexIndexBlock ( std :: istream &in )
36 : dgf::BasicBlock( in,
"GlobalVertexIndex" ),
40 bool next (
int &index )
44 return (goodline =
false);
46 if( !getnextentry( index ) )
48 DUNE_THROW ( DGFException,
"Error in " << *
this <<
": "
49 <<
"Wrong global vertex indices " );
51 return (goodline =
true);
66 class ALUParallelBlock
67 :
public dgf::BasicBlock
72 ALUParallelBlock ( std :: istream &in )
73 : dgf::BasicBlock( in,
"ALUParallel" ),
77 bool next ( std::string &name )
81 return (goodline =
false);
83 if( !getnextentry( name ) )
85 DUNE_THROW ( DGFException,
"Error in " << *
this <<
": "
86 <<
"Wrong global vertex indices " );
88 return (goodline =
true);
105 template<
int dimg,
int dimw, ALUGr
idElementType eltype, ALUGr
idRefinementType refinementtype,
class Comm >
106 struct DGFGridInfo<
Dune::ALUGrid< dimg, dimw, eltype, refinementtype, Comm > >
109 static double refineWeight () {
return ( refinementtype ==
conforming ) ? 0.5 : 1.0/(std::pow( 2.0,
double(dimg))); }
120 struct DGFBaseFactory
125 typedef typename Grid::template Codim<0>::Entity Element;
126 typedef typename Grid::template Codim<dimension>::Entity Vertex;
134 explicit DGFBaseFactory ( MPICommunicatorType comm )
136 dgf_( rank(comm), size(comm) )
144 template<
class Intersection >
145 bool wasInserted (
const Intersection &intersection )
const
147 return factory_.wasInserted( intersection );
150 template<
class GG,
class II >
151 int boundaryId (
const Intersection< GG, II > & intersection )
const
156 const int face = intersection.indexInInside();
158 const auto& refElem =
160 int corners = refElem.size( face, 1, dimension );
161 std :: vector< unsigned int > bound( corners );
162 for(
int i=0; i < corners; ++i )
164 const int k = refElem.subEntity( face, 1, i, dimension );
165 bound[ i ] = factory_.insertionIndex( entity.template subEntity< dimension >( k ) );
168 DuneGridFormatParser::facemap_t::key_type key( bound,
false );
169 const DuneGridFormatParser::facemap_t::const_iterator pos = dgf_.facemap.find( key );
170 if( pos != dgf_.facemap.end() )
171 return dgf_.facemap.find( key )->second.first;
173 return (intersection.boundary() ? 1 : 0);
176 template<
class GG,
class II >
178 boundaryParameter (
const Intersection< GG, II > & intersection )
const
183 const int face = intersection.indexInInside();
185 const auto& refElem =
187 int corners = refElem.size( face, 1, dimension );
188 std :: vector< unsigned int > bound( corners );
189 for(
int i=0; i < corners; ++i )
191 const int k = refElem.subEntity( face, 1, i, dimension );
192 bound[ i ] = factory_.insertionIndex( entity.template subEntity< dimension >( k ) );
195 DuneGridFormatParser::facemap_t::key_type key( bound,
false );
196 const DuneGridFormatParser::facemap_t::const_iterator pos = dgf_.facemap.find( key );
197 if( pos != dgf_.facemap.end() )
198 return dgf_.facemap.find( key )->second.second;
203 template<
int codim >
204 int numParameters ()
const
207 return dgf_.nofelparams;
208 else if( codim == dimension )
209 return dgf_.nofvtxparams;
215 bool haveBoundaryParameters ()
const
217 return dgf_.haveBndParameters;
220 std::vector< double > ¶meter (
const Element &element )
222 if( numParameters< 0 >() <= 0 )
225 "Calling DGFGridFactory::parameter is only allowed if there are parameters." );
227 return dgf_.elParams[ factory_.insertionIndex( element ) ];
230 std::vector< double > ¶meter (
const Vertex &
vertex )
232 if( numParameters< dimension >() <= 0 )
235 "Calling DGFGridFactory::parameter is only allowed if there are parameters." );
237 return dgf_.vtxParams[ factory_.insertionIndex(
vertex ) ];
244 MPICommunicatorType communicator,
245 const std::string &filename );
248 static Grid* callDirectly(
const std::string& gridname,
250 const char *filename,
251 MPICommunicatorType communicator )
253 typedef typename Grid::MPICommunicatorType GridCommunicatorType;
254 static const bool isSameComm = std::is_same< GridCommunicatorType, MPICommunicatorType >::value;
255 return callDirectlyImpl( gridname, rank, filename, communicator, std::integral_constant< bool, isSameComm >() );
258 static Grid* callDirectlyImpl(
const std::string& gridname,
260 const char *filename,
261 MPICommunicatorType communicator,
267 if( fileExists( filename ) )
268 return new Grid( filename );
272 DUNE_THROW( GridError,
"Unable to create " << gridname <<
" from '"
273 << filename <<
"'." );
279 static Grid* callDirectlyImpl(
const std::string& gridname,
281 const char *filename,
282 MPICommunicatorType communicator,
285 if constexpr ( !std::is_same< MPICommunicatorType, No_Comm >::value )
288 std :: stringstream tmps;
289 tmps << filename <<
"." << rank;
290 const std :: string &tmp = tmps.str();
293 if( fileExists( tmp.c_str() ) )
294 return new Grid( tmp.c_str(), communicator );
300 if( fileExists( filename ) )
301 return new Grid( filename , communicator );
305 DUNE_THROW( GridError,
"Unable to create " << gridname <<
" from '"
306 << filename <<
"'." );
315 return new Grid( communicator );
317 static bool fileExists (
const char *fileName )
319 std :: ifstream testfile( fileName );
325 static int rank( MPICommunicatorType mpiComm )
329 MPI_Comm_rank( mpiComm, &rank );
333 static int size( MPICommunicatorType mpiComm )
337 MPI_Comm_size( mpiComm, &size );
342 GridFactory factory_;
343 DuneGridFormatParser dgf_;
346 template <
int dim,
int dimw, ALUGr
idElementType eltype, ALUGr
idRefinementType refinementtype,
class Comm >
347 struct DGFGridFactory< ALUGrid< dim, dimw, eltype, refinementtype, Comm > > :
348 public DGFBaseFactory< ALUGrid< dim, dimw, eltype, refinementtype, Comm > >
350 typedef ALUGrid< dim, dimw, eltype, refinementtype, Comm > DGFGridType;
351 typedef DGFBaseFactory< DGFGridType > BaseType;
352 typedef typename BaseType :: MPICommunicatorType MPICommunicatorType;
354 using BaseType :: grid_;
355 using BaseType :: callDirectly;
357 explicit DGFGridFactory ( std::istream &input,
358 MPICommunicatorType mpiComm )
359 : DGFGridFactory( input, Comm(mpiComm) )
362 explicit DGFGridFactory (
const std::string &filename,
363 MPICommunicatorType mpiComm )
364 : DGFGridFactory( filename, Comm(mpiComm) )
367 DGFGridFactory ( std::istream &input,
369 : BaseType( MPICommunicatorType(comm) )
374 DUNE_THROW( DGFException,
"Error resetting input stream." );
375 generate( input, comm );
378 explicit DGFGridFactory (
const std::string &filename,
380 : BaseType( MPICommunicatorType(comm) )
382 std::ifstream input( filename.c_str() );
383 bool fileFound = input.is_open() ;
385 fileFound = generate( input, comm, filename );
389 std::stringstream gridname;
390 gridname <<
"ALUGrid< " << dim <<
", " << dimw <<
", eltype, ref, comm >";
391 grid_ = callDirectly( gridname.str(), this->rank( comm ), filename.c_str(), comm );
396 bool generate( std::istream &file, MPICommunicatorType comm,
const std::string &filename =
"" );
403 struct ALU2dGridParameterBlock
404 :
public GridParameterBlock
406 ALU2dGridParameterBlock( std::istream &in,
const bool verbose )
410 if( findtoken(
"tolerance" ) )
413 if( getnextentry(x) )
419 dwarn <<
"GridParameterBlock: found keyword `tolerance' but no value, "
420 <<
"defaulting to `" << tolerance_ <<
"'!" << std::endl;
423 if( tolerance_ <= 0 )
424 DUNE_THROW( DGFException,
"Nonpositive tolerance specified!" );
430 dwarn <<
"GridParameterBlock: Parameter 'tolerance' not specified, "
431 <<
"defaulting to `" << tolerance_ <<
"'!" << std::endl;
436 double tolerance ()
const {
return tolerance_; }
446 inline bool DGFBaseFactory< G > ::
449 std::istream &file, MPICommunicatorType communicator,
450 const std::string &filename )
452 typedef G DGFGridType ;
454 const int dimworld = DGFGridType :: dimensionworld ;
455 const int dimgrid = DGFGridType :: dimension;
456 dgf_.element = ( eltype ==
simplex) ?
457 DuneGridFormatParser::Simplex :
458 DuneGridFormatParser::Cube ;
459 dgf_.dimgrid = dimgrid;
460 dgf_.dimw = dimworld;
462 const bool isDGF = dgf_.isDuneGridFormat( file );
468#if ALU3DGRID_PARALLEL
469 MPI_Comm_rank( communicator, &rank );
472 dgf::GridParameterBlock parameter( file );
474 typedef FieldVector< typename DGFGridType :: ctype, dimworld > CoordinateType ;
476 ALUParallelBlock aluParallelBlock( file );
477 const bool readFromParallelDGF = aluParallelBlock.isactive();
478 bool parallelFileExists =
false;
480 std::string newfilename;
481 if (readFromParallelDGF)
484 for (
int p=0;p<=rank && ok;++p)
485 ok = aluParallelBlock.next(newfilename);
488 parallelFileExists =
true;
489 std::ifstream newfile(newfilename.c_str());
492 std::cout <<
"prozess " << rank <<
" failed to open file " << newfilename <<
" ... abort" << std::endl;
493 DUNE_THROW( InvalidStateException,
"parallel DGF file could not opend" );
496 return generateALUGrid(eltype, refinementtype, newfile, communicator, filename);
505 GlobalVertexIndexBlock vertexIndex( file );
506 const bool globalVertexIndexFound = vertexIndex.isactive();
507 if( rank == 0 || globalVertexIndexFound )
509 if( !dgf_.readDuneGrid( file, dimgrid, dimworld ) )
510 DUNE_THROW( InvalidStateException,
"DGF file not recognized on second call." );
515 dgf_.setOrientation( 2, 3 );
517 dgf_.setRefinement( 0, 1);
520 if( parallelFileExists && !globalVertexIndexFound )
521 DUNE_THROW( DGFException,
"Parallel DGF file requires GLOBALVERTEXINDEX block." );
523 for(
int n = 0; n < dgf_.nofvtx; ++n )
526 for(
int i = 0; i < dimworld; ++i )
527 pos[ i ] = dgf_.vtx[ n ][ i ];
528 if ( !globalVertexIndexFound )
529 factory_.insertVertex( pos );
533 bool ok = vertexIndex.next(globalIndex);
535 DUNE_THROW( DGFException,
"Not enough values in GlobalVertexIndex block" );
536 factory_.insertVertex( pos, globalIndex );
540 const int nFaces = (eltype ==
simplex) ? dimgrid+1 : 2*dimgrid;
541 for(
int n = 0; n < dgf_.nofelements; ++n )
543 factory_.insertElement( elementType, dgf_.elements[ n ] );
544 for(
int face = 0; face <nFaces; ++face )
546 typedef DuneGridFormatParser::facemap_t::key_type Key;
547 typedef DuneGridFormatParser::facemap_t::iterator Iterator;
549 const Key key = ElementFaceUtil::generateFace( dimgrid, dgf_.elements[ n ], face );
550 const Iterator it = dgf_.facemap.find( key );
551 if( it != dgf_.facemap.end() )
552 factory_.insertBoundary( n, face, it->second.first );
558 dgf::ProjectionBlock projectionBlock( file, dimworld );
559 const DuneBoundaryProjection< dimworld > *projection
560 = projectionBlock.defaultProjection< dimworld >();
567 factory_.insertBoundaryProjection( *projection );
569 if( rank == 0 || globalVertexIndexFound )
571 const size_t numBoundaryProjections = projectionBlock.numBoundaryProjections();
572 for(
size_t i = 0; i < numBoundaryProjections; ++i )
574 const std::vector< unsigned int > &vertices = projectionBlock.boundaryFace( i );
575 const DuneBoundaryProjection< dimworld > *projection
576 = projectionBlock.boundaryProjection< dimworld >( i );
577 factory_.insertBoundaryProjection( faceType, vertices, projection );
580 typedef dgf::PeriodicFaceTransformationBlock::AffineTransformation Transformation;
581 dgf::PeriodicFaceTransformationBlock trafoBlock( file, dimworld );
582 const int size = trafoBlock.numTransformations();
583 for(
int k = 0; k < size; ++k )
585 const Transformation &trafo = trafoBlock.transformation( k );
587 typename GridFactory::WorldMatrix matrix;
588 for(
int i = 0; i < dimworld; ++i )
589 for(
int j = 0; j < dimworld; ++j )
590 matrix[ i ][ j ] = trafo.matrix( i, j );
592 typename GridFactory::WorldVector shift;
593 for(
int i = 0; i < dimworld; ++i )
594 shift[ i ] = trafo.shift[ i ];
596 factory_.insertFaceTransformation( matrix, shift );
600 int addMissingBoundariesLocal = (dgf_.nofelements > 0) && dgf_.facemap.empty();
601 int addMissingBoundariesGlobal = addMissingBoundariesLocal;
602#if ALU3DGRID_PARALLEL
603 MPI_Allreduce( &addMissingBoundariesLocal, &addMissingBoundariesGlobal, 1, MPI_INT, MPI_MAX, communicator );
607 if( ( refinementtype ==
conforming ) && parameter.markLongestEdge() )
608 factory_.setLongestEdgeFlag();
610 if( !parameter.dumpFileName().empty() )
611 grid_ = std::unique_ptr<Grid>(factory_.createGrid( addMissingBoundariesGlobal,
false, parameter.dumpFileName() )).release() ;
613 grid_ = std::unique_ptr<Grid>(factory_.createGrid( addMissingBoundariesGlobal,
true, filename )).release();
617 template <
int dim,
int dimw, ALUGr
idElementType eltype, ALUGr
idRefinementType refinementtype,
class Comm>
618 inline bool DGFGridFactory< ALUGrid< dim, dimw, eltype, refinementtype, Comm > >
619 ::generate( std::istream &file, MPICommunicatorType communicator,
const std::string &filename )
621 return BaseType :: generateALUGrid( eltype, refinementtype, file, communicator, filename );
static constexpr int dimension
The dimension of the grid.
Definition: grid.hh:387
Intersection of a mesh entity of codimension 0 ("element") with a "neighboring" element or with the d...
Definition: intersection.hh:164
GridImp::template Codim< 0 >::Entity Entity
Type of entity that this Intersection belongs to.
Definition: intersection.hh:192
MPI_Comm MPICommunicator
The type of the mpi communicator.
Definition: mpihelper.hh:190
GridParameterBlock(std::istream &in)
constructor: read commmon parameters
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:132
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr GeometryType cube(unsigned int dim)
Returns a GeometryType representing a hypercube of dimension dim.
Definition: type.hh:472
constexpr GeometryType simplex(unsigned int dim)
Returns a GeometryType representing a simplex of dimension dim.
Definition: type.hh:463
constexpr GeometryType vertex
GeometryType representing a vertex.
Definition: type.hh:506
DWarnType dwarn(std::cerr)
Stream for warnings indicating problems.
Definition: stdstreams.hh:161
Dune namespace.
Definition: alignedallocator.hh:13
ALUGridElementType
basic element types for ALUGrid
Definition: declaration.hh:17
@ simplex
use only simplex elements (i.e., triangles or tetrahedra)
Definition: declaration.hh:18
ALUGridRefinementType
available refinement types for ALUGrid
Definition: declaration.hh:24
@ conforming
use only conforming bisection refinement
Definition: declaration.hh:25
static const type & defaultValue()
default constructor
Definition: parser.hh:28
std::string type
type of additional boundary parameters
Definition: parser.hh:25
static double refineWeight()
static int refineStepsForHalf()
number of globalRefine steps needed to refuce h by 0.5
static const ReferenceElement & general(const GeometryType &type)
get general reference elements
Definition: referenceelements.hh:198