Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
orientation_util_impl.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017: 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__UG_orientation_util_impl
34#define __H__UG_orientation_util_impl
35
36#include "common/math/ugmath.h"
39
40#include <stack>
41#include <vector>
42
43
44namespace ug{
45
46
48// InvertOrientation
49template <class iter_t>
50void InvertOrientation(Grid& grid, iter_t elemsBegin,
51 iter_t elemsEnd)
52{
53 for(iter_t iter = elemsBegin; iter != elemsEnd; ++iter)
54 grid.flip_orientation(*iter);
55}
56
57
59// FixFaceOrientation
60template <class TFaceIterator>
61void FixFaceOrientation(Grid& grid, TFaceIterator facesBegin,
62 TFaceIterator facesEnd)
63{
64 using namespace std;
65
66 {
67 // make sure that boundary faces are oriented outwards
69 for(TFaceIterator iter = facesBegin; iter != facesEnd; ++iter){
70 grid.associated_elements(vols, *iter);
71 if(vols.size() == 1 && !OrientationMatches(*iter, vols[0])){
72 grid.flip_orientation(*iter);
73 }
74 }
75 }
76
77// the rest only considers manifold faces
78// we use marks to differentiate between processed and unprocessed faces
79 grid.begin_marking();
80
81// we have to mark all faces between facesBegin and facesEnd initially,
82// to differentiate them from the other faces in the grid.
83 for(TFaceIterator iter = facesBegin; iter != facesEnd; ++iter){
84 if(NumAssociatedVolumes(grid, *iter) == 0)
85 grid.mark(*iter);
86 }
87
88// this edge descriptor will be used multiple times
90
91// containers to store neighbour elements.
92 vector<Face*> vNeighbours;
93
94// stack that stores candidates
95 stack<Face*> stkFaces;
96
97// we'll iterate through all faces
98 while(facesBegin != facesEnd)
99 {
100 // candidates are empty at this point.
101 // if the face is unprocessed it is a new candidate
102 if(grid.is_marked(*facesBegin))
103 {
104 // mark it as candidate (by removing the mark)
105 grid.unmark(*facesBegin);
106 stkFaces.push(*facesBegin);
107
108 // while the stack is not empty
109 while(!stkFaces.empty())
110 {
111 // get the candidate
112 Face* f = stkFaces.top();
113 stkFaces.pop();
114
115 // get the neighbours for each side
116 for(size_t i = 0; i < f->num_edges(); ++i)
117 {
118 f->edge_desc(i, ed);
119 GetNeighbours(vNeighbours, grid, f, i);
120
121 // fix orientation of unprocessed neighbours.
122 for(size_t j = 0; j < vNeighbours.size(); ++j)
123 {
124 Face* fn = vNeighbours[j];
125 if(grid.is_marked(fn))
126 {
127 // check whether the orientation of f and fn differs.
128 if(EdgeOrientationMatches(&ed, fn))
129 {
130 // the orientation of ed is the same as the orientation
131 // of an edge in fn.
132 // the faces thus have different orientation.
133 grid.flip_orientation(fn);
134 }
135
136 // mark the face as processed and add it to the stack
137 grid.unmark(fn);
138 stkFaces.push(fn);
139 }
140 }
141 }
142 }
143 }
144
145 // check the next face
146 ++facesBegin;
147 }
148
149 grid.end_marking();
150}
151
152
153template<class TAAPosVRT>
154bool
155CheckOrientation(Volume* vol, TAAPosVRT& aaPosVRT)
156{
157// some typedefs
158 typedef typename TAAPosVRT::ValueType vector_t;
159
160// First calculate the center of the volume
161 vector_t volCenter = CalculateCenter(vol, aaPosVRT);
162
163// now check for each side whether it points away from the center.
164 size_t numFaces = vol->num_faces();
166 vector_t normal;
167 for(size_t i = 0; i < numFaces; ++i){
168 vol->face_desc(i, fd);
169 CalculateNormal(normal, &fd, aaPosVRT);
170
171 // in order to best approximate quadrilateral faces, we'll calculate the
172 // center of the face and compare that to the volCenter.
173 vector_t faceCenter = CalculateCenter(&fd, aaPosVRT);
174
175 // now compare normal and center
176 vector_t dir;
177 VecSubtract(dir, faceCenter, volCenter);
178 if(VecDot(dir, normal) < 0)
179 return false;
180 }
181
182// all center / normal checks succeeded. Orientation is fine.
183 return true;
184}
185
186template<class TVolIterator, class TAAPosVRT>
187int
188FixOrientation(Grid& grid, TVolIterator volsBegin, TVolIterator volsEnd,
189 TAAPosVRT& aaPosVRT)
190{
191 int numFlips = 0;
192// iterate through all volumes
193 for(TVolIterator iter = volsBegin; iter != volsEnd; ++iter){
194 // check whether the orientation is fine
195 if(!CheckOrientation(*iter, aaPosVRT)){
196 grid.flip_orientation(*iter);
197 ++numFlips;
198 }
199 }
200
201 return numFlips;
202}
203
204
205}// end of namespace
206
207#endif //__H__UG_orientation_util_impl
Can be used to store information about an edge and to construct an edge.
Definition grid_base_objects.h:464
Can be queried for the edges and vertices of a face.
Definition grid_base_objects.h:684
Faces are 2-dimensional objects.
Definition grid_base_objects.h:510
virtual EdgeDescriptor edge_desc(int index) const
returns the i-th edge of the face.
Definition grid_base_objects.h:537
uint num_edges() const
Definition grid_base_objects.h:545
Manages the elements of a grid and their interconnection.
Definition grid.h:132
void end_marking()
ends a marking sequence. Call this method when you're done with marking.
Definition grid.cpp:1285
void unmark(GridObject *obj)
unmarks the object. Calls are only valid between calls to Grid::begin_marking and Grid::end_marking.
Definition grid_impl.hpp:808
bool is_marked(GridObject *obj) const
returns true if the object is marked, false if not.
Definition grid_impl.hpp:843
void mark(GridObject *obj)
marks the object. Calls are only valid between calls to Grid::begin_marking and Grid::end_marking.
Definition grid_impl.hpp:773
void flip_orientation(Edge *e)
flips the orientation of an edge.
Definition grid.cpp:535
void begin_marking()
begin marking.
Definition grid.cpp:1262
void associated_elements(traits< Vertex >::secure_container &elemsOut, TElem *e)
Puts all elements of type TAss which are contained in 'e' or which contain 'e' into elemsOut.
Definition grid_impl.hpp:466
Volumes are 3-dimensional objects.
Definition grid_base_objects.h:754
virtual FaceDescriptor face_desc(int index) const
Definition grid_base_objects.h:784
virtual uint num_faces() const
Definition grid_base_objects.h:786
int CalculateNormal(vector3 &vNormOut, Grid &grid, Edge *e, Grid::AttachmentAccessor< Vertex, APosition > &aaPos, Grid::AttachmentAccessor< Face, ANormal > *paaNormFACE)
Calculates the normal of the given edge.
Definition edge_util.cpp:314
int NumAssociatedVolumes(Grid &grid, Face *f)
returns the number of associated volumes of the specified face
Definition face_util.cpp:147
void GetNeighbours(std::vector< Face * > &vFacesOut, Grid &grid, Face *f, int side, bool clearContainer)
collects neighbours of the given side of a face.
Definition face_util.cpp:363
void CalculateCenter(vector_t &centerOut, const vector_t *pointSet, size_t numPoints)
calculates the center of a point-set
Definition math_util_impl.hpp:98
void VecSubtract(vector_t &vOut, const vector_t &v1, const vector_t &v2)
subtracts v2 from v1 and stores the result in a vOut
Definition math_vector_functions_common_impl.hpp:226
vector_t::value_type VecDot(const vector_t &v1, const vector_t &v2)
returns the dot-product of two vector_ts
Definition math_vector_functions_common_impl.hpp:385
Definition smart_pointer.h:814
the ug namespace
bool CheckOrientation(Volume *vol, TAAPosVRT &aaPosVRT)
returns true if the volume is oriented so that all sides point to this outside.
Definition orientation_util_impl.hpp:155
int FixOrientation(Grid &grid, TVolIterator volsBegin, TVolIterator volsEnd, TAAPosVRT &aaPosVRT)
Changes orientation of badly oriented volumes.
Definition orientation_util_impl.hpp:188
bool OrientationMatches(const EdgeVertices &e1, const EdgeVertices &e2)
Definition orientation.cpp:60
void InvertOrientation(Grid &grid, iter_t elemsBegin, iter_t elemsEnd)
inverts the orientation of all elements between elemsBegin and elemsEnd
Definition orientation_util_impl.hpp:50
bool EdgeOrientationMatches(EdgeVertices *ev, Face *f)
checks if the edge-orientation of the edge and the face matches.
Definition orientation_util.cpp:37
void FixFaceOrientation(Grid &grid, TFaceIterator facesBegin, TFaceIterator facesEnd)
creates uniform orientation of neighboured and boundary faces.
Definition orientation_util_impl.hpp:61
PointerConstArray< Volume * > secure_container
Definition grid.h:146