Dune Core Modules (2.5.1)

dgfyasp.hh
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_DGFPARSERYASP_HH
4 #define DUNE_DGFPARSERYASP_HH
5 
6 #include <dune/grid/common/intersection.hh>
7 #include <dune/grid/yaspgrid.hh>
8 #include "dgfparser.hh"
9 
10 namespace Dune
11 {
12 
13  // External Forward Declarations
14  // -----------------------------
15 
16  template< class GridImp, class IntersectionImp >
17  class Intersection;
18 
19 
20  namespace dgf
21  {
22 
37  : public GridParameterBlock
38  {
39  protected:
40  int _overlap; // overlap for YaspGrid
41 
42  public:
44  YaspGridParameterBlock( std::istream &in )
45  : GridParameterBlock( in ),
46  _overlap( 0 ) // default value
47  {
48  // check overlap
49  if( findtoken( "overlap" ) )
50  {
51  int x;
52  if( getnextentry(x) ) _overlap = x;
53  else
54  {
55  dwarn << "GridParameterBlock: found keyword `overlap' but no value, defaulting to `" << _overlap <<"' !\n";
56  }
57 
58  if (_overlap < 0)
59  {
60  DUNE_THROW(DGFException,"Negative overlap specified!");
61  }
62  }
63  else
64  {
65  dwarn << "YaspGridParameterBlock: Parameter 'overlap' not specified, "
66  << "defaulting to '" << _overlap << "'." << std::endl;
67  }
68 
69  }
70 
72  int overlap () const
73  {
74  return _overlap;
75  }
76 
77  };
78 
79  }
80 
84  template <int dim>
85  struct DGFGridFactory< YaspGrid<dim /*, EquidistantCoordinates<double, dim> */> >
86  {
87  typedef YaspGrid<dim> Grid;
88  const static int dimension = Grid::dimension;
89  typedef MPIHelper::MPICommunicator MPICommunicatorType;
90 
91  private:
93  typedef dgf::BoundaryDomBlock BoundaryDomainBlock;
94 
95  public:
96  explicit DGFGridFactory ( std::istream &input,
97  MPICommunicatorType comm = MPIHelper::getCommunicator() )
98  {
99  generate( input, comm );
100  }
101 
102  explicit DGFGridFactory ( const std::string &filename,
103  MPICommunicatorType comm = MPIHelper::getCommunicator() )
104  {
105  std::ifstream input( filename.c_str() );
106  if( !input )
107  DUNE_THROW( DGFException, "Error: Macrofile '" << filename << "' not found" );
108  generate( input, comm );
109  }
110 
111  ~DGFGridFactory ()
112  {
113  delete boundaryDomainBlock_;
114  }
115 
116  Grid *grid() const
117  {
118  return grid_;
119  }
120 
121  template <class Intersection>
122  bool wasInserted(const Intersection &intersection) const
123  {
124  return false;
125  }
126 
127  template <class Intersection>
128  int boundaryId(const Intersection &intersection) const
129  {
130  if( boundaryDomainBlock_->isactive() )
131  {
132  std::vector< Point > corners;
133  getCorners( intersection.geometry(), corners );
134  const dgf::DomainData *data = boundaryDomainBlock_->contains( corners );
135  if( data )
136  return data->id();
137  else
138  return intersection.indexInInside();
139  }
140  else
141  return intersection.indexInInside();
142  }
143 
144  template< int codim >
145  int numParameters () const
146  {
147  return 0;
148  }
149 
150  // return true if boundary parameters found
151  bool haveBoundaryParameters () const
152  {
153  return boundaryDomainBlock_->hasParameter();
154  }
155 
156  template< class GG, class II >
157  const typename DGFBoundaryParameter::type &
158  boundaryParameter ( const Intersection< GG, II > & intersection ) const
159  {
160  if( haveBoundaryParameters() )
161  {
162  std::vector< Point > corners;
163  getCorners( intersection.geometry(), corners );
164  const dgf::DomainData *data = boundaryDomainBlock_->contains( corners );
165  if( data )
166  return data->parameter();
167  else
169  }
170  else
172  }
173 
174  template< class Entity >
175  std::vector<double> &parameter ( const Entity &entity )
176  {
177  return emptyParam;
178  }
179 
180  private:
181  void generate( std::istream &gridin, MPICommunicatorType comm );
182 
183  template< class Geometry >
184  static void getCorners ( const Geometry &geometry, std::vector< Point > &corners )
185  {
186  corners.resize( geometry.corners() );
187  for( int i = 0; i < geometry.corners(); ++i )
188  {
189  const typename Geometry::GlobalCoordinate corner = geometry.corner( i );
190  for( int j = 0; j < dimension; ++j )
191  corners[ i ][ j ] = corner[ j ];
192  }
193  }
194 
195  Grid *grid_;
196  dgf::BoundaryDomBlock *boundaryDomainBlock_;
197  std::vector<double> emptyParam;
198  };
199 
200  // generate YaspGrid from the provided DGF
201  template< int dim >
202  inline void DGFGridFactory< YaspGrid< dim /*, EquidistantCoordinates<double, dim> */> >
203  ::generate ( std::istream &gridin, MPICommunicatorType comm )
204  {
205  dgf::IntervalBlock intervalBlock( gridin );
206 
207  if( !intervalBlock.isactive() )
208  DUNE_THROW( DGFException, "YaspGrid can only be created from an interval block." );
209 
210  if( intervalBlock.numIntervals() != 1 )
211  DUNE_THROW( DGFException, "YaspGrid can only handle 1 interval block." );
212 
213  if( intervalBlock.dimw() != dim )
214  {
216  "Cannot read an interval of dimension " << intervalBlock.dimw()
217  << " into a YaspGrid< " << dim << " >." );
218  }
219 
220  const dgf::IntervalBlock::Interval &interval = intervalBlock.get( 0 );
221 
222  FieldVector<double,dim> lang;
223  std::array<int,dim> anz;
224  for( int i = 0; i < dim; ++i )
225  {
226  // check that start point is 0.0
227  if( std::abs( interval.p[ 0 ][ i ] ) > 1e-10 )
228  {
229  DUNE_THROW( DGFException,
230  "YaspGrid cannot handle grids with non-zero left lower corner." );
231  }
232 
233  lang[ i ] = interval.p[ 1 ][ i ] - interval.p[ 0 ][ i ];
234  anz[ i ] = interval.n[ i ];
235  }
236 
237  typedef dgf::PeriodicFaceTransformationBlock::AffineTransformation Transformation;
238  dgf::PeriodicFaceTransformationBlock trafoBlock( gridin, dim );
239  std::bitset< dim > per;
240  const int numTrafos = trafoBlock.numTransformations();
241  for( int k = 0; k < numTrafos; ++k )
242  {
243  const Transformation &trafo = trafoBlock.transformation( k );
244 
245  bool identity = true;
246  for( int i = 0; i < dim; ++i )
247  for( int j = 0; j < dim; ++j )
248  identity &= (std::abs( (i == j ? 1.0 : 0.0) - trafo.matrix( i, j ) ) < 1e-10);
249  if( !identity )
250  DUNE_THROW( DGFException, "YaspGrid can only handle shifts as periodic face transformations." );
251 
252  int numDirs = 0;
253  int dir = -1;
254  for( int i = 0; i < dim; ++i )
255  {
256  if( std::abs( trafo.shift[ i ] ) < 1e-10 )
257  continue;
258  dir = i;
259  ++numDirs;
260  }
261  if( (numDirs != 1) || (std::abs( std::abs( trafo.shift[ dir ] ) - lang[ dir ] ) >= 1e-10) )
262  {
263  std::cerr << "Tranformation '" << trafo
264  << "' does not map boundaries on boundaries." << std::endl;
265  }
266  else
267  per[ dir ] = true;
268  }
269 
270  // get grid parameters
271  dgf::YaspGridParameterBlock grdParam( gridin );
272 
273  grid_ = new YaspGrid< dim >( lang, anz, per, grdParam.overlap(), comm );
274 
275  boundaryDomainBlock_ = new dgf::BoundaryDomBlock( gridin, dimension );
276  }
277 
278  template <int dim>
279  struct DGFGridInfo< YaspGrid<dim /*, EquidistantCoordinates<double, dim> */> > {
280  static int refineStepsForHalf() {return 1;}
281  static double refineWeight() {return std::pow(0.5,dim);}
282  };
283 
287  template <int dim>
288  struct DGFGridFactory< YaspGrid<dim, EquidistantOffsetCoordinates<double, dim> > >
289  {
291  const static int dimension = Grid::dimension;
292  typedef MPIHelper::MPICommunicator MPICommunicatorType;
293 
294  private:
296  typedef dgf::BoundaryDomBlock BoundaryDomainBlock;
297 
298  public:
299  explicit DGFGridFactory ( std::istream &input,
300  MPICommunicatorType comm = MPIHelper::getCommunicator() )
301  {
302  generate( input, comm );
303  }
304 
305  explicit DGFGridFactory ( const std::string &filename,
306  MPICommunicatorType comm = MPIHelper::getCommunicator() )
307  {
308  std::ifstream input( filename.c_str() );
309  generate( input, comm );
310  }
311 
312  ~DGFGridFactory ()
313  {
314  delete boundaryDomainBlock_;
315  }
316 
317  Grid *grid() const
318  {
319  return grid_;
320  }
321 
322  template <class Intersection>
323  bool wasInserted(const Intersection &intersection) const
324  {
325  return false;
326  }
327 
328  template <class Intersection>
329  int boundaryId(const Intersection &intersection) const
330  {
331  if( boundaryDomainBlock_->isactive() )
332  {
333  std::vector< Point > corners;
334  getCorners( intersection.geometry(), corners );
335  const dgf::DomainData *data = boundaryDomainBlock_->contains( corners );
336  if( data )
337  return data->id();
338  else
339  return intersection.indexInInside();
340  }
341  else
342  return intersection.indexInInside();
343  }
344 
345  template< int codim >
346  int numParameters () const
347  {
348  return 0;
349  }
350 
351  // return true if boundary parameters found
352  bool haveBoundaryParameters () const
353  {
354  return boundaryDomainBlock_->hasParameter();
355  }
356 
357  template< class GG, class II >
358  const typename DGFBoundaryParameter::type &
359  boundaryParameter ( const Intersection< GG, II > & intersection ) const
360  {
361  if( haveBoundaryParameters() )
362  {
363  std::vector< Point > corners;
364  getCorners( intersection.geometry(), corners );
365  const dgf::DomainData *data = boundaryDomainBlock_->contains( corners );
366  if( data )
367  return data->parameter();
368  else
370  }
371  else
373  }
374 
375  template< class Entity >
376  std::vector<double> &parameter ( const Entity &entity )
377  {
378  return emptyParam;
379  }
380 
381  private:
382  void generate( std::istream &gridin, MPICommunicatorType comm );
383 
384  template< class Geometry >
385  static void getCorners ( const Geometry &geometry, std::vector< Point > &corners )
386  {
387  corners.resize( geometry.corners() );
388  for( int i = 0; i < geometry.corners(); ++i )
389  {
390  const typename Geometry::GlobalCoordinate corner = geometry.corner( i );
391  for( int j = 0; j < dimension; ++j )
392  corners[ i ][ j ] = corner[ j ];
393  }
394  }
395 
396  Grid *grid_;
397  dgf::BoundaryDomBlock *boundaryDomainBlock_;
398  std::vector<double> emptyParam;
399  };
400 
401  // generate YaspGrid from the provided DGF
402  template< int dim >
403  inline void DGFGridFactory< YaspGrid<dim, EquidistantOffsetCoordinates<double, dim> > >
404  ::generate ( std::istream &gridin, MPICommunicatorType comm )
405  {
406  dgf::IntervalBlock intervalBlock( gridin );
407 
408  if( !intervalBlock.isactive() )
409  DUNE_THROW( DGFException, "YaspGrid can only be created from an interval block." );
410 
411  if( intervalBlock.numIntervals() != 1 )
412  DUNE_THROW( DGFException, "YaspGrid can only handle 1 interval block." );
413 
414  if( intervalBlock.dimw() != dim )
415  {
417  "Cannot read an interval of dimension "
418  << intervalBlock.dimw()
419  << " into a YaspGrid< " << dim << " >." );
420  }
421 
422  const dgf::IntervalBlock::Interval &interval = intervalBlock.get( 0 );
423 
424  FieldVector<double,dim> lower;
425  FieldVector<double,dim> upper;
426  std::array<int,dim> anz;
427  for( int i = 0; i < dim; ++i )
428  {
429  lower[ i ] = interval.p[ 0 ][ i ];
430  upper[ i ] = interval.p[ 1 ][ i ];
431  anz[ i ] = interval.n[ i ];
432  }
433 
434  typedef dgf::PeriodicFaceTransformationBlock::AffineTransformation Transformation;
435  dgf::PeriodicFaceTransformationBlock trafoBlock( gridin, dim );
436  std::bitset< dim > periodic;
437  const int numTrafos = trafoBlock.numTransformations();
438  for( int k = 0; k < numTrafos; ++k )
439  {
440  const Transformation &trafo = trafoBlock.transformation( k );
441 
442  bool identity = true;
443  for( int i = 0; i < dim; ++i )
444  for( int j = 0; j < dim; ++j )
445  identity &= (std::abs( (i == j ? 1.0 : 0.0) - trafo.matrix( i, j ) ) < 1e-10);
446  if( !identity )
447  DUNE_THROW( DGFException, "YaspGrid can only handle shifts as periodic face transformations." );
448 
449  int numDirs = 0;
450  int dir = -1;
451  for( int currentDir = 0; currentDir < dim; ++currentDir )
452  {
453  if( std::abs( trafo.shift[ currentDir ] ) > 1e-10 )
454  {
455  dir = currentDir;
456  ++numDirs;
457  }
458  }
459  if ( (numDirs != 1)
460  || (std::abs( std::abs( trafo.shift[ dir ] ) - std::abs( upper[ dir ] - lower[ dir ] ) ) >= 1e-10) )
461  {
462  std::cerr << "Tranformation '" << trafo
463  << "' does not map boundaries on boundaries." << std::endl;
464  }
465  else
466  {
467  periodic[ dir ] = true;
468  }
469  }
470 
471  // get grid parameters
472  dgf::YaspGridParameterBlock grdParam( gridin );
473 
474  grid_ = new YaspGrid< dim, EquidistantOffsetCoordinates<double, dim> >
475  ( lower, upper, anz, periodic, grdParam.overlap(), comm );
476 
477  boundaryDomainBlock_ = new dgf::BoundaryDomBlock( gridin, dimension );
478  }
479 
480  template <int dim>
481  struct DGFGridInfo< YaspGrid<dim, EquidistantOffsetCoordinates<double, dim> > > {
482  static int refineStepsForHalf() {return 1;}
483  static double refineWeight() {return std::pow(0.5,dim);}
484  };
485 
486 }
487 #endif // #ifndef DUNE_DGFPARSERYASP_HH
exception class for IO errors in the DGF parser
Definition: dgfexception.hh:14
Wrapper class for entities.
Definition: entity.hh:65
Container for equidistant coordinates in a YaspGrid with non-trivial origin.
Definition: coordinates.hh:125
vector space out of a tensor product of fields.
Definition: fvector.hh:93
Wrapper class for geometries.
Definition: geometry.hh:66
GlobalCoordinate corner(int i) const
Obtain a corner of the geometry.
Definition: geometry.hh:148
int corners() const
Return the number of corners of the reference element.
Definition: geometry.hh:134
@ 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:162
Geometry geometry() const
geometrical information about the intersection in global coordinates.
Definition: intersection.hh:351
int indexInInside() const
Local index of codim 1 entity in the inside() entity where intersection is contained in.
Definition: intersection.hh:374
MPI_Comm MPICommunicator
The type of the mpi communicator.
Definition: mpihelper.hh:173
static MPICommunicator getCommunicator()
get the default communicator
Definition: mpihelper.hh:181
[ provides Dune::Grid ]
Definition: yaspgrid.hh:165
Common Grid parameters.
Definition: gridparameter.hh:33
Grid parameters for YaspGrid.
Definition: dgfyasp.hh:38
YaspGridParameterBlock(std::istream &in)
constructor taking istream
Definition: dgfyasp.hh:44
int overlap() const
get dimension of world found in block
Definition: dgfyasp.hh:72
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
DWarnType dwarn(std::cerr)
Stream for warnings indicating problems.
Definition: stdstreams.hh:159
Dune namespace.
Definition: alignment.hh:11
static const type & defaultValue()
default constructor
Definition: parser.hh:26
std::string type
type of additional boundary parameters
Definition: parser.hh:23
static double refineWeight()
static int refineStepsForHalf()
number of globalRefine steps needed to refuce h by 0.5
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 10, 22:30, 2024)