|
struct | Dune::RefinementImp::Traits< topologyId, CoordType, coerceToId, dimension, Dummy > |
| Mapping from geometryType, CoordType and coerceTo to a particular Refinement implementation. More...
|
|
struct | Dune::StaticRefinement< topologyId, CoordType, coerceToId, dimension_ >::Codim< codimension > |
| The Codim struct inherited from the Refinement implementation. More...
|
|
class | Dune::StaticRefinement< topologyId, CoordType, coerceToId, dimension_ > |
| Wrap each Refinement implementation to get a consistent interface. More...
|
|
General
The Refinement system allows to temporarily refine a grid or single entities without changing the grid itself. You may want to do this because you want to write your data to a file and have to do subsampling, but want to continue the calculation with the unmodified grid afterwards.
What Refinement can do for you
For a given geometry type and refinement level, Refinement will
- assign consecutive integer indices starting at 0 to each subvertex,
- assign consecutive integer indices starting at 0 to each subelement,
- calculate the coordinates of the subvertices for you,
- calculate subvertex-indices of the corners of the subelements for you.
The geometry type of the refined entity and of the subelements may be different, for example you can refine a quadrilateral but get subelements which are triangles.
Currently the following geometry types are supported:
- hypercubes (quadrilaterals, hexahedrons),
- simplices (triangles, tetrahedrons),
- triangulating hypercubes into simplices (quadrilaterals -> triangles, hexahedrons -> tetrahedrons).
What Refinement can't do for you
- Refinement does not actually subsample your data, it only tells you where to subsample your data.
- The geometry types need to be known at compile time. See VirtualRefinement if you need to calculate the right geometry type at run time.
- No Refinement implementations for anything besides hypercubes and simplices have been written yet.
The user interface
template<unsigned topologyId, class CoordType,
unsigned coerceToId, int dimension>
class StaticRefinement
{
public:
enum { dimension };
template<int codimension>
struct codim
{
class SubEntityIterator;
};
static VertexIterator
vBegin(
int level);
static VertexIterator
vEnd(
int level);
static ElementIterator
eBegin(
int level);
static ElementIterator
eEnd(
int level);
}
The Iterators can do all the usual things that Iterators can do, except dereferencing. In addition, to do something useful, they support some additional methods:
template<unsigned topologyId, class CoordType, unsigned coerceToId, int dimension>
class VertexIterator
{
public:
typedef ImplementationDefined Refinement;
int index() const;
Refinement::CoordVector coords() const;
}
template<unsigned topologyId, class CoordType, unsigned coerceToId, int dimension>
class ElementIterator
{
public:
typedef ImplementationDefined Refinement;
int index() const;
Refinement::CoordVector coords() const;
Refinement::IndexVector vertexIndices() const;
}
How to use it
Either use VirtualRefinement, or if you don't want to do that, read on.
#include <dune/grid/common/refinement.hh>
typedef StaticRefinement<GenericGeometry::CubeTopology<2>::type::id,
SGrid<2, 2>::ctype,
2> MyRefinement;
int main()
{
const int refinementlevel = 2;
cout << "Using refinementlevel = " << refinementlevel << endl << endl;
cout << "Number of Vertices: "
<< MyRefinement::nVertices(refinementlevel)
<< endl;
cout << "Index\tx\ty" << endl;
MyRefinement::VertexIterator vEnd = MyRefinement::vEnd(refinementlevel);
for(MyRefinement::VertexIterator i = MyRefinement::vBegin(refinementlevel); i != vEnd; ++i)
cout << i.index() << "\t" << i.coords()[0] << "\t" << i.coords()[1] << endl;
cout << endl;
cout << "Index\tEcke0\tEcke1\tEcke2\tEcke3" << endl;
MyRefinement::ElementIterator eEnd = MyRefinement::eEnd(refinementlevel);
for(MyRefinement::ElementIterator i = MyRefinement::eBegin(refinementlevel); i != eEnd; ++i)
cout << i.index() << "\t"
<< i.indexVertices()[0] << "\t" << i.indexVertices()[1] << "\t"
<< i.indexVertices()[2] << "\t" << i.indexVertices()[3] << endl;
cout << endl;
}
Guarantees
The Refinement system gives this guarantee (besides conforming to the above interface:
- The indices of the subvertices and subelement start at 0 and are consecutive.
Implementing a new Refinement type
If you want to write a Refinement implementation for a particular geometry type, e.g. SquaringTheCircle (or a particular set of geometry types) here is how:
- create a file refinement/squaringthecircle.cc and #include "base.cc". Your file will be included by others, so don't forget to protect against double inclusion.
- implement a class (or template class) RefinementImp conforming exactly to the user interface above.
- put it (and it's helper stuff as apropriate) into it's own namespace Dune::RefinementImp::SquaringTheCircle.
- define the mapping of topologyId, CoordType and coerceToId to your implementation by specialising template struct RefinementImp::Traits. It should look like this:
template<class CoordType>
struct Traits<sphereTopologyId, CoordType,
GenericGeometry::CubeTopology<2>::type::id, 2>
{
typedef SquaringTheCircle::RefinementImp<CoordType>
Imp;
};
}
If you implement a template class, you have to specialise struct RefinementImp::Traits for every possible combination of topologyId and coerceToId that your implementation supports.
- #include "refinement/squaringthecircle.cc" from refinement.hh.
This is enough to integrate your implementation into the Refinement system. You probably want to include it into VirtualRefinement also.
Namespaces
The (non-virtual) Refinement system is organized in the following way into namespaces:
The complete VirtualRefinement stuff is directly in namespace Dune.
Conceptual layers
- Layer 0 declares struct RefinementImp::Traits<topologyId, CoordType, coerceToId, dim>. It's member typedef Imp tells which Refinement implementation to use for a given topologyId (and CoordType). It is located in refinementbase.cc.
- Layer 1 defines RefinementImp::XXX::RefinementImp. It implements the Refinements for each topologyId, coerceToId (and CoordType). Also in this layer are the definitions of struct RefinementImp::Traits. This layer is located in refinementXXX.cc.
- Layer 2 puts it all together. It defines class StaticRefinement<topologyId, CoordType, coerceToId, dim> by deriving from the corresponding RefinementImp. It is located in refinementbase.cc.
- There is a dummy layer 2.5 which simply includes all the refinementXXX.cc files. It is located in refinement.cc.
VirtualRefinement adds two more layers to the ones defined here.