/usr/include/dune/grid/uggrid/uggridfactory.hh is in libdune-grid-dev 2.4.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_UGGRID_FACTORY_HH
#define DUNE_UGGRID_FACTORY_HH
/** \file
\brief The specialization of the generic GridFactory for UGGrid
\author Oliver Sander
*/
#include <vector>
#include <dune/common/fvector.hh>
#include <dune/grid/common/boundarysegment.hh>
#include <dune/grid/common/gridfactory.hh>
#include <dune/grid/uggrid.hh>
namespace Dune {
/** \brief Specialization of the generic GridFactory for UGGrid
\ingroup GridFactory
<p>
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 factory. 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:
</p>
<pre>
UGGrid<3>* readMyFileFormat(const std::string& filename)
</pre>
Now, in order to create a valid UGGrid object do the
following steps:
<h2> 1) Create a GridFactory Object </h2>
<p>
Get a new GridFactory object by calling
<pre>
GridFactory<UGGrid<dim> > factory;
</pre>
<h2> 2) Enter the Vertices </h2>
<p>
Insert the grid vertices by calling
</p>
<pre>
factory.insertVertex(const FieldVector<double,dimworld>& position);
</pre>
<p>
for each vertex. The order of insertion determines the level- and leaf indices
of your level 0 vertices.
</p>
<h2> 3) Enter the elements </h2>
<p>
For each element call
</p>
<pre>
factory.insertElement(Dune::GeometryType type, const std::vector<int>& vertices);
</pre>
<p>
The parameters are
</p>
<ul>
<li> <b>type</b> - The element type. UG supports the types <i>simplex</i> and
<i>cube</i> in 2d, and <i>simplex, cube, prism</i>, and <i>pyramid</i> in 3d.
<li> <b>vertices</b> - The Ids of the vertices of this element.</li>
</ul>
<p>
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.
<h2> 4) Parametrized Domains </h2>
<p>
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.
</p>
<p>
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
<pre>
template <int dimworld> Dune::BoundarySegment
</pre>
This is an abstract base class which requires you to overload the method
<pre>
virtual FieldVector< double, dimworld > operator() (const FieldVector< double, dimworld-1 > &local)
</pre>
<p>
This methods must compute the world coordinates from the local ones on the
boundary segment. Give these classes to your grid factory by calling
</p>
<pre>
factory.insertBoundarySegment(const std::vector<int>& vertices,
const BoundarySegment<dimworld> *boundarySegment);
</pre>
<p>
Control over the allocated objects is taken from you, and the grid object
will take care of their destruction.
</p>
<h2> 5) Finish construction </h2>
<p>
To finish off the construction of the UGGrid object call
</p>
<pre>
UGGrid<dim>* grid = factory.createGrid();
</pre>
<p>
This time it is you who gets full responsibility for the allocated object.
</p>
<h2> Loading a Grid on a Parallel Machine </h2>
<p>
If you're working on a parallel machine, and you want to set up a
parallel grid, proceed as described only on the rank-0 process.
On the other processes just create a GridFactory and call createGrid()
to obtain the grid object. This will create the grid on the master process
and set up UG correctly on all other process. Call <tt>loadBalance()</tt>
to actually distribute the grid.
</p>
<p>\warning To use a parametrized boundary on a parallel machine you need
to hand over the boundary segments to the grid factory on <b>all</b> processes.
This behavior violates the Dune grid interface specification and will be
corrected in the future.
</p>
*/
template <int dimworld>
class GridFactory<UGGrid<dimworld> > : public GridFactoryInterface<UGGrid<dimworld> > {
/** \brief Type used by the grid for coordinates */
typedef typename UGGrid<dimworld>::ctype ctype;
// UGGrid only in 2d and 3d
static_assert(dimworld==2 || dimworld || 3, "UGGrid only in 2d and 3d");
public:
/** \brief Default constructor */
GridFactory();
/** \brief Constructor for a given grid object
If you already have your grid object constructed you can
hand it over using this constructor. A reason may be that
you need a UGGrid object with a non-default heap size.
If you construct your factory class using this constructor
the pointer handed over to you by the method createGrid() is
the one you supplied here.
*/
GridFactory(UGGrid<dimworld>* grid);
/** \brief Destructor */
~GridFactory();
/** \brief Insert a vertex into the coarse grid */
virtual void insertVertex(const FieldVector<ctype,dimworld>& pos);
/** \brief Insert an element into the coarse grid
\param type The GeometryType of the new element
\param vertices The vertices of the new element, using the DUNE numbering
*/
virtual void insertElement(const GeometryType& type,
const std::vector<unsigned int>& vertices);
/** \brief Method to insert a boundary segment into a coarse grid
Using this method is optional. It only influences the ordering of the segments
\param vertices The indices of the vertices of the segment
*/
void insertBoundarySegment(const std::vector<unsigned int>& vertices);
/** \brief Method to insert an arbitrarily shaped boundary segment into a coarse grid
\param vertices The indices of the vertices of the segment
\param boundarySegment Class implementing the geometry of the boundary segment.
*/
void insertBoundarySegment(const std::vector<unsigned int>& vertices,
const shared_ptr<BoundarySegment<dimworld> > &boundarySegment);
/** \brief Finalize grid creation and hand over the grid
The receiver takes responsibility of the memory allocated for the grid
*/
virtual UGGrid<dimworld>* createGrid();
static const int dimension = UGGrid<dimworld>::dimension;
template< int codim >
struct Codim
{
typedef typename UGGrid<dimworld>::template Codim< codim >::Entity Entity;
};
/** \brief Return the number of the element in the order of insertion into the factory
*
* For UGGrid elements this number is the same as the element level index
*/
virtual unsigned int
insertionIndex ( const typename Codim< 0 >::Entity &entity ) const
{
return UG_NS<dimension>::levelIndex(grid_->getRealImplementation(entity).target_);
}
/** \brief Return the number of the vertex in the order of insertion into the factory
*
* For UGGrid vertices this number is the same as the vertex level index
*/
virtual unsigned int
insertionIndex ( const typename Codim< dimension >::Entity &entity ) const
{
return UG_NS<dimension>::levelIndex(grid_->getRealImplementation(entity).target_);
}
/** \brief Return the number of the intersection in the order of insertion into the factory
*
* For UGGrid intersections this number is the same as the boundary segment index
*/
virtual unsigned int
insertionIndex ( const typename UGGrid<dimworld>::LeafIntersection &intersection ) const
{
return intersection.boundarySegmentIndex();
}
/** \brief Return true if the intersection has been explictily insterted into the factory */
virtual bool
wasInserted ( const typename UGGrid<dimworld>::LeafIntersection &intersection ) const
{
return (insertionIndex( intersection ) < boundarySegmentVertices_.size());
}
private:
// Initialize the grid structure in UG
void createBegin();
// Pointer to the grid being built
UGGrid<dimworld>* grid_;
// True if the factory allocated the grid itself, false if the
// grid was handed over from the outside
bool factoryOwnsGrid_;
/** \brief Buffer for the vertices of each explicitly given boundary segment */
std::vector<array<int, dimworld*2-2> > boundarySegmentVertices_;
/** \brief While inserting the elements this array records the number of
vertices of each element. */
std::vector<unsigned char> elementTypes_;
/** \brief While inserting the elements this array records the vertices
of the elements. */
std::vector<unsigned int> elementVertices_;
/** \brief Buffer the vertices until createend() is called */
std::vector<FieldVector<double, dimworld> > vertexPositions_;
};
}
#endif
|