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 : #include <cassert>
34 : #include <algorithm>
35 : #include "grid.h"
36 : #include "grid_util.h"
37 : #include "common/common.h"
38 : #include "lib_grid/attachments/attached_list.h"
39 : #include "lib_grid/tools/periodic_boundary_manager.h"
40 :
41 : #ifdef UG_PARALLEL
42 : #include "lib_grid/parallelization/distributed_grid.h"
43 : #endif
44 :
45 :
46 : using namespace std;
47 :
48 : namespace ug
49 : {
50 : ////////////////////////////////////////////////////////////////////////////////////////////////
51 : ////////////////////////////////////////////////////////////////////////////////////////////////
52 : // implementation of Grid
53 :
54 : ////////////////////////////////////////////////////////////////////////
55 : // constructors
56 1 : Grid::Grid() :
57 : m_aVertexContainer("Grid_VertexContainer", false),
58 : m_aEdgeContainer("Grid_EdgeContainer", false),
59 : m_aFaceContainer("Grid_FaceContainer", false),
60 : m_aVolumeContainer("Grid_VolumeContainer", false),
61 1 : m_bMarking(false),
62 : m_aMark("Grid_Mark", false),
63 1 : m_distGridMgr(NULL),
64 1 : m_periodicBndMgr(NULL)
65 : {
66 1 : m_hashCounter = 0;
67 1 : m_currentMark = 0;
68 1 : m_options = GRIDOPT_NONE;
69 2 : m_messageHub = SPMessageHub(new MessageHub());
70 :
71 1 : change_options(GRIDOPT_DEFAULT);
72 1 : }
73 :
74 0 : Grid::Grid(uint options) :
75 : m_aVertexContainer("Grid_VertexContainer", false),
76 : m_aEdgeContainer("Grid_EdgeContainer", false),
77 : m_aFaceContainer("Grid_FaceContainer", false),
78 : m_aVolumeContainer("Grid_VolumeContainer", false),
79 0 : m_bMarking(false),
80 : m_aMark("Grid_Mark", false),
81 0 : m_distGridMgr(NULL),
82 0 : m_periodicBndMgr(NULL)
83 : {
84 0 : m_hashCounter = 0;
85 0 : m_currentMark = 0;
86 0 : m_options = GRIDOPT_NONE;
87 0 : m_messageHub = SPMessageHub(new MessageHub());
88 :
89 0 : change_options(options);
90 0 : }
91 :
92 0 : Grid::Grid(const Grid& grid) :
93 : m_aVertexContainer("Grid_VertexContainer", false),
94 : m_aEdgeContainer("Grid_EdgeContainer", false),
95 : m_aFaceContainer("Grid_FaceContainer", false),
96 : m_aVolumeContainer("Grid_VolumeContainer", false),
97 0 : m_bMarking(false),
98 : m_aMark("Grid_Mark", false),
99 0 : m_distGridMgr(NULL),
100 0 : m_periodicBndMgr(NULL)
101 : {
102 0 : m_hashCounter = 0;
103 0 : m_currentMark = 0;
104 0 : m_options = GRIDOPT_NONE;
105 0 : m_messageHub = SPMessageHub(new MessageHub());
106 :
107 0 : assign_grid(grid);
108 0 : }
109 :
110 1 : Grid::~Grid()
111 : {
112 1 : notify_and_clear_observers_on_grid_destruction();
113 :
114 : // erase all elements
115 1 : clear_geometry();
116 :
117 : // remove marks - would be done anyway...
118 1 : remove_marks();
119 :
120 : // erase any internal managers and handlers
121 : #ifdef UG_PARALLEL
122 : if(m_distGridMgr) delete m_distGridMgr;
123 : #endif
124 :
125 1 : if(m_periodicBndMgr) delete m_periodicBndMgr;
126 1 : }
127 :
128 1 : void Grid::notify_and_clear_observers_on_grid_destruction(GridObserver* initiator)
129 : {
130 : // tell registered grid-observers that the grid is to be destroyed.
131 : // do this in reverse order, so that the danger of accessing invalid observers
132 : // is minimized.
133 : for(ObserverContainer::reverse_iterator iter = m_gridObservers.rbegin();
134 1 : iter != m_gridObservers.rend(); ++iter)
135 : {
136 0 : if(*iter != initiator)
137 0 : (*iter)->grid_to_be_destroyed(this);
138 : }
139 :
140 : // unregister all observers
141 1 : while(!m_gridObservers.empty())
142 0 : unregister_observer(m_gridObservers.back());
143 :
144 1 : while(!m_vertexObservers.empty())
145 0 : unregister_observer(m_vertexObservers.back());
146 :
147 1 : while(!m_edgeObservers.empty())
148 0 : unregister_observer(m_edgeObservers.back());
149 :
150 1 : while(!m_faceObservers.empty())
151 0 : unregister_observer(m_faceObservers.back());
152 :
153 1 : while(!m_volumeObservers.empty())
154 0 : unregister_observer(m_volumeObservers.back());
155 1 : }
156 :
157 0 : void Grid::
158 : set_parallel(bool parallel)
159 : {
160 0 : if(parallel){
161 : #ifdef UG_PARALLEL
162 : if(!is_parallel()){
163 : // we currently only support parallel mutli-grids, sadly...
164 : MultiGrid* mg = dynamic_cast<MultiGrid*>(this);
165 : if(mg){
166 : if(m_distGridMgr) delete m_distGridMgr;
167 : m_distGridMgr = new DistributedGridManager;
168 : m_distGridMgr->assign(*mg);
169 : }
170 : else{
171 : UG_THROW("Error during Grid::set_parallel: "
172 : "The DistributedGridManager can currently only be used to "
173 : "parallelize ug::MultiGrid. ug::Grid can currently not be used "
174 : "for parallel computations. Sorry.");
175 : }
176 : }
177 : #else
178 0 : UG_THROW("Parallelism can only be activated, if ug was compiled with "
179 : "PARALLEL=ON. This is not the case for this application.");
180 : #endif
181 : }
182 : else if(is_parallel()){
183 : #ifdef UG_PARALLEL
184 : if(m_distGridMgr) delete m_distGridMgr;
185 : m_distGridMgr = NULL;
186 : #endif
187 : }
188 0 : }
189 :
190 0 : void Grid::set_periodic_boundaries(bool is_periodic)
191 : {
192 0 : if(is_periodic)
193 : {
194 0 : if(m_periodicBndMgr) delete m_periodicBndMgr;
195 0 : m_periodicBndMgr = new PeriodicBoundaryManager();
196 0 : m_periodicBndMgr->set_grid(this);
197 : }
198 0 : else if(m_periodicBndMgr){
199 0 : delete m_periodicBndMgr;
200 0 : m_periodicBndMgr = NULL;
201 : }
202 0 : }
203 :
204 0 : bool Grid::has_periodic_boundaries() const
205 : {
206 0 : return m_periodicBndMgr != NULL;
207 : }
208 :
209 0 : PeriodicBoundaryManager* Grid::periodic_boundary_manager()
210 : {
211 0 : return m_periodicBndMgr;
212 : }
213 :
214 0 : const PeriodicBoundaryManager* Grid::periodic_boundary_manager() const
215 : {
216 0 : return m_periodicBndMgr;
217 : }
218 :
219 :
220 0 : void Grid::clear()
221 : {
222 0 : clear_geometry();
223 0 : clear_attachments();
224 0 : }
225 :
226 1 : void Grid::clear_geometry()
227 : {
228 : // disable all options to speed it up
229 1 : uint opts = get_options();
230 1 : set_options(GRIDOPT_NONE);
231 :
232 : clear<Volume>();
233 : clear<Face>();
234 : clear<Edge>();
235 : clear<Vertex>();
236 :
237 : // reset options
238 1 : set_options(opts);
239 1 : }
240 :
241 : template <class TElem>
242 0 : void Grid::clear_attachments()
243 : {
244 : typedef typename traits<TElem>::AttachmentPipe AttachmentPipe;
245 :
246 : vector<AttachmentEntry> vEntries;
247 :
248 : // iterate through all attachment pipes
249 : AttachmentPipe& ap = get_attachment_pipe<TElem>();
250 :
251 : // collect all attachment entries
252 0 : for(typename AttachmentPipe::ConstAttachmentEntryIterator iter = ap.attachments_begin();
253 0 : iter != ap.attachments_end(); ++iter)
254 : {
255 0 : vEntries.push_back(*iter);
256 : }
257 :
258 : // iterate through the entries in the vector and delete the ones
259 : // that have an enabled pass-on behaviour
260 0 : for(size_t j = 0; j < vEntries.size(); ++j)
261 : {
262 : const AttachmentEntry& ae = vEntries[j];
263 :
264 0 : if(ae.m_userData == 1){
265 0 : ap.detach(*ae.m_pAttachment);
266 : }
267 : }
268 0 : }
269 :
270 0 : void Grid::clear_attachments()
271 : {
272 0 : clear_attachments<Vertex>();
273 0 : clear_attachments<Edge>();
274 0 : clear_attachments<Face>();
275 0 : clear_attachments<Volume>();
276 0 : }
277 :
278 0 : Grid& Grid::operator = (const Grid& grid)
279 : {
280 : // clears the grid and calls assign_grid afterwards.
281 : // we're disabling any options, since new options will
282 : // be set during assign_grid anyway. This might speed
283 : // things up a little
284 0 : set_options(GRIDOPT_NONE);
285 0 : clear_geometry();
286 0 : assign_grid(grid);
287 :
288 0 : return *this;
289 : }
290 :
291 : template <class TAttachmentPipe>
292 0 : void Grid::copy_user_attachments(const TAttachmentPipe& apSrc, TAttachmentPipe& apDest,
293 : vector<int>& srcDataIndices)
294 : {
295 0 : for(typename TAttachmentPipe::ConstAttachmentEntryIterator iter = apSrc.attachments_begin();
296 0 : iter != apSrc.attachments_end(); ++iter)
297 : {
298 : const AttachmentEntry& ae = *iter;
299 0 : if(ae.m_userData == 1){
300 : // attach the attachment to this grid
301 0 : apDest.attach(*ae.m_pAttachment, ae.m_userData);
302 0 : const IAttachmentDataContainer& conSrc = *ae.m_pContainer;
303 0 : IAttachmentDataContainer& conDest = *apDest.get_data_container(*ae.m_pAttachment);
304 :
305 : // we use the containers copy-method
306 0 : conSrc.copy_to_container(&conDest, &srcDataIndices.front(),
307 : (int)srcDataIndices.size());
308 : }
309 : }
310 0 : }
311 :
312 0 : void Grid::assign_grid(const Grid& grid)
313 : {
314 : //TODO: notify a grid observer that copying has started
315 :
316 : // we need a vertex-map that allows us to find a vertex in the new grid
317 : // given a vertex in the old one.
318 0 : vector<Vertex*> vrtMap(grid.attachment_container_size<Vertex>(), NULL);
319 :
320 : // we need index-lists that allow us to copy attachments later on
321 0 : vector<int> vSrcDataIndex[NUM_GEOMETRIC_BASE_OBJECTS];
322 : vector<int>& vSrcDataIndexVRT = vSrcDataIndex[VERTEX];
323 : vector<int>& vSrcDataIndexEDGE = vSrcDataIndex[EDGE];
324 : vector<int>& vSrcDataIndexFACE = vSrcDataIndex[FACE];
325 : vector<int>& vSrcDataIndexVOL = vSrcDataIndex[VOLUME];
326 :
327 : // copy all vertices
328 0 : vSrcDataIndexVRT.resize(grid.num<Vertex>());
329 : ConstVertexIterator vrtsEnd = grid.end<Vertex>();
330 0 : for(ConstVertexIterator iter = grid.begin<Vertex>(); iter != vrtsEnd; ++iter)
331 : {
332 : Vertex* vrt = *iter;
333 0 : Vertex* nVrt = *create_by_cloning(vrt);
334 0 : vrtMap[grid.get_attachment_data_index(vrt)] = nVrt;
335 0 : vSrcDataIndexVRT[get_attachment_data_index(nVrt)] = grid.get_attachment_data_index(vrt);
336 : }
337 :
338 : // copy all edges
339 0 : vSrcDataIndexEDGE.resize(grid.num<Edge>());
340 : ConstEdgeIterator edgesEnd = grid.end<Edge>();
341 0 : for(ConstEdgeIterator iter = grid.begin<Edge>(); iter != edgesEnd; ++iter)
342 : {
343 : Edge* e = *iter;
344 0 : Edge* nE = *create_by_cloning(e, EdgeDescriptor(
345 0 : vrtMap[grid.get_attachment_data_index(e->vertex(0))],
346 0 : vrtMap[grid.get_attachment_data_index(e->vertex(1))]));
347 0 : vSrcDataIndexEDGE[get_attachment_data_index(nE)] = grid.get_attachment_data_index(e);
348 : }
349 :
350 : // copy all faces
351 0 : vSrcDataIndexFACE.resize(grid.num<Face>());
352 0 : FaceDescriptor fd;
353 : ConstFaceIterator facesEnd = grid.end<Face>();
354 0 : for(ConstFaceIterator iter = grid.begin<Face>(); iter != facesEnd; ++iter)
355 : {
356 : Face* f = *iter;
357 0 : uint numVrts = f->num_vertices();
358 0 : Face::ConstVertexArray vrts = f->vertices();
359 :
360 : // fill the face descriptor
361 0 : if(numVrts != fd.num_vertices())
362 : fd.set_num_vertices(numVrts);
363 :
364 0 : for(uint i = 0; i < numVrts; ++i)
365 0 : fd.set_vertex(i, vrtMap[grid.get_attachment_data_index(vrts[i])]);
366 :
367 : // create the new face
368 0 : Face* nF = *create_by_cloning(f, fd);
369 :
370 0 : vSrcDataIndexFACE[get_attachment_data_index(nF)] = grid.get_attachment_data_index(f);
371 : }
372 :
373 : // copy all volumes
374 0 : vSrcDataIndexVOL.resize(grid.num<Volume>());
375 0 : VolumeDescriptor vd;
376 : ConstVolumeIterator volsEnd = grid.end<Volume>();
377 0 : for(ConstVolumeIterator iter = grid.begin<Volume>(); iter != volsEnd; ++iter)
378 : {
379 : Volume* v = *iter;
380 0 : uint numVrts = v->num_vertices();
381 0 : Volume::ConstVertexArray vrts = v->vertices();
382 :
383 : // fill the volume descriptor
384 0 : if(numVrts != vd.num_vertices())
385 : vd.set_num_vertices(numVrts);
386 :
387 0 : for(uint i = 0; i < numVrts; ++i)
388 0 : vd.set_vertex(i, vrtMap[grid.get_attachment_data_index(vrts[i])]);
389 :
390 : // create the volume
391 0 : Volume* nV = *create_by_cloning(v, vd);
392 :
393 0 : vSrcDataIndexVOL[get_attachment_data_index(nV)] = grid.get_attachment_data_index(v);
394 : }
395 :
396 : // enable options
397 0 : enable_options(grid.get_options());
398 :
399 : // copy attachments that may be passed on
400 0 : copy_user_attachments(grid.m_vertexElementStorage.m_attachmentPipe,
401 0 : m_vertexElementStorage.m_attachmentPipe, vSrcDataIndexVRT);
402 0 : copy_user_attachments(grid.m_edgeElementStorage.m_attachmentPipe,
403 0 : m_edgeElementStorage.m_attachmentPipe, vSrcDataIndexEDGE);
404 0 : copy_user_attachments(grid.m_faceElementStorage.m_attachmentPipe,
405 0 : m_faceElementStorage.m_attachmentPipe, vSrcDataIndexFACE);
406 0 : copy_user_attachments(grid.m_volumeElementStorage.m_attachmentPipe,
407 0 : m_volumeElementStorage.m_attachmentPipe, vSrcDataIndexVOL);
408 :
409 : // parallelism
410 0 : if(grid.is_parallel()){
411 0 : set_parallel(true);
412 : //todo: copy interfaces from grid.
413 : }
414 :
415 : //TODO: notify a grid observer that copying has ended
416 0 : }
417 :
418 :
419 0 : VertexIterator Grid::create_by_cloning(Vertex* pCloneMe, GridObject* pParent)
420 : {
421 0 : Vertex* pNew = reinterpret_cast<Vertex*>(pCloneMe->create_empty_instance());
422 0 : register_vertex(pNew, pParent);
423 0 : return iterator_cast<VertexIterator>(get_iterator(pNew));
424 : }
425 :
426 0 : EdgeIterator Grid::create_by_cloning(Edge* pCloneMe, const IVertexGroup& ev, GridObject* pParent)
427 : {
428 0 : Edge* pNew = reinterpret_cast<Edge*>(pCloneMe->create_empty_instance());
429 0 : pNew->set_vertex(0, ev.vertex(0));
430 0 : pNew->set_vertex(1, ev.vertex(1));
431 0 : register_edge(pNew, pParent);
432 0 : return iterator_cast<EdgeIterator>(get_iterator(pNew));
433 : }
434 :
435 0 : FaceIterator Grid::create_by_cloning(Face* pCloneMe, const IVertexGroup& fv, GridObject* pParent)
436 : {
437 0 : Face* pNew = reinterpret_cast<Face*>(pCloneMe->create_empty_instance());
438 0 : uint numVrts = fv.num_vertices();
439 0 : Face::ConstVertexArray vrts = fv.vertices();
440 0 : for(uint i = 0; i < numVrts; ++i)
441 0 : pNew->set_vertex(i, vrts[i]);
442 0 : register_face(pNew, pParent);
443 0 : return iterator_cast<FaceIterator>(get_iterator(pNew));
444 : }
445 :
446 0 : VolumeIterator Grid::create_by_cloning(Volume* pCloneMe, const IVertexGroup& vv, GridObject* pParent)
447 : {
448 0 : Volume* pNew = reinterpret_cast<Volume*>(pCloneMe->create_empty_instance());
449 0 : uint numVrts = vv.num_vertices();
450 0 : Volume::ConstVertexArray vrts = vv.vertices();
451 0 : for(uint i = 0; i < numVrts; ++i)
452 0 : pNew->set_vertex(i, vrts[i]);
453 0 : register_volume(pNew, pParent);
454 0 : return iterator_cast<VolumeIterator>(get_iterator(pNew));
455 : }
456 :
457 : ////////////////////////////////////////////////////////////////////////
458 : // erase functions
459 0 : void Grid::erase(GridObject* geomObj)
460 : {
461 : assert(geomObj->container_section() != -1
462 : && "ERROR in Grid::erase(Vertex*). Invalid pipe section!");
463 :
464 0 : uint objType = geomObj->base_object_id();
465 0 : switch(objType)
466 : {
467 : case VERTEX:
468 0 : erase(dynamic_cast<Vertex*>(geomObj));
469 0 : break;
470 : case EDGE:
471 0 : erase(dynamic_cast<Edge*>(geomObj));
472 0 : break;
473 : case FACE:
474 0 : erase(dynamic_cast<Face*>(geomObj));
475 0 : break;
476 : case VOLUME:
477 0 : erase(dynamic_cast<Volume*>(geomObj));
478 0 : break;
479 : };
480 0 : }
481 :
482 3 : void Grid::erase(Vertex* vrt)
483 : {
484 : assert((vrt != NULL) && "ERROR in Grid::erase(Vertex*): invalid pointer)");
485 : assert(vrt->container_section() != -1
486 : && "ERROR in Grid::erase(Vertex*). Invalid pipe section!");
487 :
488 3 : unregister_vertex(vrt);
489 :
490 3 : delete vrt;
491 3 : }
492 :
493 3 : void Grid::erase(Edge* edge)
494 : {
495 : assert((edge != NULL) && "ERROR in Grid::erase(Edge*): invalid pointer)");
496 : assert(edge->container_section() != -1
497 : && "ERROR in Grid::erase(Edge*). Invalid pipe section!");
498 :
499 3 : unregister_edge(edge);
500 :
501 3 : delete edge;
502 3 : }
503 :
504 1 : void Grid::erase(Face* face)
505 : {
506 : assert((face != NULL) && "ERROR in Grid::erase(Face*): invalid pointer)");
507 : assert(face->container_section() != -1
508 : && "ERROR in Grid::erase(Face*). Invalid pipe section!");
509 :
510 1 : unregister_face(face);
511 :
512 1 : delete face;
513 1 : }
514 :
515 0 : void Grid::erase(Volume* vol)
516 : {
517 : assert((vol != NULL) && "ERROR in Grid::erase(Volume*): invalid pointer)");
518 : assert(vol->container_section() != -1
519 : && "ERROR in Grid::erase(Volume*). Invalid pipe section!");
520 :
521 0 : unregister_volume(vol);
522 :
523 0 : delete vol;
524 0 : }
525 :
526 : // the geometric-object-collection:
527 0 : GridObjectCollection Grid::get_grid_objects()
528 : {
529 : return GridObjectCollection(&m_vertexElementStorage.m_sectionContainer,
530 : &m_edgeElementStorage.m_sectionContainer,
531 : &m_faceElementStorage.m_sectionContainer,
532 0 : &m_volumeElementStorage.m_sectionContainer);
533 : }
534 :
535 0 : void Grid::flip_orientation(Edge* e)
536 : {
537 : swap(e->m_vertices[0], e->m_vertices[1]);
538 0 : }
539 :
540 0 : void Grid::flip_orientation(Face* f)
541 : {
542 : // inverts the order of vertices.
543 0 : uint numVrts = (int)f->num_vertices();
544 0 : vector<Vertex*> vVrts(numVrts);
545 :
546 : uint i;
547 0 : for(i = 0; i < numVrts; ++i)
548 0 : vVrts[i] = f->vertex(i);
549 :
550 0 : for(i = 0; i < numVrts; ++i)
551 0 : f->set_vertex(i, vVrts[numVrts - 1 - i]);
552 :
553 : // update associated edge list
554 0 : if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES)){
555 : m_aaEdgeContainerFACE[f].clear();
556 0 : EdgeDescriptor ed;
557 0 : for(size_t ind = 0; ind < f->num_edges(); ++ind){
558 : // get the descriptor of the i-th edge
559 0 : f->edge_desc(ind, ed);
560 : // find the edge by checking vertices.
561 0 : Edge* e = find_edge_in_associated_edges(ed.vertex(0), ed);
562 0 : if(e)
563 0 : m_aaEdgeContainerFACE[f].push_back(e);
564 : }
565 : }
566 0 : }
567 :
568 0 : void Grid::flip_orientation(Volume* vol)
569 : {
570 : // flips the orientation of volumes
571 : // get the descriptor for the flipped volume
572 0 : VolumeDescriptor vd;
573 0 : vol->get_flipped_orientation(vd);
574 :
575 : // change vertex order of the original volume
576 0 : size_t numVrts = vol->num_vertices();
577 0 : for(size_t i = 0; i < numVrts; ++i)
578 0 : vol->set_vertex(i, vd.vertex(i));
579 :
580 : // update associated edge list
581 0 : if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES)){
582 : m_aaEdgeContainerVOLUME[vol].clear();
583 0 : EdgeDescriptor ed;
584 0 : for(size_t ind = 0; ind < vol->num_edges(); ++ind){
585 : // get the descriptor of the i-th edge
586 0 : vol->edge_desc(ind, ed);
587 : // find the edge by checking vertices.
588 0 : Edge* e = find_edge_in_associated_edges(ed.vertex(0), ed);
589 0 : if(e)
590 0 : m_aaEdgeContainerVOLUME[vol].push_back(e);
591 : }
592 : }
593 :
594 : // update associated face list
595 0 : if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES)){
596 : m_aaFaceContainerVOLUME[vol].clear();
597 0 : FaceDescriptor fd;
598 0 : for(size_t ind = 0; ind < vol->num_faces(); ++ind){
599 : // get the descriptor of the i-th face
600 0 : vol->face_desc(ind, fd);
601 : // find the face by checking vertices.
602 0 : Face* f = find_face_in_associated_faces(fd.vertex(0), fd);
603 0 : if(f)
604 0 : m_aaFaceContainerVOLUME[vol].push_back(f);
605 : }
606 : }
607 0 : }
608 :
609 0 : size_t Grid::vertex_fragmentation()
610 : {
611 0 : return m_vertexElementStorage.m_attachmentPipe.num_data_entries() - m_vertexElementStorage.m_attachmentPipe.num_elements();
612 : }
613 :
614 0 : size_t Grid::edge_fragmentation()
615 : {
616 0 : return m_edgeElementStorage.m_attachmentPipe.num_data_entries() - m_edgeElementStorage.m_attachmentPipe.num_elements();
617 : }
618 :
619 0 : size_t Grid::face_fragmentation()
620 : {
621 0 : return m_faceElementStorage.m_attachmentPipe.num_data_entries() - m_faceElementStorage.m_attachmentPipe.num_elements();
622 : }
623 :
624 0 : size_t Grid::volume_fragmentation()
625 : {
626 0 : return m_volumeElementStorage.m_attachmentPipe.num_data_entries() - m_volumeElementStorage.m_attachmentPipe.num_elements();
627 : }
628 :
629 :
630 0 : GridObject* Grid::
631 : get_opposing_object(Vertex* vrt, Face* elem)
632 : {
633 0 : std::pair<GridBaseObjectId, int> id = elem->get_opposing_object(vrt);
634 0 : switch(id.first){
635 0 : case VERTEX:
636 0 : return elem->vertex(id.second);
637 0 : case EDGE:
638 0 : return get_edge(elem, id.second);
639 0 : default:
640 0 : UG_THROW("Unsupported geometric base object type returned by "
641 : "Face::get_opposing_object(vrt)");
642 : }
643 : }
644 :
645 0 : GridObject* Grid::
646 : get_opposing_object(Vertex* vrt, Volume* elem)
647 : {
648 0 : std::pair<GridBaseObjectId, int> id = elem->get_opposing_object(vrt);
649 0 : switch(id.first){
650 0 : case VERTEX:
651 0 : return elem->vertex(id.second);
652 0 : case EDGE:
653 0 : return get_edge(elem, id.second);
654 0 : case FACE:
655 0 : return get_face(elem, id.second);
656 0 : default:
657 0 : UG_THROW("Unsupported geometric base object type returned by "
658 : "Volume::get_opposing_object(vrt)");
659 : }
660 : }
661 :
662 :
663 : ////////////////////////////////////////////////////////////////////////
664 : // pass_on_values
665 : template <class TAttachmentPipe, class TElem>
666 : void Grid::pass_on_values(TAttachmentPipe& attachmentPipe,
667 : TElem* pSrc, TElem* pDest)
668 : {
669 0 : for(typename TAttachmentPipe::ConstAttachmentEntryIterator
670 : iter = attachmentPipe.attachments_begin();
671 0 : iter != attachmentPipe.attachments_end(); iter++)
672 : {
673 0 : if((*iter).m_userData == 1)
674 0 : (*iter).m_pContainer->copy_data(get_attachment_data_index(pSrc),
675 : get_attachment_data_index(pDest));
676 : }
677 : }
678 :
679 0 : void Grid::pass_on_values(Vertex* objSrc, Vertex* objDest)
680 : {
681 : pass_on_values(m_vertexElementStorage.m_attachmentPipe, objSrc, objDest);
682 0 : }
683 :
684 0 : void Grid::pass_on_values(Edge* objSrc, Edge* objDest)
685 : {
686 : pass_on_values(m_edgeElementStorage.m_attachmentPipe, objSrc, objDest);
687 0 : }
688 :
689 0 : void Grid::pass_on_values(Face* objSrc, Face* objDest)
690 : {
691 : pass_on_values(m_faceElementStorage.m_attachmentPipe, objSrc, objDest);
692 0 : }
693 :
694 0 : void Grid::pass_on_values(Volume* objSrc, Volume* objDest)
695 : {
696 : pass_on_values(m_volumeElementStorage.m_attachmentPipe, objSrc, objDest);
697 0 : }
698 :
699 : ////////////////////////////////////////////////////////////////////////
700 : // options
701 2 : void Grid::set_options(uint options)
702 : {
703 2 : change_options(options);
704 2 : }
705 :
706 1 : uint Grid::get_options() const
707 : {
708 1 : return m_options;
709 : }
710 :
711 0 : void Grid::enable_options(uint options)
712 : {
713 0 : change_options(m_options | options);
714 0 : }
715 :
716 0 : void Grid::disable_options(uint options)
717 : {
718 0 : change_options(m_options & (~options));
719 0 : }
720 :
721 99 : bool Grid::option_is_enabled(uint option) const
722 : {
723 99 : return (m_options & option) == option;
724 : }
725 :
726 3 : void Grid::change_options(uint optsNew)
727 : {
728 3 : change_vertex_options(optsNew & 0x000000FF);
729 3 : change_edge_options(optsNew & 0x0000FF00);
730 3 : change_face_options(optsNew & 0x00FF0000);
731 3 : change_volume_options(optsNew & 0xFF000000);
732 : assert((m_options == optsNew) && "Grid::change_options failed");
733 3 : }
734 : /*
735 : void Grid::register_observer(GridObserver* observer, uint observerType)
736 : {
737 : // check which elements have to be observed and store pointers to the observers.
738 : // avoid double-registration!
739 : ObserverContainer* observerContainers[] = {&m_gridObservers, &m_vertexObservers,
740 : &m_edgeObservers, & m_faceObservers, &m_volumeObservers};
741 :
742 : uint observerTypes[] = {OT_GRID_OBSERVER, OT_VERTEX_OBSERVER, OT_EDGE_OBSERVER, OT_FACE_OBSERVER, OT_VOLUME_OBSERVER};
743 : for(int i = 0; i < 5; ++i)
744 : {
745 : if((observerType & observerTypes[i]) == observerTypes[i])
746 : {
747 : ObserverContainer::iterator iter = find(observerContainers[i]->begin(), observerContainers[i]->end(), observer);
748 : if(iter == observerContainers[i]->end())
749 : observerContainers[i]->push_back(observer);
750 : }
751 : }
752 :
753 : // if the observer is a grid observer, notify him about the registration
754 : if((observerType & OT_GRID_OBSERVER) == OT_GRID_OBSERVER)
755 : observer->registered_at_grid(this);
756 : }
757 :
758 : void Grid::unregister_observer(GridObserver* observer)
759 : {
760 : // check where the observer has been registered and erase the corresponding entries.
761 : ObserverContainer* observerContainers[] = {&m_gridObservers, &m_vertexObservers,
762 : &m_edgeObservers, & m_faceObservers, &m_volumeObservers};
763 :
764 : bool unregisterdFromGridObservers = false;
765 : for(int i = 0; i < 5; ++i)
766 : {
767 : ObserverContainer::iterator iter = find(observerContainers[i]->begin(), observerContainers[i]->end(), observer);
768 : if(iter != observerContainers[i]->end())
769 : {
770 : if(i == 0)
771 : unregisterdFromGridObservers = true;
772 : observerContainers[i]->erase(iter);
773 : }
774 : }
775 :
776 : // if the observer is a grid observer, notify him about the unregistration
777 : if(unregisterdFromGridObservers)
778 : observer->unregistered_from_grid(this);
779 : }
780 : */
781 0 : void Grid::register_observer(GridObserver* observer, uint observerType)
782 : {
783 : // check which elements have to be observed and store pointers to the observers.
784 : // avoid double-registration!
785 0 : if((observerType & OT_GRID_OBSERVER) == OT_GRID_OBSERVER)
786 : {
787 0 : ObserverContainer::iterator iter = find(m_gridObservers.begin(),
788 : m_gridObservers.end(), observer);
789 0 : if(iter == m_gridObservers.end())
790 0 : m_gridObservers.push_back(observer);
791 : }
792 :
793 0 : if((observerType & OT_VERTEX_OBSERVER) == OT_VERTEX_OBSERVER)
794 : {
795 0 : ObserverContainer::iterator iter = find(m_vertexObservers.begin(),
796 : m_vertexObservers.end(), observer);
797 0 : if(iter == m_vertexObservers.end())
798 0 : m_vertexObservers.push_back(observer);
799 : }
800 :
801 0 : if((observerType & OT_EDGE_OBSERVER) == OT_EDGE_OBSERVER)
802 : {
803 0 : ObserverContainer::iterator iter = find(m_edgeObservers.begin(),
804 : m_edgeObservers.end(), observer);
805 0 : if(iter == m_edgeObservers.end())
806 0 : m_edgeObservers.push_back(observer);
807 : }
808 :
809 0 : if((observerType & OT_FACE_OBSERVER) == OT_FACE_OBSERVER)
810 : {
811 0 : ObserverContainer::iterator iter = find(m_faceObservers.begin(),
812 : m_faceObservers.end(), observer);
813 0 : if(iter == m_faceObservers.end())
814 0 : m_faceObservers.push_back(observer);
815 : }
816 :
817 0 : if((observerType & OT_VOLUME_OBSERVER) == OT_VOLUME_OBSERVER)
818 : {
819 0 : ObserverContainer::iterator iter = find(m_volumeObservers.begin(),
820 : m_volumeObservers.end(), observer);
821 0 : if(iter == m_volumeObservers.end())
822 0 : m_volumeObservers.push_back(observer);
823 : }
824 :
825 : // if the observer is a grid observer, notify him about the registration
826 : // if((observerType & OT_GRID_OBSERVER) == OT_GRID_OBSERVER)
827 : // observer->registered_at_grid(this);
828 0 : }
829 :
830 0 : void Grid::unregister_observer(GridObserver* observer)
831 : {
832 : // check where the observer has been registered and erase the corresponding entries.
833 : //bool unregisterdFromGridObservers = false;
834 :
835 : {
836 0 : ObserverContainer::iterator iter = find(m_gridObservers.begin(),
837 : m_gridObservers.end(), observer);
838 0 : if(iter != m_gridObservers.end()){
839 0 : m_gridObservers.erase(iter);
840 : }
841 :
842 : // unregisterdFromGridObservers = true;
843 : }
844 :
845 : {
846 0 : ObserverContainer::iterator iter = find(m_vertexObservers.begin(),
847 : m_vertexObservers.end(), observer);
848 0 : if(iter != m_vertexObservers.end())
849 0 : m_vertexObservers.erase(iter);
850 : }
851 :
852 : {
853 0 : ObserverContainer::iterator iter = find(m_edgeObservers.begin(),
854 : m_edgeObservers.end(), observer);
855 0 : if(iter != m_edgeObservers.end())
856 0 : m_edgeObservers.erase(iter);
857 : }
858 :
859 : {
860 0 : ObserverContainer::iterator iter = find(m_faceObservers.begin(),
861 : m_faceObservers.end(), observer);
862 0 : if(iter != m_faceObservers.end())
863 0 : m_faceObservers.erase(iter);
864 : }
865 :
866 : {
867 0 : ObserverContainer::iterator iter = find(m_volumeObservers.begin(),
868 : m_volumeObservers.end(), observer);
869 0 : if(iter != m_volumeObservers.end())
870 0 : m_volumeObservers.erase(iter);
871 : }
872 :
873 : // if the observer is a grid observer, notify him about the unregistration
874 : // if(unregisterdFromGridObservers)
875 : // observer->unregistered_from_grid(this);
876 :
877 0 : }
878 :
879 :
880 : ////////////////////////////////////////////////////////////////////////
881 : // associated edge access
882 3 : Grid::AssociatedEdgeIterator Grid::associated_edges_begin(Vertex* vrt)
883 : {
884 3 : if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
885 : {
886 : LOG("WARNING in associated_edges_begin(vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_EDGES." << endl);
887 0 : vertex_store_associated_edges(true);
888 : }
889 3 : return m_aaEdgeContainerVERTEX[vrt].begin();
890 : }
891 :
892 3 : Grid::AssociatedEdgeIterator Grid::associated_edges_end(Vertex* vrt)
893 : {
894 3 : if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
895 : {
896 : LOG("WARNING in associated_edges_end(vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_EDGES." << endl);
897 0 : vertex_store_associated_edges(true);
898 : }
899 3 : return m_aaEdgeContainerVERTEX[vrt].end();
900 : }
901 :
902 0 : Grid::AssociatedEdgeIterator Grid::associated_edges_begin(Face* face)
903 : {
904 0 : if(!option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
905 : {
906 : LOG("WARNING in associated_edges_begin(face): auto-enabling FACEOPT_STORE_ASSOCIATED_EDGES." << endl);
907 0 : face_store_associated_edges(true);
908 : }
909 0 : return m_aaEdgeContainerFACE[face].begin();
910 : }
911 :
912 0 : Grid::AssociatedEdgeIterator Grid::associated_edges_end(Face* face)
913 : {
914 0 : if(!option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
915 : {
916 : LOG("WARNING in associated_edges_end(face): auto-enabling FACEOPT_STORE_ASSOCIATED_EDGES." << endl);
917 0 : face_store_associated_edges(true);
918 : }
919 0 : return m_aaEdgeContainerFACE[face].end();
920 : }
921 :
922 0 : Grid::AssociatedEdgeIterator Grid::associated_edges_begin(Volume* vol)
923 : {
924 0 : if(!option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
925 : {
926 : LOG("WARNING in associated_edges_begin(vol): auto-enabling VOLOPT_STORE_ASSOCIATED_EDGES." << endl);
927 0 : volume_store_associated_edges(true);
928 : }
929 0 : return m_aaEdgeContainerVOLUME[vol].begin();
930 : }
931 :
932 0 : Grid::AssociatedEdgeIterator Grid::associated_edges_end(Volume* vol)
933 : {
934 0 : if(!option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
935 : {
936 : LOG("WARNING in associated_edges_end(vol): auto-enabling VOLOPT_STORE_ASSOCIATED_EDGES." << endl);
937 0 : volume_store_associated_edges(true);
938 : }
939 0 : return m_aaEdgeContainerVOLUME[vol].end();
940 : }
941 :
942 : ////////////////////////////////////////////////////////////////////////
943 : // associated face access
944 0 : Grid::AssociatedFaceIterator Grid::associated_faces_begin(Vertex* vrt)
945 : {
946 0 : if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
947 : {
948 : LOG("WARNING in associated_faces_begin(vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_FACES." << endl);
949 0 : vertex_store_associated_faces(true);
950 : }
951 0 : return m_aaFaceContainerVERTEX[vrt].begin();
952 : }
953 :
954 0 : Grid::AssociatedFaceIterator Grid::associated_faces_end(Vertex* vrt)
955 : {
956 0 : if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
957 : {
958 : LOG("WARNING in associated_faces_end(vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_FACES." << endl);
959 0 : vertex_store_associated_faces(true);
960 : }
961 0 : return m_aaFaceContainerVERTEX[vrt].end();
962 : }
963 :
964 0 : Grid::AssociatedFaceIterator Grid::associated_faces_begin(Edge* edge)
965 : {
966 0 : if(!option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
967 : {
968 : LOG("WARNING in associated_faces_begin(edge): auto-enabling EDGEOPT_STORE_ASSOCIATED_FACES." << endl);
969 0 : edge_store_associated_faces(true);
970 : }
971 0 : return m_aaFaceContainerEDGE[edge].begin();
972 : }
973 :
974 0 : Grid::AssociatedFaceIterator Grid::associated_faces_end(Edge* edge)
975 : {
976 0 : if(!option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
977 : {
978 : LOG("WARNING in associated_faces_end(edge): auto-enabling EDGEOPT_STORE_ASSOCIATED_FACES." << endl);
979 0 : edge_store_associated_faces(true);
980 : }
981 0 : return m_aaFaceContainerEDGE[edge].end();
982 : }
983 :
984 0 : Grid::AssociatedFaceIterator Grid::associated_faces_begin(Volume* vol)
985 : {
986 0 : if(!option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
987 : {
988 : LOG("WARNING in associated_faces_begin(vol): auto-enabling VOLOPT_STORE_ASSOCIATED_FACES." << endl);
989 0 : volume_store_associated_faces(true);
990 : }
991 0 : return m_aaFaceContainerVOLUME[vol].begin();
992 : }
993 :
994 0 : Grid::AssociatedFaceIterator Grid::associated_faces_end(Volume* vol)
995 : {
996 0 : if(!option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
997 : {
998 : LOG("WARNING in associated_faces_end(vol): auto-enabling VOLOPT_STORE_ASSOCIATED_FACES." << endl);
999 0 : volume_store_associated_faces(true);
1000 : }
1001 0 : return m_aaFaceContainerVOLUME[vol].end();
1002 : }
1003 :
1004 : ////////////////////////////////////////////////////////////////////////
1005 : // associated volume access
1006 0 : Grid::AssociatedVolumeIterator Grid::associated_volumes_begin(Vertex* vrt)
1007 : {
1008 0 : if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
1009 : {
1010 : LOG("WARNING in associated_volumes_begin(vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_VOLUMES." << endl);
1011 0 : vertex_store_associated_volumes(true);
1012 : }
1013 0 : return m_aaVolumeContainerVERTEX[vrt].begin();
1014 : }
1015 :
1016 0 : Grid::AssociatedVolumeIterator Grid::associated_volumes_end(Vertex* vrt)
1017 : {
1018 0 : if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
1019 : {
1020 : LOG("WARNING in associated_volumes_end(vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_VOLUMES." << endl);
1021 0 : vertex_store_associated_volumes(true);
1022 : }
1023 0 : return m_aaVolumeContainerVERTEX[vrt].end();
1024 : }
1025 :
1026 0 : Grid::AssociatedVolumeIterator Grid::associated_volumes_begin(Edge* edge)
1027 : {
1028 0 : if(!option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
1029 : {
1030 : LOG("WARNING in associated_volumes_begin(edge): auto-enabling EDGEOPT_STORE_ASSOCIATED_VOLUMES." << endl);
1031 0 : edge_store_associated_volumes(true);
1032 : }
1033 0 : return m_aaVolumeContainerEDGE[edge].begin();
1034 : }
1035 :
1036 0 : Grid::AssociatedVolumeIterator Grid::associated_volumes_end(Edge* edge)
1037 : {
1038 0 : if(!option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
1039 : {
1040 : LOG("WARNING in associated_volumes_end(edge): auto-enabling EDGEOPT_STORE_ASSOCIATED_VOLUMES." << endl);
1041 0 : edge_store_associated_volumes(true);
1042 : }
1043 0 : return m_aaVolumeContainerEDGE[edge].end();
1044 : }
1045 :
1046 0 : Grid::AssociatedVolumeIterator Grid::associated_volumes_begin(Face* face)
1047 : {
1048 0 : if(!option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
1049 : {
1050 : LOG("WARNING in associated_volumes_begin(face): auto-enabling FACEOPT_STORE_ASSOCIATED_VOLUMES." << endl);
1051 0 : face_store_associated_volumes(true);
1052 : }
1053 0 : return m_aaVolumeContainerFACE[face].begin();
1054 : }
1055 :
1056 0 : Grid::AssociatedVolumeIterator Grid::associated_volumes_end(Face* face)
1057 : {
1058 0 : if(!option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
1059 : {
1060 : LOG("WARNING in associated_volumes_end(face): auto-enabling FACEOPT_STORE_ASSOCIATED_VOLUMES." << endl);
1061 0 : face_store_associated_volumes(true);
1062 : }
1063 0 : return m_aaVolumeContainerFACE[face].end();
1064 : }
1065 :
1066 : ////////////////////////////////////////////////////////////////////////
1067 : ////////////////////////////////////////////////////////////////////////
1068 : // neighbourhood access
1069 0 : Edge* Grid::get_edge(Vertex* v1, Vertex* v2)
1070 : {
1071 0 : EdgeDescriptor ed(v1, v2);
1072 0 : return find_edge_in_associated_edges(v1, ed);
1073 : }
1074 :
1075 0 : Edge* Grid::get_edge(const EdgeVertices& ev)
1076 : {
1077 0 : return find_edge_in_associated_edges(ev.vertex(0), ev);
1078 : }
1079 :
1080 0 : Edge* Grid::get_edge(Face* f, int ind)
1081 : {
1082 : // check whether the face stores associated edges
1083 0 : if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
1084 : {
1085 0 : if(option_is_enabled(FACEOPT_AUTOGENERATE_EDGES))
1086 0 : return m_aaEdgeContainerFACE[f][ind];
1087 : else{
1088 0 : EdgeDescriptor ed;
1089 0 : f->edge_desc(ind, ed);
1090 0 : return find_edge_in_associated_edges(f, ed);
1091 : }
1092 : }
1093 : else
1094 : {
1095 : // get the descriptor of the i-th edge
1096 0 : EdgeDescriptor ed;
1097 0 : f->edge_desc(ind, ed);
1098 : // it doesn't. find the edge by checking vertices.
1099 0 : return find_edge_in_associated_edges(ed.vertex(0), ed);
1100 : }
1101 :
1102 : return NULL;
1103 : }
1104 :
1105 0 : Edge* Grid::get_edge(Volume* v, int ind)
1106 : {
1107 : // check whether the face stores associated edges
1108 0 : if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
1109 : {
1110 : // if autogenerate is enabeld, edges are sorted.
1111 0 : if(option_is_enabled(VOLOPT_AUTOGENERATE_EDGES)
1112 0 : || option_is_enabled(VOLOPT_AUTOGENERATE_FACES
1113 : | FACEOPT_AUTOGENERATE_EDGES))
1114 : {
1115 0 : return m_aaEdgeContainerVOLUME[v][ind];
1116 : }
1117 : else{
1118 0 : EdgeDescriptor ed;
1119 0 : v->edge_desc(ind, ed);
1120 0 : return find_edge_in_associated_edges(v, ed);
1121 : }
1122 : }
1123 : else
1124 : {
1125 : // get the descriptor of the i-th edge
1126 0 : EdgeDescriptor ed;
1127 0 : v->edge_desc(ind, ed);
1128 : // it doesn't. find the edge by checking vertices.
1129 0 : return find_edge_in_associated_edges(ed.vertex(0), ed);
1130 : }
1131 :
1132 : return NULL;
1133 : }
1134 :
1135 0 : Face* Grid::get_face(const FaceVertices& fv)
1136 : {
1137 0 : return find_face_in_associated_faces(fv.vertex(0), fv);
1138 : }
1139 :
1140 0 : Face* Grid::get_face(Volume* v, int ind)
1141 : {
1142 : // check whether the volume stores associated faces
1143 0 : if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
1144 : {
1145 : // if autogenerate is enabeld, faces are sorted.
1146 0 : if(option_is_enabled(VOLOPT_AUTOGENERATE_FACES))
1147 0 : return m_aaFaceContainerVOLUME[v][ind];
1148 : else{
1149 0 : FaceDescriptor fd;
1150 0 : v->face_desc(ind, fd);
1151 0 : return find_face_in_associated_faces(v, fd);
1152 : }
1153 : }
1154 : else {
1155 0 : FaceDescriptor fd;
1156 0 : v->face_desc(ind, fd);
1157 : // it does not. check associated faces of the first vertex of fd.
1158 0 : return find_face_in_associated_faces(fd.vertex(0), fd);
1159 : }
1160 : return NULL;
1161 : }
1162 :
1163 0 : Volume* Grid::get_volume(const VolumeVertices& vv)
1164 : {
1165 0 : return find_volume_in_associated_volumes(vv.vertex(0), vv);
1166 : }
1167 :
1168 : ////////////////////////////////////////////////////////////////////////
1169 : // sides
1170 0 : Vertex::side* Grid::get_side(Vertex* obj, size_t side)
1171 : {
1172 : GRID_PROFILE_FUNC();
1173 : assert(!"ERROR in Grid::get_side(Vertex*, ...): A vertex doesn't have sides!");
1174 0 : return NULL;
1175 : }
1176 :
1177 0 : Edge::side* Grid::get_side(Edge* obj, size_t side)
1178 : {
1179 : GRID_PROFILE_FUNC();
1180 : assert(side < 2 && "ERROR in Grid::get_side(Edge*, ...): Bad side index!");
1181 0 : return obj->vertex(side);
1182 : }
1183 :
1184 0 : Face::side* Grid::get_side(Face* obj, size_t side)
1185 : {
1186 : GRID_PROFILE_FUNC();
1187 : assert(side < obj->num_edges() && "ERROR in Grid::get_side(Face*, ...): Bad side index!");
1188 0 : return get_edge(obj, side);
1189 : }
1190 :
1191 0 : Volume::side* Grid::get_side(Volume* obj, size_t side)
1192 : {
1193 : GRID_PROFILE_FUNC();
1194 : assert(side < obj->num_faces() && "ERROR in Grid::get_side(Volume*, ...): Bad side index!");
1195 0 : return get_face(obj, side);
1196 : }
1197 :
1198 : ////////////////////////////////////////////////////////////////////////
1199 : // marks
1200 0 : void Grid::init_marks()
1201 : {
1202 : // attach marks to the elements
1203 0 : if(m_currentMark == 0)
1204 : {
1205 : // marks have not yet been initialized - do that now
1206 : // attach m_currentMark with default value 0
1207 : // (0 is never the currentMark while marks are active).
1208 0 : m_currentMark = 1;
1209 0 : attach_to_vertices_dv(m_aMark, 0);
1210 0 : attach_to_edges_dv(m_aMark, 0);
1211 0 : attach_to_faces_dv(m_aMark, 0);
1212 0 : attach_to_volumes_dv(m_aMark, 0);
1213 :
1214 : m_aaMarkVRT.access(*this, m_aMark);
1215 : m_aaMarkEDGE.access(*this, m_aMark);
1216 : m_aaMarkFACE.access(*this, m_aMark);
1217 : m_aaMarkVOL.access(*this, m_aMark);
1218 :
1219 0 : m_bMarking = false;
1220 : }
1221 0 : }
1222 :
1223 0 : void Grid::reset_marks()
1224 : {
1225 : // set all marks to 0 and m_currentMark to 1
1226 0 : m_currentMark = 1;
1227 : AMark::ContainerType* pContainer;
1228 :
1229 : // reset vertex marks
1230 0 : pContainer = get_attachment_data_container<Vertex>(m_aMark);
1231 0 : for(uint i = 0; i < pContainer->size(); ++i)
1232 0 : pContainer->get_elem(i) = 0;
1233 :
1234 : // reset edge marks
1235 : pContainer = get_attachment_data_container<Edge>(m_aMark);
1236 0 : for(uint i = 0; i < pContainer->size(); ++i)
1237 0 : pContainer->get_elem(i) = 0;
1238 :
1239 : // reset face marks
1240 : pContainer = get_attachment_data_container<Face>(m_aMark);
1241 0 : for(uint i = 0; i < pContainer->size(); ++i)
1242 0 : pContainer->get_elem(i) = 0;
1243 :
1244 : // reset volume marks
1245 : pContainer = get_attachment_data_container<Volume>(m_aMark);
1246 0 : for(uint i = 0; i < pContainer->size(); ++i)
1247 0 : pContainer->get_elem(i) = 0;
1248 0 : }
1249 :
1250 1 : void Grid::remove_marks()
1251 : {
1252 1 : if(m_currentMark != 0)
1253 : {
1254 0 : m_currentMark = 0;
1255 0 : detach_from_vertices(m_aMark);
1256 : detach_from_edges(m_aMark);
1257 : detach_from_faces(m_aMark);
1258 : detach_from_volumes(m_aMark);
1259 : }
1260 1 : }
1261 :
1262 0 : void Grid::begin_marking()
1263 : {
1264 0 : if(m_currentMark == 0)
1265 : {
1266 : // marks are disabled. we have to activate them
1267 0 : init_marks();
1268 : }
1269 :
1270 0 : if(m_bMarking){
1271 0 : throw(UGError("ERROR in Grid::begin_marking(): marking is already active. Don't forget to call end_marking when you're done with marking."));
1272 : }
1273 :
1274 : // increase currentMark
1275 0 : ++m_currentMark;
1276 :
1277 : // check whether we have to reset-marks
1278 0 : if(m_currentMark == -1)
1279 0 : reset_marks();
1280 :
1281 : // set m_bMarking to true
1282 0 : m_bMarking = true;
1283 0 : }
1284 :
1285 0 : void Grid::end_marking()
1286 : {
1287 0 : m_bMarking = false;
1288 0 : }
1289 :
1290 0 : void Grid::clear_marks()
1291 : {
1292 0 : if(m_bMarking){
1293 0 : end_marking();
1294 0 : begin_marking();
1295 : }
1296 : else{
1297 0 : begin_marking();
1298 0 : end_marking();
1299 : }
1300 0 : }
1301 :
1302 0 : void Grid::test_attached_linked_lists()
1303 : {
1304 : UG_LOG("empty\n");
1305 0 : }
1306 :
1307 : }// end of namespace
|