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 "grid_util.h"
34 : #include "grid.h"
35 : #include <iostream>
36 :
37 : using namespace std;
38 :
39 : namespace ug
40 : {
41 :
42 : ////////////////////////////////////////////////////////////////////////
43 : // CompareVertices
44 0 : bool CompareVertices(const FaceVertices* fv1,
45 : const FaceVertices* fv2)
46 : {
47 0 : uint numVrts = fv1->num_vertices();
48 :
49 0 : if(numVrts != fv2->num_vertices())
50 : return false;
51 :
52 0 : FaceVertices::ConstVertexArray vrts1 = fv1->vertices();
53 0 : FaceVertices::ConstVertexArray vrts2 = fv2->vertices();
54 :
55 0 : for(uint i = 0; i < numVrts; ++i)
56 : {
57 : uint j;
58 0 : for(j = 0; j < numVrts; ++j)
59 : {
60 0 : if(vrts1[i] == vrts2[j])
61 : break;
62 : }
63 :
64 : // check whether we found a matching vertex
65 0 : if(j == numVrts)
66 : return false;
67 : }
68 :
69 : return true;
70 : }
71 :
72 0 : bool CompareVertices(const VolumeVertices* vv1,
73 : const VolumeVertices* vv2)
74 : {
75 0 : uint numVrts = vv1->num_vertices();
76 :
77 0 : if(numVrts != vv2->num_vertices())
78 : return false;
79 :
80 0 : VolumeVertices::ConstVertexArray vrts1 = vv1->vertices();
81 0 : VolumeVertices::ConstVertexArray vrts2 = vv2->vertices();
82 :
83 0 : for(uint i = 0; i < numVrts; ++i)
84 : {
85 : uint j;
86 0 : for(j = 0; j < numVrts; ++j)
87 : {
88 0 : if(vrts1[i] == vrts2[j])
89 : break;
90 : }
91 :
92 : // check whether we found a matching vertex
93 0 : if(j == numVrts)
94 : return false;
95 : }
96 :
97 : return true;
98 : }
99 :
100 :
101 0 : bool VertexGroupsMatch(const IVertexGroup* elem, const IVertexGroup& desc)
102 : {
103 0 : size_t n = elem->num_vertices();
104 0 : if (desc.num_vertices() != n) return false;
105 :
106 0 : size_t numVrts = elem->num_vertices();
107 :
108 0 : if (numVrts != desc.num_vertices())
109 : return false;
110 :
111 0 : IVertexGroup::ConstVertexArray vrts1 = elem->vertices();
112 0 : IVertexGroup::ConstVertexArray vrts2 = desc.vertices();
113 :
114 0 : for (size_t i = 0; i < numVrts; ++i)
115 : {
116 : size_t j;
117 0 : for (j = 0; j < numVrts; ++j)
118 : {
119 0 : if (vrts1[i] == vrts2[j])
120 : break;
121 : }
122 :
123 : // check whether we found a matching vertex
124 0 : if (j == numVrts)
125 : return false;
126 : }
127 :
128 : return true;
129 : }
130 :
131 0 : bool VertexGroupsMatch(const Vertex* elem, const IVertexGroup& desc)
132 : {
133 0 : if (desc.num_vertices() != 1) return false;
134 0 : return desc.vertex(0) == elem;
135 : }
136 :
137 :
138 : ////////////////////////////////////////////////////////////////////////
139 : // CollectVertices
140 : /// Collects all vertices.
141 0 : void CollectVertices(std::vector<Vertex*>& vVertexOut, Grid& grid, Vertex* v, bool clearContainer)
142 : {
143 : // clear container if wanted
144 0 : if(clearContainer)
145 : vVertexOut.clear();
146 :
147 : // add vertex pointers to container
148 0 : vVertexOut.push_back(v);
149 0 : }
150 :
151 : /// Collects all vertices.
152 0 : void CollectVertices(std::vector<Vertex*>& vVertexOut, Grid& grid, Edge* e, bool clearContainer)
153 : {
154 : // clear container if wanted
155 0 : if(clearContainer)
156 : vVertexOut.clear();
157 :
158 : // resize container
159 0 : const size_t numVertex = e->num_vertices();
160 :
161 : // add vertex pointers to container
162 0 : for(size_t i = 0; i < numVertex; ++i)
163 0 : vVertexOut.push_back(e->vertex(i));
164 0 : }
165 :
166 : /// Collects all vertices.
167 0 : void CollectVertices(std::vector<Vertex*>& vVertexOut, Grid& grid, Face* f, bool clearContainer)
168 : {
169 : // clear container if wanted
170 0 : if(clearContainer)
171 : vVertexOut.clear();
172 :
173 : // resize container
174 0 : const size_t numVertex = f->num_vertices();
175 0 : FaceVertices::ConstVertexArray vrts= f->vertices();
176 :
177 : // add vertex pointers to container
178 0 : for(size_t i = 0; i < numVertex; ++i)
179 0 : vVertexOut.push_back(vrts[i]);
180 0 : }
181 :
182 : /// Collects all vertices.
183 0 : void CollectVertices(std::vector<Vertex*>& vVertexOut, Grid& grid, Volume* v, bool clearContainer)
184 : {
185 : // clear container if wanted
186 0 : if(clearContainer)
187 : vVertexOut.clear();
188 :
189 : // resize container
190 0 : const size_t numVertex = v->num_vertices();
191 0 : VolumeVertices::ConstVertexArray vrts= v->vertices();
192 :
193 : // add vertex pointers to container
194 0 : for(size_t i = 0; i < numVertex; ++i)
195 0 : vVertexOut.push_back(vrts[i]);
196 0 : }
197 :
198 :
199 :
200 : ///////////////////////////////////////////////////////////////////////////////
201 : // CollectEdgesSorted
202 : ///////////////////////////////////////////////////////////////////////////////
203 :
204 : /// Collects all edges of a vertex, thus, none.
205 0 : void CollectEdgesSorted(vector<Edge*>& vEdgesOut, Grid& grid, Vertex* v, bool clearContainer)
206 : {
207 : vEdgesOut.clear();
208 0 : }
209 :
210 : /// Collects all edges. (Returns the edge itself)
211 0 : void CollectEdgesSorted(vector<Edge*>& vEdgesOut, Grid& grid, Edge* e, bool clearContainer)
212 : {
213 0 : if(clearContainer)
214 : vEdgesOut.clear();
215 :
216 0 : vEdgesOut.push_back(e);
217 0 : }
218 :
219 : /// Collects all edges which exist in the given grid and which are part of the given face in the order defined by the reference elements.
220 0 : void CollectEdgesSorted(vector<Edge*>& vEdgesOut, Grid& grid, Face* f, bool clearContainer)
221 : {
222 0 : if(clearContainer)
223 : vEdgesOut.clear();
224 :
225 : // to improve performance, we first check the grid options.
226 0 : if(grid.option_is_enabled(FACEOPT_AUTOGENERATE_EDGES
227 : | FACEOPT_STORE_ASSOCIATED_EDGES))
228 : {
229 : // the edges can be accessed in a sorted way through iterators
230 0 : Grid::AssociatedEdgeIterator end = grid.associated_edges_end(f);
231 0 : for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(f);
232 0 : iter != end; ++iter)
233 : {
234 0 : vEdgesOut.push_back(*iter);
235 : }
236 : }
237 : else{
238 : // if no edges are present, we can leave immediately
239 0 : if(grid.num<Edge>() == 0)
240 : return;
241 : // second-best: use GetEdge in order to find the queried edges
242 : uint numEdges = f->num_edges();
243 0 : for(uint i = 0; i < numEdges; ++i)
244 : {
245 0 : Edge* e = grid.get_edge(f, i);
246 0 : if(e != NULL)
247 0 : vEdgesOut.push_back(e);
248 : }
249 : }
250 : }
251 :
252 : /// Collects all edges that exist in the given grid are part of the given volume in the order defined by the reference elements.
253 0 : void CollectEdgesSorted(vector<Edge*>& vEdgesOut, Grid& grid, Volume* v, bool clearContainer)
254 : {
255 0 : if(clearContainer)
256 : vEdgesOut.clear();
257 :
258 : // to improve performance, we first check the grid options.
259 0 : if(grid.option_is_enabled(VOLOPT_AUTOGENERATE_EDGES
260 : | VOLOPT_STORE_ASSOCIATED_EDGES)
261 0 : || grid.option_is_enabled(VOLOPT_AUTOGENERATE_FACES
262 : | FACEOPT_AUTOGENERATE_EDGES
263 : | VOLOPT_STORE_ASSOCIATED_EDGES))
264 : {
265 : // the edges can be accessed in a sorted way through iterators
266 0 : Grid::AssociatedEdgeIterator end = grid.associated_edges_end(v);
267 0 : for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(v);
268 0 : iter != end; ++iter)
269 : {
270 0 : vEdgesOut.push_back(*iter);
271 : }
272 : }
273 : else{
274 : // if no edges are present, we can leave immediately
275 0 : if(grid.num<Edge>() == 0)
276 : return;
277 :
278 : // second best: use GetEdge in order to find the queried edges.
279 0 : uint numEdges = v->num_edges();
280 0 : for(uint i = 0; i < numEdges; ++i)
281 : {
282 0 : Edge* e = grid.get_edge(v, i);
283 0 : if(e != NULL)
284 0 : vEdgesOut.push_back(e);
285 : }
286 : }
287 :
288 : }
289 :
290 : ///////////////////////////////////////////////////////////////////////////////
291 : // CollectEdges
292 : ///////////////////////////////////////////////////////////////////////////////
293 :
294 : /// Collects all edges which exist in the given grid and which are part of the given vertex.
295 0 : void CollectEdges(std::vector<Edge*>& vEdgesOut, Grid& grid, Vertex* vrt, bool clearContainer)
296 : {
297 0 : if(clearContainer)
298 : vEdgesOut.clear();
299 :
300 : // if no edges are present, we can leave immediately
301 0 : if(grid.num<Edge>() == 0)
302 0 : return;
303 :
304 0 : Grid::AssociatedEdgeIterator iterEnd = grid.associated_edges_end(vrt);
305 0 : for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(vrt);
306 0 : iter != iterEnd; ++iter)
307 : {
308 0 : vEdgesOut.push_back(*iter);
309 : }
310 : }
311 :
312 : /// Collects all edges. (Returns the edge itself)
313 0 : void CollectEdges(vector<Edge*>& vEdgesOut, Grid& grid, Edge* e, bool clearContainer)
314 : {
315 0 : if(clearContainer)
316 : vEdgesOut.clear();
317 :
318 : // if no edges are present, we can leave immediately
319 0 : if(grid.num<Edge>() == 0)
320 : return;
321 :
322 0 : vEdgesOut.push_back(e);
323 : }
324 :
325 : /// Collects all edges which exist in the given grid and which are part of the given face.
326 0 : void CollectEdges(vector<Edge*>& vEdgesOut, Grid& grid, Face* f, bool clearContainer)
327 : {
328 0 : if(clearContainer)
329 : vEdgesOut.clear();
330 :
331 : // if no edges are present, we can leave immediately
332 0 : if(grid.num<Edge>() == 0)
333 : return;
334 :
335 : // best-option: FACEOPT_STORE_ASSOCIATED_EDGES
336 0 : if(grid.option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
337 : {
338 : // ok. simply push them into the container.
339 0 : Grid::AssociatedEdgeIterator iterEnd = grid.associated_edges_end(f);
340 0 : for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(f);
341 0 : iter != iterEnd; ++iter)
342 : {
343 0 : vEdgesOut.push_back(*iter);
344 : }
345 :
346 : // everything is done. exit.
347 : return;
348 : }
349 :
350 : // second-best: use GetEdge in order to find the queried edges
351 : uint numEdges = f->num_edges();
352 0 : for(uint i = 0; i < numEdges; ++i)
353 : {
354 0 : Edge* e = grid.get_edge(f, i);
355 0 : if(e != NULL)
356 0 : vEdgesOut.push_back(e);
357 : }
358 : }
359 :
360 : /// Collects all edges that exist in the given grid are part of the given volume.
361 0 : void CollectEdges(vector<Edge*>& vEdgesOut, Grid& grid, Volume* v, bool clearContainer)
362 : {
363 0 : if(clearContainer)
364 : vEdgesOut.clear();
365 :
366 : // if no edges are present, we can leave immediately
367 0 : if(grid.num<Edge>() == 0)
368 : return;
369 :
370 : // best option: VOLOPT_STORE_ASSOCIATED_EDGES
371 0 : if(grid.option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
372 : {
373 : // iterate through the associated edges and push them into the container.
374 0 : Grid::AssociatedEdgeIterator iterEnd = grid.associated_edges_end(v);
375 0 : for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(v);
376 0 : iter != iterEnd; ++iter)
377 : {
378 0 : vEdgesOut.push_back(*iter);
379 : }
380 :
381 : // everything is done. exit.
382 : return;
383 : }
384 :
385 : // second best: use GetEdge in order to find the queried edges.
386 0 : uint numEdges = v->num_edges();
387 0 : for(uint i = 0; i < numEdges; ++i)
388 : {
389 0 : Edge* e = grid.get_edge(v, i);
390 0 : if(e != NULL)
391 0 : vEdgesOut.push_back(e);
392 : }
393 :
394 : }
395 :
396 : ////////////////////////////////////////////////////////////////////////////////
397 : // CollectFacesSorted
398 : ////////////////////////////////////////////////////////////////////////////////
399 :
400 : /// Collects all Faces of a Vertex, thus, none.
401 0 : void CollectFacesSorted(vector<Face*>& vFacesOut, Grid& grid, Vertex* v, bool clearContainer)
402 : {
403 : vFacesOut.clear();
404 0 : }
405 :
406 : /// Collects all faces and returns them in the order prescribed by the reference element.
407 0 : void CollectFacesSorted(vector<Face*>& vFacesOut, Grid& grid, Edge* e, bool clearContainer)
408 : {
409 : vFacesOut.clear();
410 0 : }
411 :
412 : /// Collects all faces and returns them in the order prescribed by the reference element.
413 0 : void CollectFacesSorted(vector<Face*>& vFacesOut, Grid& grid, Face* f, bool clearContainer)
414 : {
415 0 : if(clearContainer)
416 : vFacesOut.clear();
417 :
418 0 : if(f != NULL)
419 0 : vFacesOut.push_back(f);
420 0 : }
421 :
422 : /// Collects all faces and returns them in the order prescribed by the reference element.
423 0 : void CollectFacesSorted(vector<Face*>& vFacesOut, Grid& grid, Volume* v, bool clearContainer)
424 : {
425 0 : if(clearContainer)
426 : vFacesOut.clear();
427 :
428 : // to improve performance, we first check the grid options.
429 0 : if(grid.option_is_enabled(VOLOPT_AUTOGENERATE_FACES
430 : | VOLOPT_STORE_ASSOCIATED_FACES))
431 : {
432 : // the faces can be accessed in a sorted way through iterators
433 0 : Grid::AssociatedFaceIterator end = grid.associated_faces_end(v);
434 0 : for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(v);
435 0 : iter != end; ++iter)
436 : {
437 0 : vFacesOut.push_back(*iter);
438 : }
439 : }
440 : else{
441 : // if no faces are present, we can leave immediately
442 0 : if(grid.num<Face>() == 0)
443 : return;
444 :
445 0 : uint numFaces = v->num_faces();
446 0 : for(uint i = 0; i < numFaces; ++i)
447 : {
448 0 : Face* f = grid.get_face(v, i);
449 0 : if(f != NULL)
450 0 : vFacesOut.push_back(f);
451 : }
452 : }
453 : }
454 :
455 : ////////////////////////////////////////////////////////////////////////
456 : // CollectFaces
457 : /// Collects all faces that exist in the given grid which contain the given vertex.
458 0 : void CollectFaces(std::vector<Face*>& vFacesOut, Grid& grid, Vertex* vrt, bool clearContainer)
459 : {
460 0 : if(clearContainer)
461 : vFacesOut.clear();
462 :
463 : // if no faces are present, we can leave immediately
464 0 : if(grid.num<Face>() == 0)
465 0 : return;
466 :
467 0 : Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(vrt);
468 0 : for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(vrt);
469 0 : iter != iterEnd; ++iter)
470 : {
471 0 : vFacesOut.push_back(*iter);
472 : }
473 : }
474 :
475 : /// Collects all faces that exist in the given grid which contain the given edge.
476 0 : void CollectFaces(std::vector<Face*>& vFacesOut, Grid& grid, Edge* e, bool clearContainer)
477 : {
478 0 : if(clearContainer)
479 : vFacesOut.clear();
480 :
481 : // if no faces are present, we can leave immediately
482 0 : if(grid.num<Face>() == 0)
483 : return;
484 :
485 : // best option: EDGEOPT_STORE_ASSOCIATED_FACES
486 0 : if(grid.option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
487 : {
488 0 : Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(e);
489 0 : for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(e);
490 0 : iter != iterEnd; ++iter)
491 : {
492 0 : vFacesOut.push_back(*iter);
493 : }
494 : return;
495 : }
496 :
497 : // second best: iterate through all faces associated with the first end-point of e
498 : // and check for each if it contains e. If so push it into the container.
499 : {
500 0 : Vertex* v1 = e->vertex(0);
501 0 : Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(v1);
502 0 : for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(v1);
503 0 : iter != iterEnd; ++iter)
504 : {
505 0 : if(FaceContains(*iter, e))
506 0 : vFacesOut.push_back(*iter);
507 : }
508 : }
509 : }
510 :
511 : /// Collects all faces. (Returns the face itself)
512 0 : void CollectFaces(vector<Face*>& vFacesOut, Grid& grid, Face* e, bool clearContainer)
513 : {
514 0 : if(clearContainer)
515 : vFacesOut.clear();
516 :
517 : // if no faces are present, we can leave immediately
518 0 : if(grid.num<Face>() == 0)
519 : return;
520 :
521 0 : vFacesOut.push_back(e);
522 : }
523 :
524 : /// Collects all faces that exist in the given grid are part of the given volume.
525 0 : void CollectFaces(vector<Face*>& vFacesOut, Grid& grid, Volume* v, bool clearContainer)
526 : {
527 0 : if(clearContainer)
528 : vFacesOut.clear();
529 :
530 : // if no faces are present, we can leave immediately
531 0 : if(grid.num<Face>() == 0)
532 : return;
533 :
534 : // best option: VOLOPT_STORE_ASSOCIATED_FACES
535 0 : if(grid.option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
536 : {
537 : // iterate through the faces and add them to the container
538 0 : Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(v);
539 0 : for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(v);
540 0 : iter != iterEnd; ++iter)
541 : {
542 0 : vFacesOut.push_back(*iter);
543 : }
544 :
545 : return;
546 : }
547 :
548 : // second best: use FindFace in order to find the queried faces
549 0 : uint numFaces = v->num_faces();
550 0 : for(uint i = 0; i < numFaces; ++i)
551 : {
552 0 : Face* f = grid.get_face(v, i);
553 0 : if(f != NULL)
554 0 : vFacesOut.push_back(f);
555 : }
556 : }
557 :
558 : ////////////////////////////////////////////////////////////////////////
559 : // FaceContains
560 : /// returns true if the given face contains the two given vertices
561 0 : bool FaceContains(Face* f, EdgeVertices* ev)
562 : {
563 : uint numEdges = f->num_edges();
564 0 : EdgeDescriptor ed;
565 0 : for(uint i = 0; i < numEdges; ++i)
566 : {
567 0 : f->edge_desc(i, ed);
568 0 : if(CompareVertices(ev, &ed))
569 : return true;
570 : }
571 :
572 : return false;
573 : }
574 :
575 : ////////////////////////////////////////////////////////////////////////
576 : // FaceContains
577 : /// returns true if the given face contains the given vertex
578 0 : bool FaceContains(FaceVertices* f, Vertex* v)
579 : {
580 0 : uint numVrts = f->num_vertices();
581 0 : Face::ConstVertexArray vrts = f->vertices();
582 :
583 0 : for(uint i = 0; i < numVrts; ++i)
584 : {
585 0 : if(vrts[i] == v)
586 : return true;
587 : }
588 : return false;
589 : }
590 :
591 : ////////////////////////////////////////////////////////////////////////
592 0 : void CollectVolumes(std::vector<Volume*>& vVolumesOut, Grid& grid, Vertex* vrt, bool clearContainer)
593 : {
594 0 : if(clearContainer)
595 : vVolumesOut.clear();
596 :
597 : // if no volumes are present, we can leave immediately
598 0 : if(grid.num<Volume>() == 0)
599 0 : return;
600 :
601 0 : Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(vrt);
602 0 : for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(vrt);
603 0 : iter != iterEnd; ++iter)
604 : {
605 0 : vVolumesOut.push_back(*iter);
606 : }
607 : }
608 :
609 : ////////////////////////////////////////////////////////////////////////
610 : // CollectVolumes
611 : /// Collects all volumes that exist in the given grid which contain the given edge.
612 0 : void CollectVolumes(std::vector<Volume*>& vVolumesOut, Grid& grid, Edge* e, bool clearContainer)
613 : {
614 0 : if(clearContainer)
615 : vVolumesOut.clear();
616 :
617 : // if no volumes are present, we can leave immediately
618 0 : if(grid.num<Volume>() == 0)
619 0 : return;
620 :
621 : // best option: EDGEOPT_STORE_ASSOCIATED_VOLUMES
622 0 : if(grid.option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
623 : {
624 0 : Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(e);
625 0 : for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(e);
626 0 : iter != iterEnd; ++iter)
627 : {
628 0 : vVolumesOut.push_back(*iter);
629 : }
630 : return;
631 : }
632 :
633 : // second best: iterate through all volumes that are associated with the first vertex of e.
634 : // check for each if it contains e. if so then store it in the container.
635 0 : Vertex* v1 = e->vertex(0);
636 0 : Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(v1);
637 0 : for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(v1);
638 0 : iter != iterEnd; ++iter)
639 : {
640 0 : if(VolumeContains(*iter, e))
641 0 : vVolumesOut.push_back(*iter);
642 : }
643 : }
644 :
645 : /// Collects all volumes that exist in the given grid which contain the given face.
646 0 : void CollectVolumes(std::vector<Volume*>& vVolumesOut, Grid& grid, Face* f, bool clearContainer, bool ignoreAssociatedVolumes)
647 : {
648 0 : if(clearContainer)
649 : vVolumesOut.clear();
650 :
651 : // if no volumes are present, we can leave immediately
652 0 : if(grid.num<Volume>() == 0)
653 0 : return;
654 :
655 0 : if(!ignoreAssociatedVolumes)
656 : {
657 : // best option: FACEOPT_STORE_ASSOCIATED_VOLUMES
658 0 : if(grid.option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
659 : {
660 0 : Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(f);
661 0 : for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(f);
662 0 : iter != iterEnd; ++iter)
663 : {
664 0 : vVolumesOut.push_back(*iter);
665 : }
666 : return;
667 : }
668 : }
669 : /*
670 : // second best: use associated volumes of edges.
671 : if(grid.option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
672 : {
673 : // get an edge of the volume. check if associated volumes of that edge
674 : // contain the face.
675 : }
676 : */
677 :
678 : // worst: iterate through all volumes which are connected to the first vertex of f.
679 : // check for each if it contains f. If so, store it in the container.
680 : // to make things a little faster we'll check if the associated volumes contain a second vertex of f.
681 0 : Vertex* v1 = f->vertex(0);
682 :
683 0 : Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(v1);
684 0 : for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(v1);
685 0 : iter != iterEnd; ++iter)
686 : {
687 0 : Volume* v = *iter;
688 : // check if v contains v2
689 0 : if(VolumeContains(v, f->vertex(1)))
690 : {
691 0 : if(VolumeContains(v, f->vertex(2)))
692 : {
693 0 : if(VolumeContains(v, f))
694 0 : vVolumesOut.push_back(*iter);
695 : }
696 : }
697 : }
698 : }
699 :
700 : /// Collects all volumes. (Returns the volume itself)
701 0 : void CollectVolumes(vector<Volume*>& vVolumesOut, Grid& grid, Volume* v, bool clearContainer)
702 : {
703 0 : if(clearContainer)
704 : vVolumesOut.clear();
705 :
706 : // if no volumes are present, we can leave immediately
707 0 : if(grid.num<Volume>() == 0)
708 : return;
709 :
710 0 : vVolumesOut.push_back(v);
711 : }
712 :
713 : /// Collects all volumes that exist in the given grid which contain the given face.
714 0 : void CollectVolumes(std::vector<Volume*>& vVolumesOut, Grid& grid, FaceDescriptor& fd, bool clearContainer)
715 : {
716 0 : if(clearContainer)
717 : vVolumesOut.clear();
718 :
719 : // if no volumes are present, we can leave immediately
720 0 : if(grid.num<Volume>() == 0)
721 0 : return;
722 :
723 : // iterate through all volumes which are connected to the first vertex of fd.
724 : // check for each if it contains f. If so, store it in the container.
725 : // to make things a little faster we'll check if the associated volumes contain a second vertex of f.
726 0 : Vertex* v1 = fd.vertex(0);
727 :
728 0 : Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(v1);
729 0 : for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(v1);
730 0 : iter != iterEnd; ++iter)
731 : {
732 0 : Volume* v = *iter;
733 : // check if v contains v2
734 0 : if(VolumeContains(v, fd.vertex(1)))
735 : {
736 0 : if(VolumeContains(v, fd.vertex(2)))
737 : {
738 0 : if(VolumeContains(v, &fd))
739 0 : vVolumesOut.push_back(*iter);
740 : }
741 : }
742 : }
743 : }
744 :
745 : ////////////////////////////////////////////////////////////////////////
746 : // VolumeContains
747 : /// returns true if the given volume contains the given vertex
748 0 : bool VolumeContains(VolumeVertices* v, Vertex* vrt)
749 : {
750 0 : uint numVrts = v->num_vertices();
751 0 : Volume::ConstVertexArray vrts = v->vertices();
752 :
753 0 : for(uint i = 0; i < numVrts; ++i)
754 : {
755 0 : if(vrts[i] == vrt)
756 : return true;
757 : }
758 : return false;
759 : }
760 :
761 : /// returns true if the given volume contains the given edge
762 0 : bool VolumeContains(Volume* v, EdgeVertices* ev)
763 : {
764 0 : uint numEdges = v->num_edges();
765 0 : for(uint i = 0; i < numEdges; ++i)
766 : {
767 0 : EdgeDescriptor ed;
768 0 : v->edge_desc(i, ed);
769 0 : if(CompareVertices(ev, &ed))
770 : return true;
771 : }
772 : return false;
773 : }
774 :
775 : ////////////////////////////////////////////////////////////////////////
776 : // VolumeContains
777 : /// returns true if the given volume contains the given face
778 0 : bool VolumeContains(Volume* v, FaceVertices* fv)
779 : {
780 0 : FaceDescriptor fd;
781 0 : uint numFaces = v->num_faces();
782 0 : unsigned long hash = hash_key(fv);
783 0 : for(uint i = 0; i < numFaces; ++i)
784 : {
785 0 : v->face_desc(i, fd);
786 0 : if(hash == hash_key(&fd))
787 : {
788 0 : if(CompareVertices(fv, &fd))
789 : return true;
790 : }
791 : }
792 : return false;
793 : }
794 :
795 : }// end of namespace libGrid
|