Line data Source code
1 : /*
2 : * Copyright (c) 2009-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef __H__LIB_GRID__GRID__
34 : #define __H__LIB_GRID__GRID__
35 :
36 : #include <vector>
37 : #include <list>
38 : #include <memory>
39 : #include <boost/function.hpp>
40 : #include "common/util/message_hub.h"
41 : #include "common/ug_config.h"
42 : #include "grid_constants.h"
43 : #include "grid_base_objects.h"
44 : #include "grid_observer.h"
45 : #include "grid_object_collection.h"
46 : #include "element_storage.h"
47 : #include "grid_base_object_traits.h"
48 :
49 : // Define PROFILE_GRID to profile some often used gird-methods
50 : //#define PROFILE_GRID
51 : #ifdef PROFILE_GRID
52 : #include "common/profiler/profiler.h"
53 : #define GRID_PROFILE_FUNC() PROFILE_FUNC()
54 : #define GRID_PROFILE(name) PROFILE_BEGIN(name)
55 : #define GRID_PROFILE_END() PROFILE_END()
56 : #else
57 : #define GRID_PROFILE_FUNC()
58 : #define GRID_PROFILE(name)
59 : #define GRID_PROFILE_END()
60 : #endif
61 :
62 : namespace ug
63 : {
64 :
65 : // predeclaration of the distributed grid manager, which handles parallelization
66 : // of grids. If you want to use it, you have to include
67 : // "lib_grid/parallelization/distributed_grid.h"
68 : class DistributedGridManager;
69 :
70 : // predeclaration of the periodic boundary identifier, which handles the master/slave
71 : // identification of grid elements. If you want to use it, you have to include
72 : // "lib_grid/tools/periodic_boundary_identifier.h"
73 : class PeriodicBoundaryManager;
74 :
75 : /**
76 : * \brief Grid, MultiGrid and GridObjectCollection are contained in this group
77 : * \defgroup lib_grid_grid grid
78 : * \ingroup lib_grid
79 : * \{ */
80 :
81 : ////////////////////////////////////////////////////////////////////////////////////////////////
82 : // Grid
83 : /// Manages the elements of a grid and their interconnection.
84 : /**
85 : * The Grid class is the heart of libGrid. It can be used to create elements of
86 : * custom types, for example Vertices, Triangles or Tetrahedrons.
87 : * All elements have to be derived from either Vertex, Edge, Face or Volume
88 : * and have to specialize the template-class geometry_traits
89 : * (both defined in grid_base_objects.h).
90 : * The grid can automatically create information about connected geometric objects.
91 : * You could for example query a face for associated volumes.
92 : * Associated elements are however only stored, if the according options are set.
93 : * This reduces storage space if only particular associations are required.
94 : * Since these options can be changed dynamically at runtime on could in practice always
95 : * start with a grid holding minimal connection informations. Options are then enabled
96 : * on the fly, as required by called methods. Note however that some algorithms do
97 : * run faster if particular options are enabled.
98 : * On the other hand a grid serves as the connection between geometric objects and their
99 : * associated data. This connection is realized by so called attachments.
100 : * You can attach data to vertices, edges, faces, and volumes. Note, that data is attached
101 : * to all elements of one type at once. No sub-types are considered. This allows for
102 : * efficient storage and data-access.
103 : * thanks to this way of storing data, methods and classes can temporarily attach data
104 : * to the grids elements and thus store and access data of given elements in an
105 : * efficient way. The data-access is handled by so called attachment-accessors.
106 : * Grid defines one for each base-type as well as a generic one.
107 : *
108 : * The Grid class itself only knows about the concepts of Vertex, Edge, Face
109 : * and Volume (classes Vertex, Edge, Face, Volume).
110 : * In order to implement algorithms one needs more specialized element-types,
111 : * like Triangles, Quadrilaterals or Tetrahedrons.
112 : * Those special types are supported by the use of templates. All that a custom type
113 : * has to satisfy is that it is derived from one of the four basic elements and
114 : * that it specializes the class geometry_traits.
115 : * By calling Grids methods with those specialized types as template parameters,
116 : * you can create, erase and iterate over specialized elements.
117 : * You could for example iterate over all faces using the calls
118 : * Grid::begin<Face>() and Grid::end<Face>() (or by calling Grid::faces_begin() and Grid::faces_end()).
119 : * if you want to iterate only over elements of type Triangle (given this type has
120 : * been defined), you could call
121 : * Grid::begin<Triangle>() and Grid::end<Triangle>().
122 : * This is applicable to all methods that take an TGeomObj as their template parameter.
123 : * If a template function takes the parameter TGeomObjClass, then only one of the four
124 : * base objects should be passed (Vertex, Edge, Face and Volume).
125 : * This use if templates allows for a arbitrary number of custom elements, without
126 : * requiring any changes to the Grid-class itself.
127 : *
128 : * The Grid class features a message-hub, which can be used to distribute messages
129 : * to registered callbacks.
130 : */
131 : class UG_API Grid
132 : {
133 : public:
134 : /// The traits class holds some important types for each element-type
135 : template <class TElem>
136 : struct traits{
137 : typedef typename TElem::grid_base_object base_object;
138 : typedef ug::ElementStorage<base_object> ElementStorage;
139 : typedef typename ElementStorage::AttachmentPipe AttachmentPipe;
140 : typedef typename ElementStorage::AttachedElementList AttachedElementList;
141 : typedef typename ElementStorage::SectionContainer SectionContainer;
142 :
143 : typedef typename geometry_traits<TElem>::iterator iterator;
144 : typedef typename geometry_traits<TElem>::const_iterator const_iterator;
145 :
146 : typedef PointerConstArray<TElem*> secure_container;
147 :
148 : // CALLBACKS
149 : /// callback type for the elements base type.
150 : typedef boost::function<bool (base_object*)> callback;
151 : };
152 :
153 : /// Convenience access to grid elements
154 : /** \{ */
155 : typedef traits<Vertex> vertex_traits;
156 : typedef traits<Edge> edge_traits;
157 : typedef traits<Face> face_traits;
158 : typedef traits<Volume> volume_traits;
159 : /** \} */
160 :
161 : /// Container to store associated vertices.
162 : typedef traits<Vertex>::secure_container SecureVertexContainer;
163 : /// Container to store associated edges.
164 : typedef traits<Edge>::secure_container SecureEdgeContainer;
165 : /// Container to store associated faces.
166 : typedef traits<Face>::secure_container SecureFaceContainer;
167 : /// Container to store associated volumes.
168 : typedef traits<Volume>::secure_container SecureVolumeContainer;
169 :
170 : /// the attachment-pipe used by Grid
171 : typedef ug::AttachmentPipe<Vertex*, VertexElementStorage> VertexAttachmentPipe;
172 : typedef ug::AttachmentPipe<Edge*, EdgeElementStorage> EdgeAttachmentPipe;
173 : typedef ug::AttachmentPipe<Face*, FaceElementStorage> FaceAttachmentPipe;
174 : typedef ug::AttachmentPipe<Volume*, VolumeElementStorage> VolumeAttachmentPipe;
175 :
176 :
177 : /// the generic attachment-accessor for access to grids attachment pipes.
178 : template <class TElem, class TAttachment>
179 : class AttachmentAccessor : public ug::AttachmentAccessor<typename TElem::grid_base_object*,
180 : TAttachment,
181 : typename traits<TElem>::ElementStorage>
182 : {
183 : public:
184 : AttachmentAccessor();
185 : AttachmentAccessor(const AttachmentAccessor& aa);
186 : AttachmentAccessor(Grid& grid, TAttachment& a);
187 : AttachmentAccessor(Grid& grid, TAttachment& a, bool autoAttach);
188 :
189 : inline bool access(Grid& grid, TAttachment& a)
190 : {
191 : return ug::AttachmentAccessor<typename TElem::grid_base_object*,
192 : TAttachment,
193 : typename traits<TElem>::ElementStorage>::
194 6 : access(grid.get_attachment_pipe<TElem>(), a);
195 : }
196 : };
197 :
198 : // half-specialized AttachmentAccessors:
199 : template <class TAttachment>
200 : class VertexAttachmentAccessor : public AttachmentAccessor<Vertex, TAttachment>
201 : {
202 : public:
203 : VertexAttachmentAccessor();
204 : VertexAttachmentAccessor(const VertexAttachmentAccessor& aa);
205 : VertexAttachmentAccessor(Grid& grid, TAttachment& a);
206 : VertexAttachmentAccessor(Grid& grid, TAttachment& a, bool autoAttach);
207 : };
208 :
209 : template <class TAttachment>
210 : class EdgeAttachmentAccessor : public AttachmentAccessor<Edge, TAttachment>
211 : {
212 : public:
213 : EdgeAttachmentAccessor();
214 : EdgeAttachmentAccessor(const EdgeAttachmentAccessor& aa);
215 : EdgeAttachmentAccessor(Grid& grid, TAttachment& a);
216 : EdgeAttachmentAccessor(Grid& grid, TAttachment& a, bool autoAttach);
217 : };
218 :
219 : template <class TAttachment>
220 : class FaceAttachmentAccessor : public AttachmentAccessor<Face, TAttachment>
221 : {
222 : public:
223 : FaceAttachmentAccessor();
224 : FaceAttachmentAccessor(const FaceAttachmentAccessor& aa);
225 : FaceAttachmentAccessor(Grid& grid, TAttachment& a);
226 : FaceAttachmentAccessor(Grid& grid, TAttachment& a, bool autoAttach);
227 : };
228 :
229 : template <class TAttachment>
230 : class VolumeAttachmentAccessor : public AttachmentAccessor<Volume, TAttachment>
231 : {
232 : public:
233 : VolumeAttachmentAccessor();
234 : VolumeAttachmentAccessor(const VolumeAttachmentAccessor& aa);
235 : VolumeAttachmentAccessor(Grid& grid, TAttachment& a);
236 : VolumeAttachmentAccessor(Grid& grid, TAttachment& a, bool autoAttach);
237 : };
238 :
239 : /// Container used to store associated vertices
240 : typedef std::vector<Vertex*> VertexContainer;
241 : /// Container used to store associated edges
242 : typedef std::vector<Edge*> EdgeContainer;
243 : /// Container used to store associated faces
244 : typedef std::vector<Face*> FaceContainer;
245 : /// Container used to store associated volumes
246 : typedef std::vector<Volume*> VolumeContainer;
247 :
248 : /// used to iterate over associated edges of vertices, faces and volumes
249 : typedef EdgeContainer::iterator AssociatedEdgeIterator;
250 : /// used to iterate over associated faces of vertices, edges and volumes
251 : typedef FaceContainer::iterator AssociatedFaceIterator;
252 : /// used to iterate over associated volumes of vertices, edges and faces
253 : typedef VolumeContainer::iterator AssociatedVolumeIterator;
254 :
255 : public:
256 : ////////////////////////////////////////////////
257 : // constructors and destructor
258 : /// initialises the grid and sets the option GRIDOPT_DEFAULT.
259 : /** Pass a custom option to the alternative constructor in order
260 : * to initialise the grid with your options.
261 : * \sa Grid(uint options)*/
262 : Grid();
263 :
264 : /// initialises the grid with the given option.
265 : /** pass an or-combination of constants enumerated in
266 : * VertexOptions, EdgeOptions, FaceOptions, VolumeOptions and GridOptions.*/
267 : Grid(uint options);
268 :
269 : /// copies all elements and some attachments from the passed grid to this grid.
270 : /** While all elements and the options are copied completely from the source-grid,
271 : * the attachments are only copied if their pass-on behaviour is set to true.*/
272 : Grid(const Grid& grid);
273 :
274 : virtual ~Grid();
275 :
276 : /// copies all elements and some attachments from the passed grid to this grid.
277 : /** While all elements and the options are copied completely from the source-grid,
278 : * the attachments are only copied if their pass-on behaviour is set to true.
279 : * Attachments that were already attached to this grid are removed prior to
280 : * copying if their pass-on behaviour was set to true. They will be kept otherwise.
281 : * This is relevant to ensure that observers like GridSubsetHandler
282 : * will work after the assignment.*/
283 : Grid& operator = (const Grid& grid);
284 :
285 : ////////////////////////////////////////////////
286 : // grid options
287 : /** you can pass any option enumerated in GridOptions or specify a custom option
288 : * using an or-combination of the constants enumerated in
289 : * VertexOptions, EdgeOptions, FaceOptions and VolumeOptions.
290 : * See GridOptions for possible combinations.*/
291 : void set_options(uint options);
292 : uint get_options() const;
293 : void enable_options(uint options); ///< see set_options for a description of valid parameters.
294 : void disable_options(uint options); ///< see set_options for a description of valid parameters.
295 : bool option_is_enabled(uint option) const;///< see set_options for a description of valid parameters.
296 :
297 : ////////////////////////////////////////////////
298 : // parallelism
299 : /// tell the grid whether it will be used in a serial or in a parallel environment.
300 : /** If parallelism is enabled, the grid will internally create a distributed grid
301 : * manager, which will handle horizontal and vertical process interfaces. The
302 : * manager can be queried through the method ug::Grid::distributed_grid_manager.
303 : * If false is passed and a distributed grid manager already existed, it will
304 : * be destroyed.
305 : * parallelism is disabled by default.
306 : * \note set_parallel(true) may currently only be executed on ug::MultiGrid.
307 : * There is currently no parallelization support for plain ug::Grid.
308 : * \note parallelism may only be activated if ug was compiled with PARALLEL=ON.*/
309 : void set_parallel(bool parallel);
310 :
311 : /// returns true if the grid is prepared for parallel computations.
312 : /** If the method returns true, it is also clear, that a distributed grid manager
313 : * exists in the grid. The manager can be queried through ug::Grid::distributed_grid_manager.*/
314 : inline bool is_parallel() const;
315 :
316 : /// returns a pointer to the associated distributed grid manager.
317 : /** The method returns NULL, if no distributed grid manager for the given
318 : * grid exists. This should be the case for serial environments or for
319 : * serial grids in parallel environments.
320 : * Use ug::Grid::set_parallel() to enable or disable parallelism in a grid.
321 : * You have to include "lib_grid/parallelization/distributed_grid.h" to access
322 : * methods of a distributed grid manager.
323 : * \{ */
324 : inline DistributedGridManager* distributed_grid_manager();
325 : inline const DistributedGridManager* distributed_grid_manager() const;
326 : /** \} */
327 :
328 : ////////////////////////////////////////////////
329 : // periodic boundaries
330 : /// tell the grid whether it may contain periodic boundaries.
331 : /**
332 : * If the grid may contain periodic boundaries, it instantiate a PeriodicBoundaryManager.*/
333 : void set_periodic_boundaries(bool);
334 : /// returns true, if grid has the possibility to handle periodic boundaries.
335 : bool has_periodic_boundaries() const;
336 :
337 : /// returns a pointer to the associated periodic boundary manager.
338 : /** The method returns NULL, if no periodic boundary get_attachment_accessor for the given
339 : * grid exists.
340 : * Use ug::Grid::set_periodic_boundaries() to enable or disable periodic boundaries in a grid.
341 : * You have to include "lib_grid/tools/periodic_boundary_manager.h" to access
342 : * methods of the peridodic boundary manager.
343 : * \{ */
344 : PeriodicBoundaryManager* periodic_boundary_manager();
345 : const PeriodicBoundaryManager* periodic_boundary_manager() const;
346 : /** \} */
347 :
348 :
349 : ////////////////////////////////////////////////
350 : // clear
351 : /// clears the grids geometry and attachments
352 : void clear();
353 : /// clears the grids geometry. Registered attachments remain.
354 : void clear_geometry();
355 : /// clears the grids attachments. The geometry remains.
356 : void clear_attachments();
357 :
358 : ////////////////////////////////////////////////
359 : // element creation
360 : /// create a custom element.
361 : /**
362 : * TGeomObj has to be a geometric object type as described in grid_base_objects.h.
363 : * You may optionally specify a GridObject pParent.
364 : * pParent may be used by observers to initialize the created object in a specific way.
365 : */
366 : template<class TGeomObj>
367 : typename geometry_traits<TGeomObj>::iterator
368 : create(GridObject* pParent = NULL);
369 :
370 : /// create a custom element from a descriptor.
371 : /**
372 : * TGeomObj has to be a geometric object type as described in grid_base_objects.h.
373 : * You may optionally specify a GridObject pParent.
374 : * pParent may be used by observers to initialize the created object in a specific way.
375 : */
376 : template <class TGeomObj>
377 : typename geometry_traits<TGeomObj>::iterator
378 : create(const typename geometry_traits<TGeomObj>::Descriptor& descriptor,
379 : GridObject* pParent = NULL);
380 :
381 : /// create a custom element and replaces an old one.
382 : /**
383 : * Be sure, that TGeomObj has the same reference-element as pReplaceMe.
384 : * Similar to create. With pReplaceMe you may specify an element of the same base-type
385 : * as TGeomObj, which shall be replaced. The replaced element will be deleted from grid.
386 : * pReplaceMe will be treated as pParent for GridObservers.
387 : *
388 : * Calls pass_on_values.
389 : *
390 : * Notes for GridObservers:
391 : * create_and_replace will call in the given order (replace elem with the appropriate name).
392 : * - elem_created(newElem)
393 : * - elem_to_be_replaced(oldElem, newElem)
394 : * - elem_to_be_deleted(oldElem)
395 : */
396 : template <class TGeomObj>
397 : typename geometry_traits<TGeomObj>::iterator
398 : create_and_replace(typename geometry_traits<TGeomObj>::grid_base_object* pReplaceMe);
399 :
400 : /// this method creates a new vertex, which has the same type as pCloneMe.
401 : VertexIterator create_by_cloning(Vertex* pCloneMe, GridObject* pParent = NULL);
402 :
403 : /// this method creates a new edge, which has the same type as pCloneMe.
404 : EdgeIterator create_by_cloning(Edge* pCloneMe, const IVertexGroup& ev, GridObject* pParent = NULL);
405 :
406 : /// this method creates a new face, which has the same type as pCloneMe.
407 : FaceIterator create_by_cloning(Face* pCloneMe, const IVertexGroup& fv, GridObject* pParent = NULL);
408 :
409 : /// this method creates a new volume, which has the same type as pCloneMe.
410 : VolumeIterator create_by_cloning(Volume* pCloneMe, const IVertexGroup& vv, GridObject* pParent = NULL);
411 :
412 : /// Reserves memory for the creation of the given object type
413 : /** Calls to this method are optional, but can improve runtime.
414 : * Specify the total number of objects which the grid should be
415 : * capable to hold (if more are required, the grid will automatically
416 : * adjust sizes)
417 : */
418 : template <class TGeomObj>
419 : void reserve(size_t num);
420 :
421 : ////////////////////////////////////////////////
422 : // element deletion
423 : void erase(GridObject* geomObj);
424 : void erase(Vertex* vrt);
425 : void erase(Edge* edge);
426 : void erase(Face* face);
427 : void erase(Volume* vol);
428 :
429 : /**\todo: This erase method can cause problems if used with multi-grids.*/
430 : template <class GeomObjIter>
431 : void erase(const GeomObjIter& iterBegin, const GeomObjIter& iterEnd);
432 :
433 : template <class TGeomObj>
434 : void clear();
435 :
436 : ////////////////////////////////////////////////
437 : // replace
438 : /// Replace vrtOld with vrtNew.
439 : /**
440 : * WARNING: USE THIS METHOD WITH CARE!
441 : * vrtOld and vrtNew have both to be registered vertices of this grid.
442 : * vrtOld will be erased during this method.
443 : * Make sure that no geometric object in the grid references both
444 : * vrtOld and vrtNew.
445 : * This method iterates through all geometric objects that are
446 : * connected with vrtOld and replaces vrtOld by vrtNew in each.
447 : * Connectivity information will be updated on the fly.
448 : * Elements that reference both vrtOld and vrtNew will reference
449 : * vrtNew two times after the completion of replace_vertex.
450 : * This leads to degenerate elements and most likely to bad
451 : * runtime behavior.
452 : *
453 : * requires options in GRIDOPT_VERTEXCENTRIC_INTERCONNECTION.
454 : */
455 : bool replace_vertex(Vertex* vrtOld, Vertex* vrtNew);
456 :
457 : /// checks if replace_vertex would be a valid operation
458 : /**
459 : * Checks if a call of replace_vertex with vertices vrtOld and vrtNew
460 : * would lead to degenerate elements. If so false is returned.
461 : * If not true is returned.
462 : *
463 : * requires options in GRIDOPT_VERTEXCENTRIC_INTERCONNECTION.
464 : */
465 : bool replace_vertex_is_valid(Vertex* vrtOld, Vertex* vrtNew);
466 :
467 : /// notifies the grid that two objects will be merged.
468 : /** The grid forwards this notification to its GridObservers.
469 : * The notification is not relevant for the grid itself.
470 : * \{ */
471 : void objects_will_be_merged(Vertex* target, Vertex* elem1,
472 : Vertex* elem2);
473 : void objects_will_be_merged(Edge* target, Edge* elem1,
474 : Edge* elem2);
475 : void objects_will_be_merged(Face* target, Face* elem1,
476 : Face* elem2);
477 : void objects_will_be_merged(Volume* target, Volume* elem1,
478 : Volume* elem2);
479 : /** \} */
480 : /*
481 : /// VrtPairIterator has to be an iterator with value-type std::pair<Vertex*, Vertex*>
482 : template <class VrtPairIter>
483 : void replace_vertices(VrtPairIter& iterBegin, VrtPairIter& iterEnd);
484 : */
485 :
486 : ////////////////////////////////////////////////
487 : // geometric-object-collection
488 : /// returns the the GridObjectCollection of the grid:
489 : virtual GridObjectCollection get_grid_objects();
490 :
491 : ////////////////////////////////////////////////
492 : /// flips the orientation of an edge.
493 : void flip_orientation(Edge* e);
494 :
495 : ////////////////////////////////////////////////
496 : /// flips the orientation of a face.
497 : void flip_orientation(Face* f);
498 :
499 : ////////////////////////////////////////////////
500 : /// flips the orientation of a volume.
501 : void flip_orientation(Volume* vol);
502 :
503 : ////////////////////////////////////////////////
504 : // Iterators
505 : template <class TGeomObj>
506 : typename geometry_traits<TGeomObj>::iterator
507 : begin();
508 :
509 : template <class TGeomObj>
510 : typename geometry_traits<TGeomObj>::iterator
511 : end();
512 :
513 0 : inline VertexIterator vertices_begin() {return begin<Vertex>();}
514 : inline VertexIterator vertices_end() {return end<Vertex>();}
515 2 : inline EdgeIterator edges_begin() {return begin<Edge>();}
516 : inline EdgeIterator edges_end() {return end<Edge>();}
517 4 : inline FaceIterator faces_begin() {return begin<Face>();}
518 : inline FaceIterator faces_end() {return end<Face>();}
519 4 : inline VolumeIterator volumes_begin() {return begin<Volume>();}
520 : inline VolumeIterator volumes_end() {return end<Volume>();}
521 :
522 : template <class TGeomObj>
523 : typename geometry_traits<TGeomObj>::const_iterator
524 : begin() const;
525 :
526 : template <class TGeomObj>
527 : typename geometry_traits<TGeomObj>::const_iterator
528 : end() const;
529 :
530 : /// returns the first element of the given type.
531 : /** Make sure that elements of the given type exist!
532 : * Behaviour is undefined, if not.*/
533 : template <class TGeomObj> TGeomObj* front();
534 :
535 : /// returns the last element of the given type.
536 : /** Make sure that elements of the given type exist!
537 : * Behaviour is undefined, if not.*/
538 : template <class TGeomObj> TGeomObj* back();
539 :
540 : // element manipulation
541 : /*
542 : void set_vertices(Edge* e, EdgeDesctiptor& ed);
543 : void set_vertices(Face* f, FaceDescriptor& fd);
544 : void set_vertices(Volume* v, VolumeDescriptor& vd);
545 : */
546 :
547 : ////////////////////////////////////////////////
548 : // element numbers
549 : template <class TGeomObj>
550 : size_t num() const;
551 0 : inline size_t num_vertices() const {return num<Vertex>();}
552 0 : inline size_t num_edges() const {return num<Edge>();}
553 0 : inline size_t num_faces() const {return num<Face>();}
554 0 : inline size_t num_volumes()const {return num<Volume>();}
555 :
556 : size_t vertex_fragmentation(); ///< returns the number of unused vertex-data-entries.
557 : size_t edge_fragmentation(); ///< returns the number of unused edge-data-entries.
558 : size_t face_fragmentation(); ///< returns the number of unused face-data-entries.
559 : size_t volume_fragmentation(); ///< returns the number of unused volume-data-entries.
560 :
561 : /// returns the size of the associated attachment containers.
562 : /** valid types for TGeomObj are Vertex, Edge, Face, Volume.*/
563 : template <class TGeomObj>
564 : size_t attachment_container_size() const;
565 :
566 : ////////////////////////////////////////////////
567 : // connectivity-information
568 : /// returns the edge between v1 and v2, if it exists. Returns NULL if not.
569 : Edge* get_edge(Vertex* v1, Vertex* v2);
570 : /// returns the edge that is described by ev.
571 : /** Note that you may pass an EdgeDescriptor to this method.*/
572 : Edge* get_edge(const EdgeVertices& ev);
573 : /// If it exists, this method returns the i-th edge of the given Face. If not NULL is returned.
574 : /** To make sure that associated edges always exist, enable the grid-option
575 : * FACEOPT_AUTOGENERATE_EDGES.
576 : * For maximal performance, the option FACEOPT_STORE_ASSOCIATED_EDGES
577 : * should be enabled.
578 : * \note If all edges of a face have to be processed, it may be faster
579 : * to get all edges in one single call.
580 : * This can be done using Grid::associated_elements.*/
581 : Edge* get_edge(Face* f, int ind);
582 : /// If it exists, this method returns the i-th edge of the given Volume. If not NULL is returned.
583 : /** To make sure that associated edges always exist, enable the grid-option
584 : * VOLOPT_AUTOGENERATE_EDGES.
585 : * For maximal performance, the option VOLOPT_STORE_ASSOCIATED_EDGES
586 : * should be enabled.
587 : * \note If all edges of a volume have to be processed, it may be faster
588 : * to get all edges in one single call.
589 : * This can be done using Grid::associated_elements.*/
590 : Edge* get_edge(Volume* v, int ind);
591 : /// returns the face that is described by fv.
592 : /** Note that you may pass a FaceDescriptor to this method.*/
593 : Face* get_face(const FaceVertices& fv);
594 : /// If it exists, this method returns the i-th face of the given Volume. If not NULL is returned.
595 : /** To make sure that associated faces always exist, enable the grid-option
596 : * VOLOPT_AUTOGENERATE_FACES.
597 : * For maximal performance, the option VOLOPT_STORE_ASSOCIATED_FACES
598 : * should be enabled.
599 : * \note If all faces of a volume have to be processed, it may be faster
600 : * to get all faces in one single call.
601 : * This can be done using Grid::associated_elements.*/
602 : Face* get_face(Volume* v, int ind);
603 : /// returns the volume that is described by ev.
604 : /** Note that you may pass an VolumeDescriptor to this method.*/
605 : Volume* get_volume(const VolumeVertices& vv);
606 :
607 : /// returns the element for the given vertices.
608 : /** Note that you can either pass an element type (Edge, Face, Volume)
609 : * or a descriptor (EdgeDescriptor, FaceDescriptor, VolumeDescriptor).
610 : * The method returns NULL, if the specified element does not exist.
611 : * A special overload exists for Vertex*, which simply returns the
612 : * specified vertex. Useful for template programming...
613 : * \{ */
614 0 : Edge* get_element(const EdgeVertices& ev) {return get_edge(ev);}
615 0 : Face* get_element(const FaceVertices& fv) {return get_face(fv);}
616 : Volume* get_element(const VolumeVertices& vv) {return get_volume(vv);}
617 : /** \} */
618 :
619 : /// This overload is only useful to avoid compile issues in templated code
620 : Vertex* get_element(const VertexDescriptor& vd) {return vd.vertex();}
621 :
622 :
623 : ////////////////////////////////////////////////
624 : // access to the sides of an geometric object
625 : /// This method returns the i-th side of an Edge, Face or Volume.
626 : /** If obj has dimension d, then all associated elements of dimension d-1
627 : * are regarded as sides. (Face -> Edge). Only derivates of Volume,
628 : * Face or Edge may be queried for their sides. If you call this method
629 : * with Vertex*, an assertion is triggered, since vertices do not have sides.
630 : *
631 : * It is not in all cases guaranteed that an object has sides.
632 : * If i.e. the FACEOPT_AUTOGENERATE_EDGES is not enabled in the grids options,
633 : * then it is not guaranteed that all side-edges of each face exist (in most
634 : * cases they wont exist). The method returns NULL in this case.
635 : * If however FACEOPT_AUTOGENERATE_EDGES is enabled then this method always
636 : * will return an edge if queried for the side of a face.
637 : * For volumes the appropriate option is called VOLOPT_AUTOGENERATE_FACES.
638 : *
639 : * The method will be faster if elements store associated lower dimensional
640 : * elements. Options VOLOPT_STORE_ASSOCIATED_FACES and
641 : * FACEOPT_STORE_ASSOCIATED_EDGES have to be enabled for this.
642 : *
643 : * \note If all sides of an element have to be processed, it may be faster
644 : * to get all sides in one single call.
645 : * This can be done using Grid::associated_elements.
646 : */
647 : Vertex::side* get_side(Vertex* obj, size_t side);
648 : Edge::side* get_side(Edge* obj, size_t side);
649 : Face::side* get_side(Face* obj, size_t side);
650 : Volume::side* get_side(Volume* obj, size_t side);
651 :
652 : /// returns the geometric object on the opposing side of the given vertex regarding the given element.
653 : /** \note Currently only implemented for Face and Volume.
654 : * \{ */
655 : GridObject* get_opposing_object(Vertex* vrt, Face* elem);
656 : GridObject* get_opposing_object(Vertex* vrt, Volume* elem);
657 : /** \} */
658 :
659 :
660 : /// Puts all elements of type TAss which are contained in 'e' or which contain 'e' into elemsOut
661 : /** One shouldn't depend on the order of elements in elemsOut.
662 : * Use Grid::associated_elements_sorted if the order matters.
663 : *
664 : * \note The returned container is only valid until changes to the queried
665 : * grid are performed.
666 : *
667 : * \note The following typedefs might ease your work with associated elements:
668 : * AssociatedVertices, AssociatedEdges, AssociatedFaces and
669 : * AssociatedVolumes.
670 : * Those are typedefs for Grid::traits<Vertex>::container, ...
671 : *
672 : * \note Depending on the current grid options, this method may use Grid::mark.
673 : * Valid arguments for TElem are Vertex, Edge, Face, Volume.
674 : * \sa Grid::associated_elements_sorted
675 : * \{ */
676 : template <class TElem>
677 : void associated_elements(traits<Vertex>::secure_container& elemsOut, TElem* e);
678 : template <class TElem>
679 : void associated_elements(traits<Edge>::secure_container& elemsOut, TElem* e);
680 : template <class TElem>
681 : void associated_elements(traits<Face>::secure_container& elemsOut, TElem* e);
682 : template <class TElem>
683 : void associated_elements(traits<Volume>::secure_container& elemsOut, TElem* e);
684 : /** \} */
685 :
686 : /// Puts all elements of type TAss which are contained in 'e' into elemsOut in the reference elements order
687 : /** The order of elements in elemsOut is the same as the order in the reference element.
688 : * Note that, depending on active grid options, this method may take more
689 : * time than associated_elements, and should thus only be invoked, if the order
690 : * of elements matters. Use Grid::associated_elements if the order does not matter.
691 : *
692 : * Valid arguments for TElem are Vertex, Edge, Face, Volume.
693 : * Let TAss be the type of queried elements in elemsOut.
694 : * Only associated elements of lower dimension can be sorted. The method
695 : * thus behaves as follows:
696 : * TAss::dim < TElem::dim -> associated elements are written to 'elemsOut'
697 : * with the same order as in the reference element
698 : * TAss::dim == TElem::dim -> onle 'e' itself will be written to 'elemsOut'
699 : * TAss::dim > TElem::dim -> elemsOut will be empty.
700 : *
701 : * \note The returned container is only valid until changes to the queried
702 : * grid are performed.
703 : *
704 : * \note The following typedefs might ease your work with associated elements:
705 : * AssociatedVertices, AssociatedEdges, AssociatedFaces and
706 : * AssociatedVolumes.
707 : * Those are typedefs for traits<Vertex>::container, ...
708 : *
709 : * \note Depending on the current grid options, this method may use Grid::mark.
710 : * \sa Grid::associated_elements*/
711 : template <class TElem>
712 : void associated_elements_sorted(traits<Vertex>::secure_container& elemsOut, TElem* e);
713 : template <class TElem>
714 : void associated_elements_sorted(traits<Edge>::secure_container& elemsOut, TElem* e);
715 : template <class TElem>
716 : void associated_elements_sorted(traits<Face>::secure_container& elemsOut, TElem* e);
717 : template <class TElem>
718 : void associated_elements_sorted(traits<Volume>::secure_container& elemsOut, TElem* e);
719 :
720 :
721 : ////////////////////////////////////////////////
722 : // attachments
723 : ////////////////////////////////////////////////////////////////////////
724 : /// attach with custom pass-on-behaviour and unspecified default value.
725 : template <class TGeomObjClass>
726 : void attach_to(IAttachment& attachment, bool passOnValues);
727 :
728 0 : inline void attach_to_vertices(IAttachment& attachment, bool passOnValues) {attach_to<Vertex>(attachment, passOnValues);}
729 : inline void attach_to_edges(IAttachment& attachment, bool passOnValues) {attach_to<Edge>(attachment, passOnValues);}
730 : inline void attach_to_faces(IAttachment& attachment, bool passOnValues) {attach_to<Face>(attachment, passOnValues);}
731 : inline void attach_to_volumes(IAttachment& attachment, bool passOnValues) {attach_to<Volume>(attachment, passOnValues);}
732 :
733 : inline void attach_to_all(IAttachment& attachment, bool passOnValues);
734 :
735 : ////////////////////////////////////////////////////////////////////////
736 : /// attach with default pass-on behaviour and unspecified default value.
737 : template <class TGeomObjClass>
738 7 : inline void attach_to(IAttachment& attachment) {attach_to<TGeomObjClass>(attachment, attachment.default_pass_on_behaviour());}
739 :
740 7 : inline void attach_to_vertices(IAttachment& attachment) {attach_to<Vertex>(attachment);}
741 0 : inline void attach_to_edges(IAttachment& attachment) {attach_to<Edge>(attachment);}
742 0 : inline void attach_to_faces(IAttachment& attachment) {attach_to<Face>(attachment);}
743 0 : inline void attach_to_volumes(IAttachment& attachment) {attach_to<Volume>(attachment);}
744 :
745 : /// attaches to vertices, edges, faces and volumes at once.
746 : inline void attach_to_all(IAttachment& attachment);
747 :
748 : ////////////////////////////////////////////////////////////////////////
749 : // attach with specified default value and default pass-on behaviour
750 : template <class TGeomObjClass, class TAttachment>
751 : void attach_to_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue);
752 :
753 : template <class TAttachment>
754 0 : inline void attach_to_vertices_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue) {attach_to_dv<Vertex>(attachment, defaultValue);}
755 : template <class TAttachment>
756 0 : inline void attach_to_edges_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue) {attach_to_dv<Edge>(attachment, defaultValue);}
757 : template <class TAttachment>
758 0 : inline void attach_to_faces_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue) {attach_to_dv<Face>(attachment, defaultValue);}
759 : template <class TAttachment>
760 0 : inline void attach_to_volumes_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue) {attach_to_dv<Volume>(attachment, defaultValue);}
761 :
762 : /// attaches to vertices, edges, faces and volumes at once.
763 : template <class TAttachment>
764 : inline void attach_to_all_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue);
765 :
766 : ////////////////////////////////////////////////////////////////////////
767 : // attach with specified default value and custom pass-on behaviour
768 : template <class TGeomObjClass, class TAttachment>
769 : void attach_to_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue, bool passOnValues);
770 :
771 : template <class TAttachment>
772 0 : inline void attach_to_vertices_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue, bool passOnValues) {attach_to_dv<Vertex>(attachment, defaultValue, passOnValues);}
773 : template <class TAttachment>
774 : inline void attach_to_edges_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue, bool passOnValues) {attach_to_dv<Edge>(attachment, defaultValue, passOnValues);}
775 : template <class TAttachment>
776 : inline void attach_to_faces_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue, bool passOnValues) {attach_to_dv<Face>(attachment, defaultValue, passOnValues);}
777 : template <class TAttachment>
778 : inline void attach_to_volumes_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue, bool passOnValues) {attach_to_dv<Volume>(attachment, defaultValue, passOnValues);}
779 :
780 : template <class TAttachment>
781 : inline void attach_to_all_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue, bool passOnValues);
782 : ////////////////////////////////////////////////////////////////////////
783 : // detach
784 : template <class TGeomObjClass>
785 : void detach_from(IAttachment& attachment);
786 :
787 0 : inline void detach_from_vertices(IAttachment& attachment) {detach_from<Vertex>(attachment);}
788 0 : inline void detach_from_edges(IAttachment& attachment) {detach_from<Edge>(attachment);}
789 0 : inline void detach_from_faces(IAttachment& attachment) {detach_from<Face>(attachment);}
790 0 : inline void detach_from_volumes(IAttachment& attachment) {detach_from<Volume>(attachment);}
791 :
792 : inline void detach_from_all(IAttachment& attachment);
793 :
794 :
795 : template <class TGeomObjClass>
796 : inline bool has_attachment(IAttachment& attachment) {return get_attachment_pipe<TGeomObjClass>().has_attachment(attachment);}
797 :
798 : inline bool has_vertex_attachment(IAttachment& attachment) {return has_attachment<Vertex>(attachment);}
799 : inline bool has_edge_attachment(IAttachment& attachment) {return has_attachment<Edge>(attachment);}
800 : inline bool has_face_attachment(IAttachment& attachment) {return has_attachment<Face>(attachment);}
801 : inline bool has_volume_attachment(IAttachment& attachment) {return has_attachment<Volume>(attachment);}
802 :
803 : ////////////////////////////////////////////////////////////////////////
804 : // direct attachment access
805 : template <class TGeomObj>
806 : uint get_attachment_data_index(TGeomObj* pObj) const;
807 :
808 : template <class TGeomObj, class TAttachment>
809 : typename TAttachment::ContainerType*
810 : get_attachment_data_container(TAttachment& attachment);
811 :
812 : /// returns the attachment-pipe in which data associated with the given objects-types are stored.
813 : /** This method is seldomly used, can however be useful. Use with care.
814 : * If in doubt please use the methods featured by Grid instead of directly
815 : * operating on the attachment pipe.
816 : */
817 : template <class TGeomObj>
818 : typename traits<TGeomObj>::AttachmentPipe&
819 : get_attachment_pipe();
820 :
821 : ////////////////////////////////////////////////
822 : // observers
823 : /**
824 : * observerType may be any or-combination of constants enumerated in ObserverType.
825 : */
826 : void register_observer(GridObserver* observer, uint observerType = OT_FULL_OBSERVER);
827 : void unregister_observer(GridObserver* observer);
828 :
829 : /*
830 : template <class GeomObjClass>
831 : util::IAttachmentDataContainer* get_data_container(util::IAttachment& attachment);
832 :
833 : util::IAttachmentDataContainer* get_vertex_data_container(util::IAttachment& attachment) {return get_data_container<Vertex>(attachment);}
834 : util::IAttachmentDataContainer* get_edge_data_container(util::IAttachment& attachment) {return get_data_container<Edge>(attachment);}
835 : util::IAttachmentDataContainer* get_face_data_container(util::IAttachment& attachment) {return get_data_container<Face>(attachment);}
836 : util::IAttachmentDataContainer* get_volume_data_container(util::IAttachment& attachment) {return get_data_container<Volume>(attachment);}
837 : */
838 :
839 : ////////////////////////////////////////////////
840 : // pass_on_values
841 : void pass_on_values(Vertex* objSrc, Vertex* objDest);
842 : void pass_on_values(Edge* objSrc, Edge* objDest);
843 : void pass_on_values(Face* objSrc, Face* objDest);
844 : void pass_on_values(Volume* objSrc, Volume* objDest);
845 :
846 : // subject to change!
847 : AssociatedEdgeIterator associated_edges_begin(Vertex* vrt);///< DO NOT INVOKE! Subject to change.
848 : AssociatedEdgeIterator associated_edges_end(Vertex* vrt);///< DO NOT INVOKE! Subject to change.
849 : AssociatedEdgeIterator associated_edges_begin(Face* face);///< DO NOT INVOKE! Subject to change.
850 : AssociatedEdgeIterator associated_edges_end(Face* face);///< DO NOT INVOKE! Subject to change.
851 : AssociatedEdgeIterator associated_edges_begin(Volume* vol);///< DO NOT INVOKE! Subject to change.
852 : AssociatedEdgeIterator associated_edges_end(Volume* vol);///< DO NOT INVOKE! Subject to change.
853 :
854 : AssociatedFaceIterator associated_faces_begin(Vertex* vrt);///< DO NOT INVOKE! Subject to change.
855 : AssociatedFaceIterator associated_faces_end(Vertex* vrt);///< DO NOT INVOKE! Subject to change.
856 : AssociatedFaceIterator associated_faces_begin(Edge* edge);///< DO NOT INVOKE! Subject to change.
857 : AssociatedFaceIterator associated_faces_end(Edge* edge);///< DO NOT INVOKE! Subject to change.
858 : AssociatedFaceIterator associated_faces_begin(Volume* vol);///< DO NOT INVOKE! Subject to change.
859 : AssociatedFaceIterator associated_faces_end(Volume* vol);///< DO NOT INVOKE! Subject to change.
860 :
861 : AssociatedVolumeIterator associated_volumes_begin(Vertex* vrt);///< DO NOT INVOKE! Subject to change.
862 : AssociatedVolumeIterator associated_volumes_end(Vertex* vrt);///< DO NOT INVOKE! Subject to change.
863 : AssociatedVolumeIterator associated_volumes_begin(Edge* edge);///< DO NOT INVOKE! Subject to change.
864 : AssociatedVolumeIterator associated_volumes_end(Edge* edge);///< DO NOT INVOKE! Subject to change.
865 : AssociatedVolumeIterator associated_volumes_begin(Face* face);///< DO NOT INVOKE! Subject to change.
866 : AssociatedVolumeIterator associated_volumes_end(Face* face);///< DO NOT INVOKE! Subject to change.
867 :
868 : ////////////////////////////////////////////////
869 : // advanced element manipulation
870 3 : inline void register_element(Vertex* v, GridObject* pParent = NULL) {register_vertex(v, pParent);}
871 : inline void unregister_element(Vertex* v) {unregister_vertex(v);}
872 0 : inline void register_element(Edge* e, GridObject* pParent = NULL) {register_edge(e, pParent);}
873 : inline void unregister_element(Edge* e) {unregister_edge(e);}
874 1 : inline void register_element(Face* f, GridObject* pParent = NULL) {register_face(f, pParent);}
875 : inline void unregister_element(Face* f) {unregister_face(f);}
876 0 : inline void register_element(Volume* v, GridObject* pParent = NULL) {register_volume(v, pParent);}
877 : inline void unregister_element(Volume* v) {unregister_volume(v);}
878 :
879 : /// registers the given element and replaces the old one. Calls pass_on_values.
880 : /// \{
881 : void register_and_replace_element(Vertex* v, Vertex* pReplaceMe);
882 : void register_and_replace_element(Edge* e, Edge* pReplaceMe);
883 : void register_and_replace_element(Face* f, Face* pReplaceMe);
884 : void register_and_replace_element(Volume* v, Volume* pReplaceMe);
885 : /// \}
886 :
887 : ////////////////////////////////////////////////
888 : // marks
889 : /// begin marking.
890 : /** Call this method whenever you want to start a marking sequence.
891 : * On a call to this method all old marks are deleted.
892 : * When called for the first time, some preparations have to be taken,
893 : * which may consume some time. Successive calls however are very fast.*/
894 : void begin_marking();
895 : /// clears all marks
896 : /** Calls are only valid between calls to Grid::begin_marking and Grid::end_marking.*/
897 : void clear_marks();
898 :
899 : /// marks the object. Calls are only valid between calls to Grid::begin_marking and Grid::end_marking.
900 : /** Only pass objects that are contained by the grid.
901 : * \{ */
902 : inline void mark(GridObject* obj);
903 : inline void mark(Vertex* obj);
904 : inline void mark(Edge* obj);
905 : inline void mark(Face* obj);
906 : inline void mark(Volume* obj);
907 : /** \} */
908 :
909 : /// marks all objects between begin and end
910 : /** TIterator::value_type has to be either
911 : * Vertex*, Edge*, Face* or Volume*.*/
912 : template <class TIterator>
913 : void mark(TIterator begin, TIterator end);
914 :
915 : /// unmarks the object. Calls are only valid between calls to Grid::begin_marking and Grid::end_marking.
916 : /** Only pass objects that are contained by the grid.
917 : * \{ */
918 : inline void unmark(GridObject* obj);
919 : inline void unmark(Vertex* obj);
920 : inline void unmark(Edge* obj);
921 : inline void unmark(Face* obj);
922 : inline void unmark(Volume* obj);
923 : /** \} */
924 :
925 : /// unmarks all objects between begin and end
926 : /** TIterator::value_type has to be either
927 : * Vertex*, Edge*, Face* or Volume*.*/
928 : template <class TIterator>
929 : void unmark(TIterator begin, TIterator end);
930 :
931 : /// returns true if the object is marked, false if not.
932 : /** Only pass objects that are contained by the grid.
933 : * \{ */
934 : inline bool is_marked(GridObject* obj) const;
935 : inline bool is_marked(Vertex* obj) const;
936 : inline bool is_marked(Edge* obj) const;
937 : inline bool is_marked(Face* obj) const;
938 : inline bool is_marked(Volume* obj) const;
939 : /** \} */
940 :
941 : /// ends a marking sequence. Call this method when you're done with marking.
942 : void end_marking();
943 :
944 : /// gives access to the grid's message-hub
945 : SPMessageHub message_hub() {return m_messageHub;}
946 :
947 : /// a temporary testing method
948 : void test_attached_linked_lists();
949 :
950 : protected:
951 : typedef std::vector<GridObserver*> ObserverContainer;
952 :
953 : typedef Attachment<VertexContainer> AVertexContainer;
954 : typedef Attachment<EdgeContainer> AEdgeContainer;
955 : typedef Attachment<FaceContainer> AFaceContainer;
956 : typedef Attachment<VolumeContainer> AVolumeContainer;
957 :
958 : typedef Attachment<int> AMark;
959 :
960 : protected:
961 : /// unregisters all observers. Call this method in destructors of derived classes.
962 : /** If the derived class is an observer itself and if you don't want it to be
963 : * notified on grid-destruction, e.g., because you call this method in the
964 : * destructor of your derived class, then pass a pointer to your class through
965 : * the initiator parameter to this function.
966 : * \param initiator: The initiator won't be notified about grid destruction
967 : */
968 : void notify_and_clear_observers_on_grid_destruction(GridObserver* initiator = NULL);
969 :
970 : /// returns the element storage for a given element type
971 : template <class TElem> inline
972 : typename traits<TElem>::ElementStorage&
973 : element_storage()
974 : {return ElementStorageSelector<typename geometry_traits<TElem>::grid_base_object>::
975 : element_storage(m_vertexElementStorage, m_edgeElementStorage,
976 : m_faceElementStorage, m_volumeElementStorage);
977 : }
978 :
979 : /// returns the const element storage for a given element type
980 : template <class TElem> inline
981 : const typename traits<TElem>::ElementStorage&
982 : element_storage() const
983 : {return ElementStorageSelector<typename geometry_traits<TElem>::grid_base_object>::
984 : element_storage(m_vertexElementStorage, m_edgeElementStorage,
985 : m_faceElementStorage, m_volumeElementStorage);
986 : }
987 :
988 : /// copies the contents from the given grid to this grid.
989 : /** Make sure that the grid on which this method is called is
990 : * empty before the method is called.*/
991 : void assign_grid(const Grid& grid);
992 :
993 : /// assigns a unique hash value to a Vertex.
994 : /** overflow is not handled properly.
995 : * If sombody creates 2^32 elements, the uniquness can no longer be guaranteed.*/
996 3 : inline void assign_hash_value(Vertex* vrt) {vrt->m_hashValue = m_hashCounter++;}
997 :
998 : void register_vertex(Vertex* v, GridObject* pParent = NULL);///< pDF specifies the element from which v derives its values
999 : void unregister_vertex(Vertex* v);
1000 : void register_edge(Edge* e, GridObject* pParent = NULL,
1001 : Face* createdByFace = NULL, Volume* createdByVol = NULL);///< pDF specifies the element from which v derives its values
1002 : void unregister_edge(Edge* e);
1003 : void register_face(Face* f, GridObject* pParent = NULL,
1004 : Volume* createdByVol = NULL);///< pDF specifies the element from which v derives its values
1005 : void unregister_face(Face* f);
1006 : void register_volume(Volume* v, GridObject* pParent = NULL);///< pDF specifies the element from which v derives its values
1007 : void unregister_volume(Volume* v);
1008 :
1009 : void change_options(uint optsNew);
1010 :
1011 : void change_vertex_options(uint optsNew);
1012 : void change_edge_options(uint optsNew);
1013 : void change_face_options(uint optsNew);
1014 : void change_volume_options(uint optsNew);
1015 :
1016 : void vertex_store_associated_edges(bool bStoreIt);
1017 : void vertex_store_associated_faces(bool bStoreIt);
1018 : void vertex_store_associated_volumes(bool bStoreIt);
1019 : void edge_store_associated_faces(bool bStoreIt);
1020 : void edge_store_associated_volumes(bool bStoreIt);
1021 : void face_store_associated_edges(bool bStoreIt);
1022 : void face_store_associated_volumes(bool bStoreIt);
1023 : void face_autogenerate_edges(bool bAutogen);
1024 : void volume_store_associated_edges(bool bStoreIt);
1025 : void volume_store_associated_faces(bool bStoreIt);
1026 : void volume_autogenerate_edges(bool bAutogen);
1027 : void volume_autogenerate_faces(bool bAutogen);
1028 :
1029 : void volume_sort_associated_edge_container();
1030 :
1031 : template <class TAttachmentPipe, class TElem>
1032 : void pass_on_values(TAttachmentPipe& attachmentPipe,
1033 : TElem* pSrc, TElem* pDest);
1034 :
1035 : // some methods that simplify auto-enabling of grid options
1036 : inline void autoenable_option(uint option, const char* caller, const char* optionName);
1037 :
1038 : // neighbourhood access
1039 : template <class TGeomObj>
1040 : Edge* find_edge_in_associated_edges(TGeomObj* obj,
1041 : const EdgeVertices& ev);
1042 :
1043 : template <class TGeomObj>
1044 : Face* find_face_in_associated_faces(TGeomObj* obj,
1045 : const FaceVertices& fv);
1046 :
1047 : template <class TGeomObj>
1048 : Volume* find_volume_in_associated_volumes(TGeomObj* obj,
1049 : const VolumeVertices& vv);
1050 :
1051 : // get associated elements
1052 : void get_associated(SecureVertexContainer& vrts, Edge* e);
1053 : void get_associated(SecureVertexContainer& vrts, Face* f);
1054 : void get_associated(SecureVertexContainer& vrts, Volume* v);
1055 :
1056 : void get_associated(SecureEdgeContainer& edges, Vertex* v);
1057 : void get_associated(SecureEdgeContainer& edges, Face* f);
1058 : void get_associated(SecureEdgeContainer& edges, Volume* v);
1059 :
1060 : void get_associated(SecureFaceContainer& faces, Vertex* v);
1061 : void get_associated(SecureFaceContainer& faces, Edge* e);
1062 : void get_associated(SecureFaceContainer& faces, Volume* v);
1063 :
1064 : void get_associated(SecureVolumeContainer& vols, Vertex* v);
1065 : void get_associated(SecureVolumeContainer& vols, Edge* e);
1066 : void get_associated(SecureVolumeContainer& vols, Face* f);
1067 :
1068 : template <class TContainer>
1069 : void get_associated(TContainer& container, GridObject* o);
1070 :
1071 : template <class TElem>
1072 : void get_associated(typename traits<typename TElem::grid_base_object>
1073 : ::secure_container& elems, TElem* e);
1074 :
1075 : /** this method does not use possibly attached containers and can thus
1076 : * be used, when such containers are to be built.*/
1077 : void get_associated_vols_raw(SecureVolumeContainer& vols, Face* f);
1078 :
1079 : void get_associated_sorted(SecureVertexContainer& vrts, Edge* e) const;
1080 : void get_associated_sorted(SecureVertexContainer& vrts, Face* f) const;
1081 : void get_associated_sorted(SecureVertexContainer& vrts, Volume* v) const;
1082 :
1083 : void get_associated_sorted(SecureEdgeContainer& edges, Vertex* v);
1084 : void get_associated_sorted(SecureEdgeContainer& edges, Face* f);
1085 : void get_associated_sorted(SecureEdgeContainer& edges, Volume* v);
1086 :
1087 : void get_associated_sorted(SecureFaceContainer& faces, Vertex* v);
1088 : void get_associated_sorted(SecureFaceContainer& faces, Edge* e);
1089 : void get_associated_sorted(SecureFaceContainer& faces, Volume* v);
1090 :
1091 : void get_associated_sorted(SecureVolumeContainer& vols, Vertex* v);
1092 : void get_associated_sorted(SecureVolumeContainer& vols, Edge* e);
1093 : void get_associated_sorted(SecureVolumeContainer& vols, Face* f);
1094 :
1095 : template <class TElem>
1096 : void get_associated_sorted(typename traits<typename TElem::grid_base_object>
1097 : ::secure_container& elems, TElem* e);
1098 :
1099 :
1100 : /// helps in copying attachment pipes during assign_grid
1101 : /** Note that this method only copies attachments with m_userData==1.
1102 : * \todo Copy behavior should be changed to all user-attachments.*/
1103 : template <class TAttachmentPipe>
1104 : void copy_user_attachments(const TAttachmentPipe& apSrc, TAttachmentPipe& apDest,
1105 : std::vector<int>& srcDataIndices);
1106 :
1107 : // marks
1108 : void init_marks();
1109 : void reset_marks();
1110 : void remove_marks();
1111 :
1112 : protected:
1113 : /// returns the iterator at which the given element lies in the section container
1114 : /** This method may only be called if the element has already been registered at the grid.
1115 : * \{
1116 : */
1117 : inline traits<Vertex>::SectionContainer::iterator
1118 : get_iterator(Vertex* o)
1119 : {
1120 : return m_vertexElementStorage.m_sectionContainer.
1121 : get_container().get_iterator(o);
1122 : }
1123 :
1124 : inline traits<Edge>::SectionContainer::iterator
1125 : get_iterator(Edge* o)
1126 : {
1127 : return m_edgeElementStorage.m_sectionContainer.
1128 : get_container().get_iterator(o);
1129 : }
1130 :
1131 : inline traits<Face>::SectionContainer::iterator
1132 : get_iterator(Face* o)
1133 : {
1134 : return m_faceElementStorage.m_sectionContainer.
1135 : get_container().get_iterator(o);
1136 : }
1137 :
1138 : inline traits<Volume>::SectionContainer::iterator
1139 : get_iterator(Volume* o)
1140 : {
1141 : return m_volumeElementStorage.m_sectionContainer.
1142 : get_container().get_iterator(o);
1143 : }
1144 : /** \} */
1145 :
1146 :
1147 : /// helper to clear_attachments
1148 : template <class TElem>
1149 : void clear_attachments();
1150 :
1151 : protected:
1152 : VertexElementStorage m_vertexElementStorage;
1153 : EdgeElementStorage m_edgeElementStorage;
1154 : FaceElementStorage m_faceElementStorage;
1155 : VolumeElementStorage m_volumeElementStorage;
1156 :
1157 : uint m_options;
1158 : uint32 m_hashCounter;
1159 :
1160 : // observer handling
1161 : ObserverContainer m_gridObservers;
1162 : ObserverContainer m_vertexObservers;
1163 : ObserverContainer m_edgeObservers;
1164 : ObserverContainer m_faceObservers;
1165 : ObserverContainer m_volumeObservers;
1166 :
1167 : // interconnection management
1168 : AVertexContainer m_aVertexContainer;
1169 : AEdgeContainer m_aEdgeContainer;
1170 : AFaceContainer m_aFaceContainer;
1171 : AVolumeContainer m_aVolumeContainer;
1172 :
1173 : AttachmentAccessor<Vertex, AEdgeContainer> m_aaEdgeContainerVERTEX;
1174 : AttachmentAccessor<Vertex, AFaceContainer> m_aaFaceContainerVERTEX;
1175 : AttachmentAccessor<Vertex, AVolumeContainer> m_aaVolumeContainerVERTEX;
1176 :
1177 : AttachmentAccessor<Edge, AEdgeContainer> m_aaEdgeContainerEDGE;
1178 : AttachmentAccessor<Edge, AFaceContainer> m_aaFaceContainerEDGE;
1179 : AttachmentAccessor<Edge, AVolumeContainer> m_aaVolumeContainerEDGE;
1180 :
1181 : AttachmentAccessor<Face, AEdgeContainer> m_aaEdgeContainerFACE;
1182 : AttachmentAccessor<Face, AFaceContainer> m_aaFaceContainerFACE;
1183 : AttachmentAccessor<Face, AVolumeContainer> m_aaVolumeContainerFACE;
1184 :
1185 : AttachmentAccessor<Volume, AEdgeContainer> m_aaEdgeContainerVOLUME;
1186 : AttachmentAccessor<Volume, AFaceContainer> m_aaFaceContainerVOLUME;
1187 : AttachmentAccessor<Volume, AVolumeContainer> m_aaVolumeContainerVOLUME;
1188 :
1189 : // marks
1190 : int m_currentMark; // 0: marks inactive. -1: reset-marks (sets currentMark to 1)
1191 : bool m_bMarking;
1192 : AMark m_aMark;
1193 : VertexAttachmentAccessor<AMark> m_aaMarkVRT;
1194 : EdgeAttachmentAccessor<AMark> m_aaMarkEDGE;
1195 : FaceAttachmentAccessor<AMark> m_aaMarkFACE;
1196 : VolumeAttachmentAccessor<AMark> m_aaMarkVOL;
1197 :
1198 : SPMessageHub m_messageHub;
1199 : DistributedGridManager* m_distGridMgr;
1200 : PeriodicBoundaryManager* m_periodicBndMgr;
1201 : };
1202 :
1203 : /** \} */
1204 : }//end of namespace
1205 :
1206 : #include "grid_impl.hpp"
1207 :
1208 : #endif
|