DUNE-FEM (unstable)

Refinement

Modules

 Refinement implementation for hypercubes
 
 Refinement implementation for triangulating hypercubes
 
 Refinement implementation for simplices
 
 Virtual Refinement
 

Namespaces

namespace  Dune::RefinementImp
 This namespace contains the implementation of Refinement.
 

Classes

class  Dune::RefinementIntervals
 Holds the number of refined intervals per axis needed for virtual and static refinement. More...
 
class  Dune::StaticRefinement< topologyId, CoordType, coerceToId, dimension_ >
 Wrap each Refinement implementation to get a consistent interface. More...
 

Functions

RefinementIntervals Dune::refinementIntervals (int intervals)
 Creates a RefinementIntervals object. More...
 
RefinementIntervals Dune::refinementLevels (int levels)
 Creates a RefinementIntervals object. More...
 

Detailed Description

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 number of refined intervals, 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:
constexpr static int dimension = dimension_;
template<int codimension>
struct codim
{
class SubEntityIterator;
};
typedef ImplementationDefined VertexIterator; // These are aliases for codim<codim>::SubEntityIterator
typedef ImplementationDefined ElementIterator;
typedef ImplementationDefined IndexVector; // These are FieldVectors
typedef ImplementationDefined CoordVector;
static int nVertices(Dune::RefinementIntervals intervals);
static int nElements(Dune::RefinementIntervals intervals);
}
Holds the number of refined intervals per axis needed for virtual and static refinement.
Definition: base.cc:94
static ElementIterator eEnd(Dune::RefinementIntervals tag)
Get an ElementIterator.
Definition: base.cc:247
static ElementIterator eBegin(Dune::RefinementIntervals tag)
Get an ElementIterator.
Definition: base.cc:237
static int nElements(Dune::RefinementIntervals tag)
Get the number of Elements.
Definition: base.cc:227
Codim< 0 >::SubEntityIterator ElementIterator
The ElementIterator of the Refinement.
Definition: base.cc:163
static int nVertices(Dune::RefinementIntervals tag)
Get the number of Vertices.
Definition: base.cc:197
static VertexIterator vBegin(Dune::RefinementIntervals tag)
Get a VertexIterator.
Definition: base.cc:207
Codim< dimension >::SubEntityIterator VertexIterator
The VertexIterator of the Refinement.
Definition: base.cc:161
typedef CoordVector
The CoordVector of the Refinement.
Definition: base.cc:170
typedef IndexVector
The IndexVector of the Refinement.
Definition: base.cc:177
static VertexIterator vEnd(Dune::RefinementIntervals tag)
Get a VertexIterator.
Definition: base.cc:217

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;
// Coords of the center of mass of the element
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 the necessary files
#include <dune/grid/common/refinement.hh>
// If you know that you are only ever going to need one refinement
// backend, you can include the corresponding file directly:
//#include <dune/grid/common/refinement/hcube.cc>
// Get yourself the Refinement you need:
typedef StaticRefinement<GeometryTypes::cube(2),
SGrid<2, 2>::ctype,
2> MyRefinement;
int main()
{
const Dune::RefinementIntervals refinementlevel = Dune::refinementLevels(2); // equivalent: Dune::refinementIntervals(4)
cout << "Using refinementlevel = " << refinementlevel.intervals() << endl << endl;
// get Number of Vertices
cout << "Number of Vertices: "
<< MyRefinement::nVertices(refinementlevel)
<< endl;
// Iterate over Vertices
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;
// Iterate over Vertices
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;
}
constexpr GeometryType cube(unsigned int dim)
Returns a GeometryType representing a hypercube of dimension dim.
Definition: type.hh:462
RefinementIntervals refinementLevels(int levels)
Creates a RefinementIntervals object.
Definition: base.cc:117

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 appropriate) 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:
    // we're only implementing this for dim=2
    template<class CoordType>
    struct Traits<sphereTopologyId, CoordType,
    GeometryTypes::cube(2), 2>
    {
    typedef SquaringTheCircle::RefinementImp<CoordType> Imp;
    };
    }
    This namespace contains the implementation of Refinement.
    Definition: base.cc:29
    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.

Function Documentation

◆ refinementIntervals()

RefinementIntervals Dune::refinementIntervals ( int  intervals)
inline

Creates a RefinementIntervals object.

Parameters
intervalsNumber of refined intervals per axis

◆ refinementLevels()

RefinementIntervals Dune::refinementLevels ( int  levels)
inline

Creates a RefinementIntervals object.

Parameters
levelsNumber of refinement levels, translates to \(2^{levels}\) intervals per axis
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 12, 23:30, 2024)