Dune Core Modules (unstable)

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