23
/** \brief Specialization of the generic GridFactory for UGGrid
28
If you want to write a routine that reads a grid from some
29
file into a Dune UGGrid object you have to know how to use the UGGrid
30
grid factory. In the following we
31
assume that you have a grid in some file format and an
32
empty UGGrid object, created by one of its constructors.
33
Hence, your file reader method signature may look like this:
37
UGGrid<3>* readMyFileFormat(const std::string& filename)
40
Now, in order to create a valid UGGrid object do the
43
<h2> 1) Create a GridFactory Object </h2>
45
Get a new GridFactory object by calling
47
GridFactory<UGGrid<dim> > factory;
50
<h2> 2) Enter the Vertices </h2>
53
Insert the grid vertices by calling
57
factory.insertVertex(const FieldVector<double,dimworld>& position);
61
for each vertex. The order of insertion determines the level- and leaf indices
62
of your level 0 vertices.
66
<h2> 3) Enter the elements </h2>
73
factory.insertElement(Dune::GeometryType type, const std::vector<int>& vertices);
81
<li> <b>type</b> - The element type. UG supports the types <i>simplex</i> and
82
<i>cube</i> in 2d, and <i>simplex, cube, prism</i>, and <i>pyramid</i> in 3d.
83
<li> <b>vertices</b> - The Ids of the vertices of this element.</li>
87
The numbering of the vertices of each element is expected to follow the DUNE conventions.
88
Refer to the page on reference elements for the details.
90
<h2> 4) Parametrized Domains </h2>
93
UGGrid supports parametrized domains. That means that you can provide a
94
smooth description of your grid boundary. The actual grid will always
95
be piecewise linear; however, as you refine, the grid will approach your
96
prescribed boundary. You don't have to do this. If your
97
coarse grid boundary describes your domain well read on at Section 5.
101
In order to create curved boundary segments, for each segment you have to write
102
a class which implements the correct geometry. These classes are then handed
103
over to the UGGrid object. Boundary segment implementations must be derived
106
template <int dimworld> Dune::BoundarySegment
108
This is an abstract base class which requires you to overload the method
111
virtual FieldVector< double, dimworld > operator() (const FieldVector< double, dimworld-1 > &local)
115
This methods must compute the world coordinates from the local ones on the
116
boundary segment. Give these classes to your grid factory by calling
119
factory.insertBoundarySegment(const std::vector<int>& vertices,
120
const BoundarySegment<dimworld> *boundarySegment);
124
Control over the allocated objects is taken from you, and the grid object
125
will take care of their destruction.
128
<h2> 5) Finish construction </h2>
131
To finish off the construction of the UGGrid object call
135
UGGrid<dim>* grid = factory.createGrid();
139
This time it is you who gets full responsibility for the allocated object.
142
<h2> Loading a Grid on a Parallel Machine </h2>
144
If you're working on a parallel machine, and you want to set up a
145
parallel grid, proceed as described only on the rank-0 process.
146
On the other processes just create a GridFactory and call createGrid()
147
to obtain the grid object. This will create the grid on the master process
148
and set up UG correctly on all other process. Call <tt>loadBalance()</tt>
149
to actually distribute the grid.
152
<p>\warning To use a parametrized boundary on a parallel machine you need
153
to hand over the boundary segments to the grid factory on <b>all</b> processes.
154
This behavior violates the Dune grid interface specification and will be
155
corrected in the future.
158
template <int dimworld>
159
class GridFactory<UGGrid<dimworld> > : public GridFactoryInterface<UGGrid<dimworld> > {
161
/** \brief Type used by the grid for coordinates */
162
typedef typename UGGrid<dimworld>::ctype ctype;
164
// UGGrid only in 2d and 3d
165
dune_static_assert(dimworld==2 || dimworld || 3, "UGGrid only in 2d and 3d");
169
/** \brief Default constructor */
172
/** \brief Constructor for a given grid object
174
If you already have your grid object constructed you can
175
hand it over using this constructor. A reason may be that
176
you need a UGGrid object with a non-default heap size.
178
If you construct your factory class using this constructor
179
the pointer handed over to you by the method createGrid() is
180
the one you supplied here.
182
GridFactory(UGGrid<dimworld>* grid);
184
/** \brief Destructor */
187
/** \brief Insert a vertex into the coarse grid */
188
virtual void insertVertex(const FieldVector<ctype,dimworld>& pos);
190
/** \brief Insert an element into the coarse grid
191
\param type The GeometryType of the new element
192
\param vertices The vertices of the new element, using the DUNE numbering
194
virtual void insertElement(const GeometryType& type,
195
const std::vector<unsigned int>& vertices);
197
/** \brief Method to insert a boundary segment into a coarse grid
199
Using this method is optional. It only influences the ordering of the segments
201
\param vertices The indices of the vertices of the segment
203
void insertBoundarySegment(const std::vector<unsigned int>& vertices);
205
/** \brief Method to insert an arbitrarily shaped boundary segment into a coarse grid
206
\param vertices The indices of the vertices of the segment
207
\param boundarySegment Class implementing the geometry of the boundary segment.
209
void insertBoundarySegment(const std::vector<unsigned int>& vertices,
210
const shared_ptr<BoundarySegment<dimworld> > &boundarySegment);
213
/** \brief Finalize grid creation and hand over the grid
215
The receiver takes responsibility of the memory allocated for the grid
217
virtual UGGrid<dimworld>* createGrid();
221
// Initialize the grid structure in UG
224
// Pointer to the grid being built
225
UGGrid<dimworld>* grid_;
227
// True if the factory allocated the grid itself, false if the
228
// grid was handed over from the outside
229
bool factoryOwnsGrid_;
231
/** \brief Buffer for the vertices of each explicitly given boundary segment */
232
std::vector<array<int, dimworld*2-2> > boundarySegmentVertices_;
234
/** \brief While inserting the elements this array records the number of
235
vertices of each element. */
236
std::vector<unsigned char> elementTypes_;
238
/** \brief While inserting the elements this array records the vertices
240
std::vector<unsigned int> elementVertices_;
242
/** \brief Buffer the vertices until createend() is called */
243
std::vector<FieldVector<double, dimworld> > vertexPositions_;
23
/** \brief Specialization of the generic GridFactory for UGGrid
28
If you want to write a routine that reads a grid from some
29
file into a Dune UGGrid object you have to know how to use the UGGrid
30
grid factory. In the following we
31
assume that you have a grid in some file format and an
32
empty UGGrid object, created by one of its constructors.
33
Hence, your file reader method signature may look like this:
37
UGGrid<3>* readMyFileFormat(const std::string& filename)
40
Now, in order to create a valid UGGrid object do the
43
<h2> 1) Create a GridFactory Object </h2>
45
Get a new GridFactory object by calling
47
GridFactory<UGGrid<dim> > factory;
50
<h2> 2) Enter the Vertices </h2>
53
Insert the grid vertices by calling
57
factory.insertVertex(const FieldVector<double,dimworld>& position);
61
for each vertex. The order of insertion determines the level- and leaf indices
62
of your level 0 vertices.
66
<h2> 3) Enter the elements </h2>
73
factory.insertElement(Dune::GeometryType type, const std::vector<int>& vertices);
81
<li> <b>type</b> - The element type. UG supports the types <i>simplex</i> and
82
<i>cube</i> in 2d, and <i>simplex, cube, prism</i>, and <i>pyramid</i> in 3d.
83
<li> <b>vertices</b> - The Ids of the vertices of this element.</li>
87
The numbering of the vertices of each element is expected to follow the DUNE conventions.
88
Refer to the page on reference elements for the details.
90
<h2> 4) Parametrized Domains </h2>
93
UGGrid supports parametrized domains. That means that you can provide a
94
smooth description of your grid boundary. The actual grid will always
95
be piecewise linear; however, as you refine, the grid will approach your
96
prescribed boundary. You don't have to do this. If your
97
coarse grid boundary describes your domain well read on at Section 5.
101
In order to create curved boundary segments, for each segment you have to write
102
a class which implements the correct geometry. These classes are then handed
103
over to the UGGrid object. Boundary segment implementations must be derived
106
template <int dimworld> Dune::BoundarySegment
108
This is an abstract base class which requires you to overload the method
111
virtual FieldVector< double, dimworld > operator() (const FieldVector< double, dimworld-1 > &local)
115
This methods must compute the world coordinates from the local ones on the
116
boundary segment. Give these classes to your grid factory by calling
119
factory.insertBoundarySegment(const std::vector<int>& vertices,
120
const BoundarySegment<dimworld> *boundarySegment);
124
Control over the allocated objects is taken from you, and the grid object
125
will take care of their destruction.
128
<h2> 5) Finish construction </h2>
131
To finish off the construction of the UGGrid object call
135
UGGrid<dim>* grid = factory.createGrid();
139
This time it is you who gets full responsibility for the allocated object.
142
<h2> Loading a Grid on a Parallel Machine </h2>
144
If you're working on a parallel machine, and you want to set up a
145
parallel grid, proceed as described only on the rank-0 process.
146
On the other processes just create a GridFactory and call createGrid()
147
to obtain the grid object. This will create the grid on the master process
148
and set up UG correctly on all other process. Call <tt>loadBalance()</tt>
149
to actually distribute the grid.
152
<p>\warning To use a parametrized boundary on a parallel machine you need
153
to hand over the boundary segments to the grid factory on <b>all</b> processes.
154
This behavior violates the Dune grid interface specification and will be
155
corrected in the future.
158
template <int dimworld>
159
class GridFactory<UGGrid<dimworld> > : public GridFactoryInterface<UGGrid<dimworld> > {
161
/** \brief Type used by the grid for coordinates */
162
typedef typename UGGrid<dimworld>::ctype ctype;
164
// UGGrid only in 2d and 3d
165
dune_static_assert(dimworld==2 || dimworld || 3, "UGGrid only in 2d and 3d");
169
/** \brief Default constructor */
172
/** \brief Constructor for a given grid object
174
If you already have your grid object constructed you can
175
hand it over using this constructor. A reason may be that
176
you need a UGGrid object with a non-default heap size.
178
If you construct your factory class using this constructor
179
the pointer handed over to you by the method createGrid() is
180
the one you supplied here.
182
GridFactory(UGGrid<dimworld>* grid);
184
/** \brief Destructor */
187
/** \brief Insert a vertex into the coarse grid */
188
virtual void insertVertex(const FieldVector<ctype,dimworld>& pos);
190
/** \brief Insert an element into the coarse grid
191
\param type The GeometryType of the new element
192
\param vertices The vertices of the new element, using the DUNE numbering
194
virtual void insertElement(const GeometryType& type,
195
const std::vector<unsigned int>& vertices);
197
/** \brief Method to insert a boundary segment into a coarse grid
199
Using this method is optional. It only influences the ordering of the segments
201
\param vertices The indices of the vertices of the segment
203
void insertBoundarySegment(const std::vector<unsigned int>& vertices);
205
/** \brief Method to insert an arbitrarily shaped boundary segment into a coarse grid
206
\param vertices The indices of the vertices of the segment
207
\param boundarySegment Class implementing the geometry of the boundary segment.
209
void insertBoundarySegment(const std::vector<unsigned int>& vertices,
210
const shared_ptr<BoundarySegment<dimworld> > &boundarySegment);
213
/** \brief Finalize grid creation and hand over the grid
215
The receiver takes responsibility of the memory allocated for the grid
217
virtual UGGrid<dimworld>* createGrid();
219
static const int dimension = UGGrid<dimworld>::dimension;
221
template< int codim >
224
typedef typename UGGrid<dimworld>::template Codim< codim >::Entity Entity;
227
/** \brief Return the number of the element in the order of insertion into the factory
229
* For UGGrid elements this number is the same as the element level index
232
insertionIndex ( const typename Codim< 0 >::Entity &entity ) const
234
return UG_NS<dimension>::levelIndex(grid_->getRealImplementation(entity).target_);
237
/** \brief Return the number of the vertex in the order of insertion into the factory
239
* For UGGrid vertices this number is the same as the vertex level index
242
insertionIndex ( const typename Codim< dimension >::Entity &entity ) const
244
return UG_NS<dimension>::levelIndex(grid_->getRealImplementation(entity).target_);
249
// Initialize the grid structure in UG
252
// Pointer to the grid being built
253
UGGrid<dimworld>* grid_;
255
// True if the factory allocated the grid itself, false if the
256
// grid was handed over from the outside
257
bool factoryOwnsGrid_;
259
/** \brief Buffer for the vertices of each explicitly given boundary segment */
260
std::vector<array<int, dimworld*2-2> > boundarySegmentVertices_;
262
/** \brief While inserting the elements this array records the number of
263
vertices of each element. */
264
std::vector<unsigned char> elementTypes_;
266
/** \brief While inserting the elements this array records the vertices
268
std::vector<unsigned int> elementVertices_;
270
/** \brief Buffer the vertices until createend() is called */
271
std::vector<FieldVector<double, dimworld> > vertexPositions_;