How to Write a File Reader for UGGrid Objects

If you want to write a routine that reads a grid from some file into a Dune UGGrid object you have to know how to use the UGGrid grid creation interface. In the following we assume that you have a grid in some file format and an empty UGGrid object, created by one of its constructors. Hence, your file reader method signature may look like this:

void readMyFileFormat(Dune::UGGrid<3>& grid, const std::string& filename)
Now, in order to create a valid UGGrid object do the following steps:

1) Start the Creation Process

First of all you have to call

grid.createBegin();
This will set up the internal grid creation process.

2) Enter the Vertices

Now you have to enter the grid vertices. Create a vertex by calling

grid.insertVertex(const FieldVector<double,dimworld>& position);

3) Enter the elements

For each element call

grid.insertElement(Dune::GeometryType type, const std::vector<int>& vertices);

The parameters are

The numbering of the vertices of each element is expected to follow the DUNE conventions. Refer to the page on reference elements for the details.

4) Parametrized Domains

UGGrid supports parametrized domains. That means that you can provide a smooth description of your grid boundary. The actual grid will always be piecewise linear; however, as you refine, the grid will approach your prescribed boundary. You don't have to do this. If your coarse grid boundary describes your domain well read on at Section 5.

In order to create curved boundary segments, for each segment you have to write a class which implements the correct geometry. These classes are then handed over to the UGGrid object. Boundary segment implementations must be derived from

    template <int dimworld> Dune::BoundarySegment
This is an abstract base class which requires you to overload the method
virtual FieldVector< double, dimworld > operator() (const FieldVector< double, dimworld-1 > &local)

This methods must compute the world coordinates from the local ones on the boundary segment. Give these classes to your grid by calling

grid.insertBoundarySegment(const std::vector<int>& vertices,
                           const BoundarySegment<dimworld> *boundarySegment);

Control over the allocated objects is taken from you, and the grid object will take care of their destruction.

5) Finish construction

To finish off the construction of the UGGrid object call

grid.createEnd();

Loading a Grid on a Parallel Machine

If you're working on a parallel machine, and you want to set up a parallel grid, proceed as described on all processes. This will create the grid on the master process and set up UG correctly on all other process. Call loadBalance() to actually distribute the grid.

WARNING: UG internally requests that all boundary vertices be inserted before the inner ones. That means that if your input grid doesn't comply with this, it will have its vertices reordered by createEnd(). So don't be surprised if you just read a grid and write it back to disk to find your vertex numberings changed.

Mail comments, critique, and corrections to sander@mi.fu.berlin.de.