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_IMPLEMENTATION__
34 : #define __H__LIB_GRID__GRID_IMPLEMENTATION__
35 :
36 : //#include <cassert>
37 : #include "common/common.h"
38 : #include "common/static_assert.h"
39 : #include "grid_util.h"
40 : #include "grid.h"
41 :
42 : namespace ug
43 : {
44 : ////////////////////////////////////////////////////////////////////////
45 : // parallelism
46 : bool Grid::
47 : is_parallel() const
48 : {
49 0 : return m_distGridMgr != NULL;
50 : }
51 :
52 : DistributedGridManager* Grid::
53 : distributed_grid_manager()
54 : {
55 0 : return m_distGridMgr;
56 : }
57 :
58 : const DistributedGridManager* Grid::
59 : distributed_grid_manager() const
60 : {
61 0 : return m_distGridMgr;
62 : }
63 :
64 :
65 : ////////////////////////////////////////////////////////////////////////
66 : // create functions
67 : template<class TGeomObj>
68 : typename geometry_traits<TGeomObj>::iterator
69 3 : Grid::create(GridObject* pParent)
70 : {
71 : STATIC_ASSERT(geometry_traits<TGeomObj>::CONTAINER_SECTION != -1
72 : && geometry_traits<TGeomObj>::BASE_OBJECT_ID != -1,
73 : invalid_geometry_type);
74 :
75 3 : TGeomObj* geomObj = new TGeomObj;
76 : // int baseObjectType = geometry_traits<GeomObjType>::base_object_type();
77 : // geomObj->m_elemHandle = m_elementStorage[baseObjectType].m_sectionContainer.insert_element(geomObj, geometry_traits<GeomObjType>::container_section());
78 : // m_elementStorage[baseObjectType].m_attachmentPipe.register_element(geomObj);
79 :
80 : register_element(geomObj, pParent);
81 :
82 3 : return iterator_cast<typename geometry_traits<TGeomObj>::iterator>(get_iterator(geomObj));
83 : }
84 :
85 : template <class TGeomObj>
86 : typename geometry_traits<TGeomObj>::iterator
87 1 : Grid::create(const typename geometry_traits<TGeomObj>::Descriptor& descriptor,
88 : GridObject* pParent)
89 : {
90 : STATIC_ASSERT(geometry_traits<TGeomObj>::CONTAINER_SECTION != -1
91 : && geometry_traits<TGeomObj>::BASE_OBJECT_ID != -1,
92 : invalid_geometry_type);
93 :
94 1 : TGeomObj* geomObj = new TGeomObj(descriptor);
95 :
96 : // int baseObjectType = geometry_traits<TGeomObj>::base_object_type();
97 : // geomObj->m_elemHandle = m_elementStorage[baseObjectType].m_sectionContainer.insert_element(geomObj, geometry_traits<GeomObjType>::container_section());
98 : // m_elementStorage[baseObjectType].m_attachmentPipe.register_element(geomObj);
99 :
100 : register_element(geomObj, pParent);
101 :
102 1 : return iterator_cast<typename geometry_traits<TGeomObj>::iterator>(get_iterator(geomObj));
103 : }
104 :
105 : template<class TGeomObj>
106 : typename geometry_traits<TGeomObj>::iterator
107 0 : Grid::create_and_replace(typename geometry_traits<TGeomObj>::grid_base_object* pReplaceMe)
108 : {
109 : STATIC_ASSERT(geometry_traits<TGeomObj>::CONTAINER_SECTION != -1
110 : && geometry_traits<TGeomObj>::BASE_OBJECT_ID != -1,
111 : invalid_geometry_type);
112 :
113 0 : TGeomObj* geomObj = new TGeomObj;
114 :
115 0 : if(geomObj->reference_object_id() == pReplaceMe->reference_object_id())
116 : {
117 0 : register_and_replace_element(geomObj, pReplaceMe);
118 : return iterator_cast<typename geometry_traits<TGeomObj>::iterator>(get_iterator(geomObj));
119 : }
120 : else
121 : {
122 : LOG("ERROR in Grid::create_and_replace(...): reference objects do not match!");
123 : assert(!"ERROR in Grid::create_and_replace(...): reference objects do not match!");
124 0 : delete geomObj;
125 : return end<TGeomObj>();
126 : }
127 : }
128 :
129 : ////////////////////////////////////////////////////////////////////////
130 : template <class TGeomObj>
131 0 : void Grid::reserve(size_t num)
132 : {
133 : STATIC_ASSERT(geometry_traits<TGeomObj>::BASE_OBJECT_ID != -1,
134 : invalid_geometry_type);
135 :
136 : element_storage<TGeomObj>().m_attachmentPipe.reserve(num);
137 0 : }
138 :
139 : ////////////////////////////////////////////////////////////////////////
140 : // erase
141 : template <class GeomObjIter>
142 0 : void Grid::erase(const GeomObjIter& iterBegin, const GeomObjIter& iterEnd)
143 : {
144 : GeomObjIter iter = iterBegin;
145 0 : while(iter != iterEnd)
146 : {
147 : GeomObjIter tmpIter = iter;
148 : ++iter;
149 0 : erase(*tmpIter);
150 : }
151 0 : }
152 :
153 : template <class TGeomObj>
154 : void Grid::clear()
155 : {
156 11 : while(begin<TGeomObj>() != end<TGeomObj>())
157 7 : erase(*begin<TGeomObj>());
158 : }
159 :
160 : ////////////////////////////////////////////////////////////////////////
161 : // Iterators
162 : template <class TGeomObj>
163 : typename geometry_traits<TGeomObj>::iterator
164 : Grid::begin()
165 : {
166 : STATIC_ASSERT(geometry_traits<TGeomObj>::BASE_OBJECT_ID != -1,
167 : invalid_GeomObj);
168 :
169 : return iterator_cast<typename geometry_traits<TGeomObj>::iterator>
170 0 : (element_storage<TGeomObj>().m_sectionContainer.section_begin(geometry_traits<TGeomObj>::CONTAINER_SECTION));
171 : }
172 :
173 : template <class TGeomObj>
174 : typename geometry_traits<TGeomObj>::iterator
175 : Grid::end()
176 : {
177 : STATIC_ASSERT(geometry_traits<TGeomObj>::BASE_OBJECT_ID != -1,
178 : invalid_GeomObj);
179 :
180 : return iterator_cast<typename geometry_traits<TGeomObj>::iterator>
181 0 : (element_storage<TGeomObj>().m_sectionContainer.section_end(geometry_traits<TGeomObj>::CONTAINER_SECTION));
182 : }
183 :
184 : template <class TGeomObj>
185 : typename geometry_traits<TGeomObj>::const_iterator
186 : Grid::begin() const
187 : {
188 : STATIC_ASSERT(geometry_traits<TGeomObj>::BASE_OBJECT_ID != -1,
189 : invalid_GeomObj);
190 :
191 : return iterator_cast<typename geometry_traits<TGeomObj>::const_iterator>
192 0 : (element_storage<TGeomObj>().m_sectionContainer.section_begin(geometry_traits<TGeomObj>::CONTAINER_SECTION));
193 : }
194 :
195 : template <class TGeomObj>
196 : typename geometry_traits<TGeomObj>::const_iterator
197 : Grid::end() const
198 : {
199 : STATIC_ASSERT(geometry_traits<TGeomObj>::BASE_OBJECT_ID != -1,
200 : invalid_GeomObj);
201 :
202 : return iterator_cast<typename geometry_traits<TGeomObj>::const_iterator>
203 0 : (element_storage<TGeomObj>().m_sectionContainer.section_end(geometry_traits<TGeomObj>::CONTAINER_SECTION));
204 : }
205 :
206 : template <class TGeomObj>
207 : TGeomObj*
208 : Grid::front()
209 : {
210 : STATIC_ASSERT(geometry_traits<TGeomObj>::BASE_OBJECT_ID != -1,
211 : invalid_GeomObj);
212 :
213 : return static_cast<TGeomObj*>(*element_storage<TGeomObj>().m_sectionContainer.
214 : front(geometry_traits<TGeomObj>::CONTAINER_SECTION));
215 : }
216 :
217 : template <class TGeomObj>
218 : TGeomObj*
219 : Grid::back()
220 : {
221 : STATIC_ASSERT(geometry_traits<TGeomObj>::BASE_OBJECT_ID != -1,
222 : invalid_GeomObj);
223 :
224 : return static_cast<TGeomObj*>(*element_storage<TGeomObj>().m_sectionContainer.
225 : back(geometry_traits<TGeomObj>::CONTAINER_SECTION));
226 : }
227 : ////////////////////////////////////////////////////////////////////////
228 : // element numbers
229 : template <class TGeomObj>
230 0 : size_t Grid::num() const
231 : {
232 : STATIC_ASSERT(geometry_traits<TGeomObj>::BASE_OBJECT_ID != -1,
233 : invalid_GeomObj);
234 :
235 : int secIndex = geometry_traits<TGeomObj>::CONTAINER_SECTION;
236 :
237 : if(secIndex == -1)
238 13 : return element_storage<TGeomObj>().m_sectionContainer.num_elements();
239 :
240 0 : return element_storage<TGeomObj>().m_sectionContainer.num_elements(secIndex);
241 : }
242 :
243 : inline void Grid::
244 : objects_will_be_merged(Vertex* target, Vertex* elem1,
245 : Vertex* elem2)
246 : {
247 0 : for(Grid::ObserverContainer::iterator iter = m_vertexObservers.begin();
248 0 : iter != m_vertexObservers.end(); iter++)
249 : {
250 0 : (*iter)->vertices_to_be_merged(this, target, elem1, elem2);
251 : }
252 : }
253 :
254 : inline void Grid::
255 : objects_will_be_merged(Edge* target, Edge* elem1,
256 : Edge* elem2)
257 : {
258 0 : for(Grid::ObserverContainer::iterator iter = m_edgeObservers.begin();
259 0 : iter != m_edgeObservers.end(); iter++)
260 : {
261 0 : (*iter)->edges_to_be_merged(this, target, elem1, elem2);
262 : }
263 : }
264 :
265 : inline void Grid::
266 : objects_will_be_merged(Face* target, Face* elem1,
267 : Face* elem2)
268 : {
269 0 : for(Grid::ObserverContainer::iterator iter = m_faceObservers.begin();
270 0 : iter != m_faceObservers.end(); iter++)
271 : {
272 0 : (*iter)->faces_to_be_merged(this, target, elem1, elem2);
273 : }
274 : }
275 :
276 : inline void Grid::
277 : objects_will_be_merged(Volume* target, Volume* elem1,
278 : Volume* elem2)
279 : {
280 : for(Grid::ObserverContainer::iterator iter = m_volumeObservers.begin();
281 : iter != m_volumeObservers.end(); iter++)
282 : {
283 : (*iter)->volumes_to_be_merged(this, target, elem1, elem2);
284 : }
285 : }
286 :
287 : template <class TGeomObj>
288 : size_t Grid::attachment_container_size() const
289 : {
290 : return element_storage<TGeomObj>().m_attachmentPipe.num_data_entries();
291 : }
292 :
293 : ////////////////////////////////////////////////////////////////////////
294 : // attachment handling
295 : template <class TGeomObjClass>
296 : void Grid::attach_to(IAttachment& attachment, bool passOnValues)
297 : {
298 : STATIC_ASSERT(geometry_traits<TGeomObjClass>::BASE_OBJECT_ID != -1,
299 : invalid_GeomObjClass);
300 :
301 : // setup the options for this attachment.
302 : int options = 0;
303 7 : if(passOnValues)
304 : options = 1;
305 :
306 7 : element_storage<TGeomObjClass>().m_attachmentPipe.attach(attachment, options);
307 : }
308 :
309 : inline void Grid::attach_to_all(IAttachment& attachment, bool passOnValues)
310 : {
311 : attach_to<Vertex>(attachment, passOnValues);
312 : attach_to<Edge>(attachment, passOnValues);
313 : attach_to<Face>(attachment, passOnValues);
314 : attach_to<Volume>(attachment, passOnValues);
315 : }
316 :
317 0 : inline void Grid::attach_to_all(IAttachment& attachment)
318 : {
319 0 : attach_to<Vertex>(attachment);
320 0 : attach_to<Edge>(attachment);
321 0 : attach_to<Face>(attachment);
322 0 : attach_to<Volume>(attachment);
323 0 : }
324 :
325 : template <class TGeomObjClass, class TAttachment>
326 0 : void Grid::attach_to_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue)
327 : {
328 0 : attach_to_dv<TGeomObjClass, TAttachment>(attachment, defaultValue, attachment.default_pass_on_behaviour());
329 0 : }
330 :
331 : template <class TAttachment>
332 0 : inline void Grid::
333 : attach_to_all_dv(TAttachment& attachment,
334 : const typename TAttachment::ValueType& defaultValue)
335 : {
336 0 : attach_to_dv<Vertex>(attachment, defaultValue);
337 0 : attach_to_dv<Edge>(attachment, defaultValue);
338 0 : attach_to_dv<Face>(attachment, defaultValue);
339 0 : attach_to_dv<Volume>(attachment, defaultValue);
340 0 : }
341 :
342 : template <class TGeomObjClass, class TAttachment>
343 : void Grid::attach_to_dv(TAttachment& attachment, const typename TAttachment::ValueType& defaultValue, bool passOnValues)
344 : {
345 : STATIC_ASSERT(geometry_traits<TGeomObjClass>::BASE_OBJECT_ID != -1,
346 : invalid_GeomObjClass);
347 :
348 : // setup the options for this attachment.
349 : int options = 0;
350 0 : if(passOnValues)
351 : options = 1;
352 :
353 0 : element_storage<TGeomObjClass>().m_attachmentPipe.attach(attachment, defaultValue, options);
354 : }
355 :
356 : template <class TAttachment>
357 : inline void Grid::
358 : attach_to_all_dv(TAttachment& attachment,
359 : const typename TAttachment::ValueType& defaultValue,
360 : bool passOnValues)
361 : {
362 : attach_to_dv<Vertex>(attachment, defaultValue, passOnValues);
363 : attach_to_dv<Edge>(attachment, defaultValue, passOnValues);
364 : attach_to_dv<Face>(attachment, defaultValue, passOnValues);
365 : attach_to_dv<Volume>(attachment, defaultValue, passOnValues);
366 : }
367 :
368 : template <class TGeomObjClass>
369 : void Grid::detach_from(IAttachment& attachment)
370 : {
371 : STATIC_ASSERT(geometry_traits<TGeomObjClass>::BASE_OBJECT_ID != -1,
372 : invalid_GeomObjClass);
373 :
374 3 : element_storage<TGeomObjClass>().m_attachmentPipe.detach(attachment);
375 0 : }
376 :
377 0 : inline void Grid::detach_from_all(IAttachment& attachment)
378 : {
379 : detach_from<Vertex>(attachment);
380 : detach_from<Edge>(attachment);
381 : detach_from<Face>(attachment);
382 : detach_from<Volume>(attachment);
383 0 : }
384 :
385 : /*
386 : template <class TGeomObjClass>
387 : util::IAttachmentDataContainer* Grid::get_data_container(util::IAttachment& attachment)
388 : {
389 : assert(geometry_traits<TGeomObjClass>::base_object_type() != -1
390 : && "ERROR in Grid::get_data_container(...). Invalid base_object_type of GeomObjClass!");
391 :
392 : return m_elementStorage[geometry_traits<TGeomObjClass>::base_object_type()].
393 : m_attachmentPipe.get_data_container(attachment);
394 : }
395 : */
396 :
397 : template <class TGeomObj, class TAttachment>
398 : typename TAttachment::ContainerType*
399 : Grid::get_attachment_data_container(TAttachment& attachment)
400 : {
401 : STATIC_ASSERT(geometry_traits<TGeomObj>::BASE_OBJECT_ID != -1,
402 : invalid_GeomObj);
403 :
404 0 : return element_storage<TGeomObj>().m_attachmentPipe.get_data_container(attachment);
405 : }
406 :
407 : template <class TGeomObj>
408 : typename Grid::traits<TGeomObj>::AttachmentPipe&
409 : Grid::get_attachment_pipe()
410 : {
411 : STATIC_ASSERT(geometry_traits<TGeomObj>::BASE_OBJECT_ID != -1,
412 : invalid_GeomObj);
413 :
414 7 : return element_storage<TGeomObj>().m_attachmentPipe;
415 : }
416 :
417 : template <class TGeomObj>
418 : uint
419 : Grid::get_attachment_data_index(TGeomObj* pObj) const
420 : {
421 : typedef typename geometry_traits<TGeomObj>::grid_base_object BaseObj;
422 : return attachment_traits<BaseObj*, ElementStorage<BaseObj> >::
423 : get_data_index(&element_storage<TGeomObj>(), pObj);
424 : }
425 :
426 : inline void
427 0 : Grid::autoenable_option(uint option, const char* caller, const char* optionName)
428 : {
429 0 : if(!option_is_enabled(option))
430 : {
431 0 : LOG("WARNING in " << caller << ": auto-enabling " << optionName << "." << std::endl);
432 0 : enable_options(option);
433 : }
434 0 : }
435 :
436 : ////////////////////////////////////////////////////////////////////////
437 : // marks
438 : template <class TIterator>
439 : void Grid::mark(TIterator begin, TIterator end)
440 : {
441 0 : for(TIterator iter = begin; iter != end; ++iter)
442 0 : mark(*iter);
443 : }
444 :
445 : template <class TIterator>
446 : void Grid::unmark(TIterator begin, TIterator end)
447 : {
448 : for(TIterator iter = begin; iter != end; ++iter)
449 : unmark(*iter);
450 : }
451 :
452 :
453 : ////////////////////////////////////////////////////////////////////////
454 : template <class TContainer>
455 0 : void Grid::get_associated(TContainer& container, GridObject* o)
456 : {
457 0 : switch(o->base_object_id()){
458 0 : case VERTEX: return get_associated(container, static_cast<Vertex*>(o));
459 0 : case EDGE: return get_associated(container, static_cast<Edge*>(o));
460 0 : case FACE: return get_associated(container, static_cast<Face*>(o));
461 0 : case VOLUME: return get_associated(container, static_cast<Volume*>(o));
462 : }
463 : }
464 :
465 : template <class TElem>
466 : void Grid::associated_elements(traits<Vertex>::secure_container& elemsOut, TElem* e)
467 : {
468 0 : get_associated(elemsOut, e);
469 0 : }
470 :
471 : template <class TElem>
472 : void Grid::associated_elements(traits<Edge>::secure_container& elemsOut, TElem* e)
473 : {
474 0 : get_associated(elemsOut, e);
475 0 : }
476 :
477 : template <class TElem>
478 : void Grid::associated_elements(traits<Face>::secure_container& elemsOut, TElem* e)
479 : {
480 0 : get_associated(elemsOut, e);
481 0 : }
482 :
483 : template <class TElem>
484 : void Grid::associated_elements(traits<Volume>::secure_container& elemsOut, TElem* e)
485 : {
486 0 : get_associated(elemsOut, e);
487 0 : }
488 :
489 : template <class TElem>
490 0 : void Grid::get_associated(typename traits<typename TElem::grid_base_object>
491 : ::secure_container& elems, TElem* e)
492 : {
493 : // we have to retrieve a valid pointer on the element pointer. The only way
494 : // to receive it, is to return the pointer to the entry in which e is stored in
495 : // the element storage.
496 0 : elems.set_external_array(
497 : element_storage<typename TElem::grid_base_object>().m_sectionContainer.
498 : get_container().get_pointer_to_element(e),
499 : 1);
500 0 : }
501 :
502 : template <class TElem>
503 : void Grid::associated_elements_sorted(traits<Vertex>::secure_container& elemsOut, TElem* e)
504 : {
505 0 : get_associated_sorted(elemsOut, e);
506 0 : }
507 :
508 : template <class TElem>
509 : void Grid::associated_elements_sorted(traits<Edge>::secure_container& elemsOut, TElem* e)
510 : {
511 0 : get_associated_sorted(elemsOut, e);
512 0 : }
513 :
514 : template <class TElem>
515 : void Grid::associated_elements_sorted(traits<Face>::secure_container& elemsOut, TElem* e)
516 : {
517 0 : get_associated_sorted(elemsOut, e);
518 0 : }
519 :
520 : template <class TElem>
521 : void Grid::associated_elements_sorted(traits<Volume>::secure_container& elemsOut, TElem* e)
522 : {
523 0 : get_associated_sorted(elemsOut, e);
524 0 : }
525 :
526 :
527 : template <class TElem>
528 0 : void Grid::get_associated_sorted(typename traits<typename TElem::grid_base_object>
529 : ::secure_container& elems, TElem* e)
530 : {
531 : // we have to retrieve a valid pointer on the element pointer. The only way
532 : // to receive it, is to return the pointer to the entry in which e is stored in
533 : // the element storage.
534 0 : elems.set_external_array(
535 : element_storage<typename TElem::grid_base_object>().m_sectionContainer.
536 : get_container().get_pointer_to_element(e),
537 : 1);
538 0 : }
539 :
540 :
541 : ////////////////////////////////////////////////////////////////////////
542 : // neighbourhood access
543 : template <class TGeomObj>
544 3 : Edge* Grid::find_edge_in_associated_edges(TGeomObj* obj, const EdgeVertices& ev)
545 : {
546 : GRID_PROFILE_FUNC();
547 :
548 3 : AssociatedEdgeIterator iterEnd = associated_edges_end(obj);
549 3 : for(AssociatedEdgeIterator iter = associated_edges_begin(obj);
550 5 : iter != iterEnd; ++iter)
551 : {
552 2 : Edge* e = *iter;
553 2 : if(CompareVertices(e, &ev))
554 : return e;
555 : }
556 : return NULL;
557 : }
558 :
559 :
560 : template <class TGeomObj>
561 0 : Face* Grid::find_face_in_associated_faces(TGeomObj* obj, const FaceVertices& fv)
562 : {
563 : GRID_PROFILE_FUNC();
564 :
565 0 : unsigned long key = hash_key(&fv);
566 0 : AssociatedFaceIterator iterEnd = associated_faces_end(obj);
567 0 : for(AssociatedFaceIterator iter = associated_faces_begin(obj);
568 0 : iter != iterEnd; ++iter)
569 : {
570 0 : Face* f = *iter;
571 0 : if(key == hash_key(f))
572 : {
573 0 : if(CompareVertices(f, &fv))
574 : return f;
575 : }
576 : }
577 :
578 : return NULL;
579 : }
580 :
581 : template <class TGeomObj>
582 0 : Volume* Grid::find_volume_in_associated_volumes(TGeomObj* obj,
583 : const VolumeVertices& vv)
584 : {
585 : GRID_PROFILE_FUNC();
586 :
587 0 : unsigned long key = hash_key(&vv);
588 0 : AssociatedVolumeIterator iterEnd = associated_volumes_end(obj);
589 0 : for(AssociatedVolumeIterator iter = associated_volumes_begin(obj);
590 0 : iter != iterEnd; ++iter)
591 : {
592 0 : Volume* v = *iter;
593 0 : if(key == hash_key(v))
594 : {
595 0 : if(CompareVertices(v, &vv))
596 : return v;
597 : }
598 : }
599 :
600 : return NULL;
601 : }
602 :
603 :
604 : ////////////////////////////////////////////////////////////////////////
605 : ////////////////////////////////////////////////////////////////////////
606 : // implementation of Grids AttachmentAccessors
607 :
608 : ////////////////////////////////////////////////////////////////////////
609 : // AttachmentAccessor
610 : template <class TElem, class TAttachment>
611 : Grid::AttachmentAccessor<TElem, TAttachment>::
612 : AttachmentAccessor() :
613 : ug::AttachmentAccessor<TElem*, TAttachment, ElementStorage<TElem> >()
614 : {
615 : }
616 :
617 : template <class TElem, class TAttachment>
618 : Grid::AttachmentAccessor<TElem, TAttachment>::
619 : AttachmentAccessor(const AttachmentAccessor& aa) :
620 : ug::AttachmentAccessor<TElem*, TAttachment, ElementStorage<TElem> >(aa)
621 : {
622 : }
623 :
624 : template <class TElem, class TAttachment>
625 : Grid::AttachmentAccessor<TElem, TAttachment>::
626 : AttachmentAccessor(Grid& grid, TAttachment& a) :
627 : ug::AttachmentAccessor<typename TElem::grid_base_object*, TAttachment,
628 : typename traits<TElem>::ElementStorage>
629 : (grid.get_attachment_pipe<TElem>(), a)
630 : {
631 : }
632 :
633 : template <class TElem, class TAttachment>
634 0 : Grid::AttachmentAccessor<TElem, TAttachment>::
635 : AttachmentAccessor(Grid& grid, TAttachment& a, bool autoAttach) :
636 : ug::AttachmentAccessor<typename TElem::grid_base_object*, TAttachment,
637 : typename traits<TElem>::ElementStorage>()
638 : {
639 0 : if(autoAttach){
640 0 : if(!grid.has_attachment<TElem>(a))
641 0 : grid.attach_to<TElem>(a);
642 : }
643 :
644 : access(grid, a);
645 0 : }
646 :
647 : ////////////////////////////////////////////////////////////////////////
648 : // VertexAttachmentAccessor
649 : template <class TAttachment>
650 : Grid::VertexAttachmentAccessor<TAttachment>::
651 : VertexAttachmentAccessor() :
652 : Grid::AttachmentAccessor<Vertex, TAttachment>()
653 : {
654 : }
655 :
656 : template <class TAttachment>
657 : Grid::VertexAttachmentAccessor<TAttachment>::
658 : VertexAttachmentAccessor(const VertexAttachmentAccessor& aa) :
659 : Grid::AttachmentAccessor<Vertex, TAttachment>(aa)
660 : {
661 : }
662 :
663 : template <class TAttachment>
664 : Grid::VertexAttachmentAccessor<TAttachment>::
665 : VertexAttachmentAccessor(Grid& grid, TAttachment& a) :
666 : Grid::AttachmentAccessor<Vertex, TAttachment>(grid, a)
667 : {
668 : }
669 :
670 : template <class TAttachment>
671 : Grid::VertexAttachmentAccessor<TAttachment>::
672 : VertexAttachmentAccessor(Grid& grid, TAttachment& a, bool autoAttach) :
673 : Grid::AttachmentAccessor<Vertex, TAttachment>(grid, a, autoAttach)
674 : {
675 : }
676 :
677 :
678 : ////////////////////////////////////////////////////////////////////////
679 : // EdgeAttachmentAccessor
680 : template <class TAttachment>
681 : Grid::EdgeAttachmentAccessor<TAttachment>::
682 : EdgeAttachmentAccessor() :
683 : Grid::AttachmentAccessor<Edge, TAttachment>()
684 : {
685 : }
686 :
687 : template <class TAttachment>
688 : Grid::EdgeAttachmentAccessor<TAttachment>::
689 : EdgeAttachmentAccessor(const EdgeAttachmentAccessor& aa) :
690 : Grid::AttachmentAccessor<Edge, TAttachment>(aa)
691 : {
692 : }
693 :
694 : template <class TAttachment>
695 : Grid::EdgeAttachmentAccessor<TAttachment>::
696 : EdgeAttachmentAccessor(Grid& grid, TAttachment& a) :
697 : Grid::AttachmentAccessor<Edge, TAttachment>(grid, a)
698 : {
699 : }
700 :
701 : template <class TAttachment>
702 : Grid::EdgeAttachmentAccessor<TAttachment>::
703 : EdgeAttachmentAccessor(Grid& grid, TAttachment& a, bool autoAttach) :
704 : Grid::AttachmentAccessor<Edge, TAttachment>(grid, a, autoAttach)
705 : {
706 : }
707 :
708 :
709 : ////////////////////////////////////////////////////////////////////////
710 : // FaceAttachmentAccessor
711 : template <class TAttachment>
712 : Grid::FaceAttachmentAccessor<TAttachment>::
713 : FaceAttachmentAccessor() :
714 : Grid::AttachmentAccessor<Face, TAttachment>()
715 : {
716 : }
717 :
718 : template <class TAttachment>
719 : Grid::FaceAttachmentAccessor<TAttachment>::
720 : FaceAttachmentAccessor(const FaceAttachmentAccessor& aa) :
721 : Grid::AttachmentAccessor<Face, TAttachment>(aa)
722 : {
723 : }
724 :
725 : template <class TAttachment>
726 : Grid::FaceAttachmentAccessor<TAttachment>::
727 : FaceAttachmentAccessor(Grid& grid, TAttachment& a) :
728 : Grid::AttachmentAccessor<Face, TAttachment>(grid, a)
729 : {
730 : }
731 :
732 : template <class TAttachment>
733 : Grid::FaceAttachmentAccessor<TAttachment>::
734 : FaceAttachmentAccessor(Grid& grid, TAttachment& a, bool autoAttach) :
735 : Grid::AttachmentAccessor<Face, TAttachment>(grid, a, autoAttach)
736 : {
737 : }
738 :
739 :
740 : ////////////////////////////////////////////////////////////////////////
741 : // FaceAttachmentAccessor
742 : template <class TAttachment>
743 : Grid::VolumeAttachmentAccessor<TAttachment>::
744 : VolumeAttachmentAccessor() :
745 : Grid::AttachmentAccessor<Volume, TAttachment>()
746 : {
747 : }
748 :
749 : template <class TAttachment>
750 : Grid::VolumeAttachmentAccessor<TAttachment>::
751 : VolumeAttachmentAccessor(const VolumeAttachmentAccessor& aa) :
752 : Grid::AttachmentAccessor<Volume, TAttachment>(aa)
753 : {
754 : }
755 :
756 : template <class TAttachment>
757 : Grid::VolumeAttachmentAccessor<TAttachment>::
758 : VolumeAttachmentAccessor(Grid& grid, TAttachment& a) :
759 : Grid::AttachmentAccessor<Volume, TAttachment>(grid, a)
760 : {
761 : }
762 :
763 : template <class TAttachment>
764 : Grid::VolumeAttachmentAccessor<TAttachment>::
765 : VolumeAttachmentAccessor(Grid& grid, TAttachment& a, bool autoAttach) :
766 : Grid::AttachmentAccessor<Volume, TAttachment>(grid, a, autoAttach)
767 : {
768 : }
769 :
770 :
771 : ////////////////////////////////////////////////////////////////////////
772 : // marks
773 : inline void Grid::mark(GridObject* obj)
774 : {
775 : const int typeID = obj->base_object_id();
776 : switch(typeID){
777 : case VERTEX: mark(static_cast<Vertex*>(obj)); break;
778 : case EDGE: mark(static_cast<Edge*>(obj)); break;
779 : case FACE: mark(static_cast<Face*>(obj)); break;
780 : case VOLUME: mark(static_cast<Volume*>(obj)); break;
781 : }
782 : }
783 :
784 : inline void Grid::mark(Vertex* obj)
785 : {
786 : assert(m_bMarking && "ERROR: Grid::mark may only be called between calls to Grid::begin_marking and Grid::end_marking.");
787 0 : m_aaMarkVRT[obj] = m_currentMark;
788 0 : }
789 :
790 : inline void Grid::mark(Edge* obj)
791 : {
792 : assert(m_bMarking && "ERROR: Grid::mark may only be called between calls to Grid::begin_marking and Grid::end_marking.");
793 0 : m_aaMarkEDGE[obj] = m_currentMark;
794 0 : }
795 :
796 : inline void Grid::mark(Face* obj)
797 : {
798 : assert(m_bMarking && "ERROR: Grid::mark may only be called between calls to Grid::begin_marking and Grid::end_marking.");
799 0 : m_aaMarkFACE[obj] = m_currentMark;
800 0 : }
801 :
802 : inline void Grid::mark(Volume* obj)
803 : {
804 : assert(m_bMarking && "ERROR: Grid::mark may only be called between calls to Grid::begin_marking and Grid::end_marking.");
805 0 : m_aaMarkVOL[obj] = m_currentMark;
806 0 : }
807 :
808 : inline void Grid::unmark(GridObject* obj)
809 : {
810 : const int typeID = obj->base_object_id();
811 : switch(typeID){
812 : case VERTEX: unmark(static_cast<Vertex*>(obj)); break;
813 : case EDGE: unmark(static_cast<Edge*>(obj)); break;
814 : case FACE: unmark(static_cast<Face*>(obj)); break;
815 : case VOLUME: unmark(static_cast<Volume*>(obj)); break;
816 : }
817 : }
818 :
819 : inline void Grid::unmark(Vertex* obj)
820 : {
821 : assert(m_bMarking && "ERROR: Grid::unmark may only be called between calls to Grid::begin_marking and Grid::end_marking.");
822 : m_aaMarkVRT[obj] = 0;
823 : }
824 :
825 : inline void Grid::unmark(Edge* obj)
826 : {
827 : assert(m_bMarking && "ERROR: Grid::unmark may only be called between calls to Grid::begin_marking and Grid::end_marking.");
828 0 : m_aaMarkEDGE[obj] = 0;
829 : }
830 :
831 : inline void Grid::unmark(Face* obj)
832 : {
833 : assert(m_bMarking && "ERROR: Grid::unmark may only be called between calls to Grid::begin_marking and Grid::end_marking.");
834 0 : m_aaMarkFACE[obj] = 0;
835 : }
836 :
837 : inline void Grid::unmark(Volume* obj)
838 : {
839 : assert(m_bMarking && "ERROR: Grid::unmark may only be called between calls to Grid::begin_marking and Grid::end_marking.");
840 : m_aaMarkVOL[obj] = 0;
841 : }
842 :
843 0 : inline bool Grid::is_marked(GridObject* obj) const
844 : {
845 0 : const int typeID = obj->base_object_id();
846 0 : switch(typeID){
847 : case VERTEX: return is_marked(static_cast<Vertex*>(obj));
848 : case EDGE: return is_marked(static_cast<Edge*>(obj));
849 : case FACE: return is_marked(static_cast<Face*>(obj));
850 : case VOLUME: return is_marked(static_cast<Volume*>(obj));
851 : default: return false;
852 : }
853 : }
854 :
855 : inline bool Grid::is_marked(Vertex* obj) const
856 : {
857 0 : if(m_currentMark == 0)
858 : return false;
859 0 : return m_aaMarkVRT[obj] == m_currentMark;
860 : }
861 :
862 : inline bool Grid::is_marked(Edge* obj) const
863 : {
864 0 : if(m_currentMark == 0)
865 : return false;
866 0 : return m_aaMarkEDGE[obj] == m_currentMark;
867 : }
868 :
869 : inline bool Grid::is_marked(Face* obj) const
870 : {
871 0 : if(m_currentMark == 0)
872 : return false;
873 0 : return m_aaMarkFACE[obj] == m_currentMark;
874 : }
875 :
876 : inline bool Grid::is_marked(Volume* obj) const
877 : {
878 0 : if(m_currentMark == 0)
879 : return false;
880 0 : return m_aaMarkVOL[obj] == m_currentMark;
881 : }
882 :
883 : }// end of namespace libGrid
884 : #endif
|