Please have a look on the non-virtual Refinement documentation.
Refinement can only be used when you know the geometryType of your entities at compile time. You could circumvent this by using a switch(geometryType), but each case would look very much the same. If you have many such switch() statements, or each case contains lots of code, or you simply have many possible geometryTypes, this can be quiet annoying.
VirtualRefinement does all of this switch() statements for you. It defines a common virtual base class per dimension, and derives one class for each geometryType and coerceTo from that class. The derived classes simply wrap the non-virtual classes from Refinement. This makes it possible to treat each geometryType (of a given dimension) the same, and thus eleminates the many repetitions of lots of code.
But the case statements are not totally gone yet. VirtualRefinement does these statements once and for all by wrapping them into the buildRefinement() function.
When you write a Refinement implementation for a new combination of geometryType and coerceTo, you have to tell buildRefinement() about it.
- First, you have to implement the non-virtual part in Refinement, if you have not done so yet.
- Second, visit the end of refinementvirtual.cc, and look for the specialisations of template<int dimension, class CoordType> class RefinementBuilder. There is one specialisation for each dimension, containing the single method build().
- The build() contains two levels of switch statements, the outer for geomentryType and the inner for coerceTo. Each case will either return the correct VirtualRefinement or fall throught to the end of the method and throw an error. Insert the cases for your refinement.
Everything else has been done for you automatically.
The interface is defined by the template class VirtualRefinement. It simply defines the CoordVectors and IndexVectors appropriate for this dimension and CoordType, defines which iterators to use, and provides some proxy or pure virtual functions.
For each class Refinement<geometryType, CoordType, coercTo, dim> we provide a class VirtualRefinementImp<geometryType, CoordType, coercTo, dim>, which wraps the matching class Refinement<geometryType, CoordType, coercTo, dim> and derives from the matching base class VirtualRefinement<dimension, CoordType>. Each VirtualRefinementImp is a singleton and has a static instance() method which will return this instance as a reference to the base class VirtualRefinement. All this is done in a single template class.