~ubuntu-branches/ubuntu/utopic/dune-grid/utopic-proposed

« back to all changes in this revision

Viewing changes to dune/grid/uggrid/uggridfactory.hh

  • Committer: Package Import Robot
  • Author(s): Ansgar Burchardt
  • Date: 2014-02-14 10:49:16 UTC
  • mfrom: (1.3.1) (5.1.4 experimental)
  • Revision ID: package-import@ubuntu.com-20140214104916-2clchnny3eu7ks4w
Tags: 2.3.0-2
InstallĀ /usr/share/dune-grid.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
 
// vi: set et ts=8 sw=4 sts=4:
 
1
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 
2
// vi: set et ts=4 sw=2 sts=2:
3
3
 
4
4
#ifndef DUNE_UGGRID_FACTORY_HH
5
5
#define DUNE_UGGRID_FACTORY_HH
20
20
namespace Dune {
21
21
 
22
22
 
23
 
    /** \brief Specialization of the generic GridFactory for UGGrid
24
 
 
25
 
        \ingroup GridFactory
26
 
        
27
 
    <p>
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:
34
 
    </p>
35
 
    
36
 
    <pre>
37
 
    UGGrid&lt;3&gt;* readMyFileFormat(const std::string& filename)
38
 
    </pre>
39
 
    
40
 
    Now, in order to create a valid UGGrid object do the
41
 
    following steps:
42
 
    
43
 
    <h2> 1) Create a GridFactory Object </h2>
44
 
    <p>
45
 
    Get a new GridFactory object by calling
46
 
    <pre>
47
 
    GridFactory<UGGrid<dim> > factory;
48
 
    </pre>
49
 
    
50
 
    <h2> 2)  Enter the Vertices </h2>
51
 
    
52
 
    <p>
53
 
    Insert the grid vertices by calling
54
 
    </p>
55
 
    
56
 
    <pre>
57
 
    factory.insertVertex(const FieldVector&lt;double,dimworld&gt;& position);
58
 
    </pre>
59
 
 
60
 
    <p>
61
 
    for each vertex.  The order of insertion determines the level- and leaf indices
62
 
    of your level 0 vertices.
63
 
    </p>
64
 
 
65
 
    
66
 
    <h2> 3) Enter the elements </h2>
67
 
    
68
 
    <p>
69
 
    For each element call
70
 
    </p>
71
 
    
72
 
    <pre>
73
 
    factory.insertElement(Dune::GeometryType type, const std::vector&lt;int&gt;& vertices);
74
 
    </pre>      
75
 
    
76
 
    <p>
77
 
    The parameters are
78
 
    </p>
79
 
    
80
 
    <ul>
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>
84
 
    </ul>
85
 
    
86
 
    <p>
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.
89
 
    
90
 
    <h2> 4) Parametrized Domains </h2>
91
 
    
92
 
    <p>
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.
98
 
    </p>
99
 
    
100
 
    <p>
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
104
 
    from
105
 
    <pre>
106
 
    template &lt;int dimworld&gt; Dune::BoundarySegment
107
 
    </pre>
108
 
    This is an abstract base class which requires you to overload the method
109
 
    
110
 
    <pre>
111
 
    virtual FieldVector&lt; double, dimworld &gt; operator() (const FieldVector&lt; double, dimworld-1 &gt; &local)
112
 
    </pre>
113
 
    
114
 
    <p>
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
117
 
    </p>
118
 
    <pre>
119
 
    factory.insertBoundarySegment(const std::vector&lt;int&gt;& vertices, 
120
 
                               const BoundarySegment&lt;dimworld&gt; *boundarySegment);
121
 
    </pre>
122
 
    
123
 
    <p>
124
 
    Control over the allocated objects is taken from you, and the grid object
125
 
    will take care of their destruction.
126
 
    </p>
127
 
    
128
 
    <h2> 5) Finish construction </h2>
129
 
    
130
 
    <p>
131
 
    To finish off the construction of the UGGrid object call
132
 
    </p>
133
 
    
134
 
    <pre>
135
 
    UGGrid<dim>* grid = factory.createGrid();
136
 
    </pre>
137
 
 
138
 
    <p>
139
 
    This time it is you who gets full responsibility for the allocated object.
140
 
    </p>
141
 
    
142
 
    <h2> Loading a Grid on a Parallel Machine </h2>
143
 
    <p>
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.
150
 
    </p>
151
 
 
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.
156
 
    </p>
157
 
    */
158
 
    template <int dimworld>
159
 
    class GridFactory<UGGrid<dimworld> > : public GridFactoryInterface<UGGrid<dimworld> > {
160
 
 
161
 
        /** \brief Type used by the grid for coordinates */
162
 
        typedef typename UGGrid<dimworld>::ctype ctype;
163
 
 
164
 
        // UGGrid only in 2d and 3d
165
 
        dune_static_assert(dimworld==2 || dimworld || 3, "UGGrid only in 2d and 3d");
166
 
 
167
 
    public:
168
 
 
169
 
        /** \brief Default constructor */
170
 
        GridFactory();
171
 
 
172
 
        /** \brief Constructor for a given grid object 
173
 
 
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.
177
 
 
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.
181
 
         */
182
 
        GridFactory(UGGrid<dimworld>* grid);
183
 
        
184
 
        /** \brief Destructor */
185
 
        ~GridFactory();
186
 
 
187
 
        /** \brief Insert a vertex into the coarse grid */
188
 
        virtual void insertVertex(const FieldVector<ctype,dimworld>& pos);
189
 
 
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
193
 
        */
194
 
        virtual void insertElement(const GeometryType& type,
195
 
                                   const std::vector<unsigned int>& vertices);
196
 
 
197
 
        /** \brief Method to insert a boundary segment into a coarse grid
198
 
 
199
 
        Using this method is optional.  It only influences the ordering of the segments
200
 
 
201
 
            \param vertices The indices of the vertices of the segment
202
 
        */
203
 
        void insertBoundarySegment(const std::vector<unsigned int>& vertices);
204
 
 
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.
208
 
        */
209
 
        void insertBoundarySegment(const std::vector<unsigned int>& vertices,
210
 
                                   const shared_ptr<BoundarySegment<dimworld> > &boundarySegment);
211
 
 
212
 
 
213
 
        /** \brief Finalize grid creation and hand over the grid
214
 
 
215
 
        The receiver takes responsibility of the memory allocated for the grid
216
 
        */
217
 
        virtual UGGrid<dimworld>* createGrid();
218
 
 
219
 
    private:
220
 
 
221
 
        // Initialize the grid structure in UG
222
 
        void createBegin();
223
 
 
224
 
        // Pointer to the grid being built
225
 
        UGGrid<dimworld>* grid_;
226
 
 
227
 
        // True if the factory allocated the grid itself, false if the
228
 
        // grid was handed over from the outside
229
 
        bool factoryOwnsGrid_;
230
 
 
231
 
        /** \brief Buffer for the vertices of each explicitly given boundary segment */
232
 
        std::vector<array<int, dimworld*2-2> > boundarySegmentVertices_;
233
 
 
234
 
        /** \brief While inserting the elements this array records the number of
235
 
            vertices of each element. */
236
 
        std::vector<unsigned char> elementTypes_;
237
 
 
238
 
        /** \brief While inserting the elements this array records the vertices
239
 
            of the elements. */
240
 
        std::vector<unsigned int> elementVertices_;
241
 
 
242
 
        /** \brief Buffer the vertices until createend() is called */
243
 
        std::vector<FieldVector<double, dimworld> > vertexPositions_;
244
 
 
 
23
  /** \brief Specialization of the generic GridFactory for UGGrid
 
24
 
 
25
      \ingroup GridFactory
 
26
 
 
27
     <p>
 
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:
 
34
     </p>
 
35
 
 
36
     <pre>
 
37
     UGGrid&lt;3&gt;* readMyFileFormat(const std::string& filename)
 
38
     </pre>
 
39
 
 
40
     Now, in order to create a valid UGGrid object do the
 
41
     following steps:
 
42
 
 
43
     <h2> 1) Create a GridFactory Object </h2>
 
44
     <p>
 
45
     Get a new GridFactory object by calling
 
46
     <pre>
 
47
     GridFactory<UGGrid<dim> > factory;
 
48
     </pre>
 
49
 
 
50
     <h2> 2)  Enter the Vertices </h2>
 
51
 
 
52
     <p>
 
53
     Insert the grid vertices by calling
 
54
     </p>
 
55
 
 
56
     <pre>
 
57
     factory.insertVertex(const FieldVector&lt;double,dimworld&gt;& position);
 
58
     </pre>
 
59
 
 
60
     <p>
 
61
     for each vertex.  The order of insertion determines the level- and leaf indices
 
62
     of your level 0 vertices.
 
63
     </p>
 
64
 
 
65
 
 
66
     <h2> 3) Enter the elements </h2>
 
67
 
 
68
     <p>
 
69
     For each element call
 
70
     </p>
 
71
 
 
72
     <pre>
 
73
     factory.insertElement(Dune::GeometryType type, const std::vector&lt;int&gt;& vertices);
 
74
     </pre>
 
75
 
 
76
     <p>
 
77
     The parameters are
 
78
     </p>
 
79
 
 
80
     <ul>
 
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>
 
84
     </ul>
 
85
 
 
86
     <p>
 
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.
 
89
 
 
90
     <h2> 4) Parametrized Domains </h2>
 
91
 
 
92
     <p>
 
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.
 
98
     </p>
 
99
 
 
100
     <p>
 
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
 
104
     from
 
105
     <pre>
 
106
     template &lt;int dimworld&gt; Dune::BoundarySegment
 
107
     </pre>
 
108
     This is an abstract base class which requires you to overload the method
 
109
 
 
110
     <pre>
 
111
     virtual FieldVector&lt; double, dimworld &gt; operator() (const FieldVector&lt; double, dimworld-1 &gt; &local)
 
112
     </pre>
 
113
 
 
114
     <p>
 
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
 
117
     </p>
 
118
     <pre>
 
119
     factory.insertBoundarySegment(const std::vector&lt;int&gt;& vertices,
 
120
                             const BoundarySegment&lt;dimworld&gt; *boundarySegment);
 
121
     </pre>
 
122
 
 
123
     <p>
 
124
     Control over the allocated objects is taken from you, and the grid object
 
125
     will take care of their destruction.
 
126
     </p>
 
127
 
 
128
     <h2> 5) Finish construction </h2>
 
129
 
 
130
     <p>
 
131
     To finish off the construction of the UGGrid object call
 
132
     </p>
 
133
 
 
134
     <pre>
 
135
     UGGrid<dim>* grid = factory.createGrid();
 
136
     </pre>
 
137
 
 
138
     <p>
 
139
     This time it is you who gets full responsibility for the allocated object.
 
140
     </p>
 
141
 
 
142
     <h2> Loading a Grid on a Parallel Machine </h2>
 
143
     <p>
 
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.
 
150
     </p>
 
151
 
 
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.
 
156
     </p>
 
157
   */
 
158
  template <int dimworld>
 
159
  class GridFactory<UGGrid<dimworld> > : public GridFactoryInterface<UGGrid<dimworld> > {
 
160
 
 
161
    /** \brief Type used by the grid for coordinates */
 
162
    typedef typename UGGrid<dimworld>::ctype ctype;
 
163
 
 
164
    // UGGrid only in 2d and 3d
 
165
    dune_static_assert(dimworld==2 || dimworld || 3, "UGGrid only in 2d and 3d");
 
166
 
 
167
  public:
 
168
 
 
169
    /** \brief Default constructor */
 
170
    GridFactory();
 
171
 
 
172
    /** \brief Constructor for a given grid object
 
173
 
 
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.
 
177
 
 
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.
 
181
     */
 
182
    GridFactory(UGGrid<dimworld>* grid);
 
183
 
 
184
    /** \brief Destructor */
 
185
    ~GridFactory();
 
186
 
 
187
    /** \brief Insert a vertex into the coarse grid */
 
188
    virtual void insertVertex(const FieldVector<ctype,dimworld>& pos);
 
189
 
 
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
 
193
     */
 
194
    virtual void insertElement(const GeometryType& type,
 
195
                               const std::vector<unsigned int>& vertices);
 
196
 
 
197
    /** \brief Method to insert a boundary segment into a coarse grid
 
198
 
 
199
       Using this method is optional.  It only influences the ordering of the segments
 
200
 
 
201
        \param vertices The indices of the vertices of the segment
 
202
     */
 
203
    void insertBoundarySegment(const std::vector<unsigned int>& vertices);
 
204
 
 
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.
 
208
     */
 
209
    void insertBoundarySegment(const std::vector<unsigned int>& vertices,
 
210
                               const shared_ptr<BoundarySegment<dimworld> > &boundarySegment);
 
211
 
 
212
 
 
213
    /** \brief Finalize grid creation and hand over the grid
 
214
 
 
215
       The receiver takes responsibility of the memory allocated for the grid
 
216
     */
 
217
    virtual UGGrid<dimworld>* createGrid();
 
218
 
 
219
    static const int dimension = UGGrid<dimworld>::dimension;
 
220
 
 
221
    template< int codim >
 
222
    struct Codim
 
223
    {
 
224
      typedef typename UGGrid<dimworld>::template Codim< codim >::Entity Entity;
245
225
    };
246
226
 
 
227
    /** \brief Return the number of the element in the order of insertion into the factory
 
228
     *
 
229
     * For UGGrid elements this number is the same as the element level index
 
230
     */
 
231
    virtual unsigned int
 
232
    insertionIndex ( const typename Codim< 0 >::Entity &entity ) const
 
233
    {
 
234
      return UG_NS<dimension>::levelIndex(grid_->getRealImplementation(entity).target_);
 
235
    }
 
236
 
 
237
    /** \brief Return the number of the vertex in the order of insertion into the factory
 
238
     *
 
239
     * For UGGrid vertices this number is the same as the vertex level index
 
240
     */
 
241
    virtual unsigned int
 
242
    insertionIndex ( const typename Codim< dimension >::Entity &entity ) const
 
243
    {
 
244
      return UG_NS<dimension>::levelIndex(grid_->getRealImplementation(entity).target_);
 
245
    }
 
246
 
 
247
  private:
 
248
 
 
249
    // Initialize the grid structure in UG
 
250
    void createBegin();
 
251
 
 
252
    // Pointer to the grid being built
 
253
    UGGrid<dimworld>* grid_;
 
254
 
 
255
    // True if the factory allocated the grid itself, false if the
 
256
    // grid was handed over from the outside
 
257
    bool factoryOwnsGrid_;
 
258
 
 
259
    /** \brief Buffer for the vertices of each explicitly given boundary segment */
 
260
    std::vector<array<int, dimworld*2-2> > boundarySegmentVertices_;
 
261
 
 
262
    /** \brief While inserting the elements this array records the number of
 
263
        vertices of each element. */
 
264
    std::vector<unsigned char> elementTypes_;
 
265
 
 
266
    /** \brief While inserting the elements this array records the vertices
 
267
        of the elements. */
 
268
    std::vector<unsigned int> elementVertices_;
 
269
 
 
270
    /** \brief Buffer the vertices until createend() is called */
 
271
    std::vector<FieldVector<double, dimworld> > vertexPositions_;
 
272
 
 
273
  };
 
274
 
247
275
}
248
276
 
249
277
#endif