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:
First of all you have to call
grid.createBegin();This will set up the internal grid creation process.
Now you have to enter the grid vertices. Create a vertex by calling
grid.insertVertex(const FieldVector<double,dimworld>& position);
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.
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::BoundarySegmentThis 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.
To finish off the construction of the UGGrid object call
grid.createEnd();
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.