ug4
quality_util.h
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_quality_util
34 #define __H__UG_quality_util
35 
36 #include <limits>
37 #include <algorithm>
38 #include <string>
39 #include <vector>
43 #include "lib_grid/grid/grid.h"
44 
45 namespace ug {
46 
48 
53 template <class TAAPos>
55 {
56  // q = aMax * (a0 + a1 + a2) / (4*sqrt(3)*A)
57  using std::max;
58 
60  const number a[3] = { VecDistance(aaPos[vrts[0]], aaPos[vrts[1]]),
61  VecDistance(aaPos[vrts[1]], aaPos[vrts[2]]),
62  VecDistance(aaPos[vrts[2]], aaPos[vrts[0]])};
63  const number aMax = max(max(a[0], a[1]), a[2]);
64 
65  const number A = TriangleArea(aaPos[vrts[0]], aaPos[vrts[1]], aaPos[vrts[2]]);
66 
67  if(aMax > 0)
68  return (6.9282032302755091741097853660235 * A) / (aMax * (a[0] + a[1] + a[2]));
69  return 0;
70 }
71 
73 
78 template <class TAAPos>
80 {
81  // q = aMax * (a0 + a1 + a2 + a3) / (4*A)
82  using std::max;
83 
85  const number a[4] = { VecDistance(aaPos[vrts[0]], aaPos[vrts[1]]),
86  VecDistance(aaPos[vrts[1]], aaPos[vrts[2]]),
87  VecDistance(aaPos[vrts[2]], aaPos[vrts[3]]),
88  VecDistance(aaPos[vrts[3]], aaPos[vrts[0]])};
89  const number aMax = max(max(max(a[0], a[1]), a[2]), a[3]);
90 
91  const number A = QuadrilateralArea(aaPos[vrts[0]], aaPos[vrts[1]],
92  aaPos[vrts[2]], aaPos[vrts[3]]);
93 
94  if(aMax > 0)
95  return (4. * A) / (aMax * (a[0] + a[1] + a[2] + a[3]));
96  return 0;
97 }
98 
99 
101 
104 template <class TAAPos>
105 number AspectRatio (FaceVertices* f, TAAPos& aaPos)
106 {
107  switch(f->num_vertices()){
108  case 3: return TriangleAspectRatio (f, aaPos);
109  case 4: return QuadrilateralAspectRatio (f, aaPos);
110  default: UG_THROW("AspectRatio only supports faces with 3 or 4 vertices.");
111  }
112 }
113 
114 
115 template <class TAAPos>
116 number GetMaxEdgeLength (Volume* vol, TAAPos& aaPos)
117 {
118  using std::max;
119  number maxEdgeLenSq = 0;
120  EdgeDescriptor ed;
121  const size_t numEdges = vol->num_edges();
122  for(size_t i = 0; i < numEdges; ++i){
123  vol->edge_desc (i, ed);
125  const number edgeLenSq = VecDistanceSq (aaPos[vrts[0]], aaPos[vrts[1]]);
126  maxEdgeLenSq = max (maxEdgeLenSq, edgeLenSq);
127  }
128  return sqrt (maxEdgeLenSq);
129 }
130 
131 
132 template <class TAAPos>
134 {
135  /* optimal Aspect Ratio of a regular tetrahedron with edge lengths a:
136  * Q = hmin/lmax = sqrt(2/3)*a / a = 0.8164...
137  *
138  * Info: return value is normalized by factor sqrt(3/2)
139  * (s. Shewchuk 2002)
140  */
141 
142  Tetrahedron* tet = dynamic_cast<Tetrahedron*>(vol);
143 
144  UG_COND_THROW(!tet, "Expected volume of type Tetrahedron");
145 
146  const number minTetHeight = CalculateMinVolumeHeight(tet, aaPos);
147  const number maxEdgeLength = GetMaxEdgeLength(vol, aaPos);
148 
149  if(maxEdgeLength > 0)
150  return std::sqrt(3/2.0) * minTetHeight / maxEdgeLength;
151  else
152  return 0;
153 }
154 
155 
156 template <class TAAPos>
157 number AspectRatio(Volume* vol, TAAPos& aaPos)
158 {
159  switch(vol->num_vertices()){
160  case 4: return TetrahedronAspectRatio (vol, aaPos);
161  default: UG_THROW("AspectRatio only supports volumes with 4 vertices.");
162  }
163 }
164 
165 
166 
173 
174  std::string to_string();
175 };
176 
177 
179 template <class TElemIter, class TAAPos>
181 GetAspectRatioInfo (TElemIter elemsBegin, TElemIter elemsEnd, TAAPos& aaPos)
182 {
183  using std::min;
184  using std::max;
185 
186  AspectRatioInfo ari;
187  ari.mean = 0;
188  ari.min = 0;
189  ari.max = 0;
190  ari.sd = 0;
191 
192  if(elemsBegin == elemsEnd)
193  return ari;
194 
195  ari.min = 1;
196  number counter = 0;
197 
198  for(TElemIter ielem = elemsBegin; ielem != elemsEnd; ++ielem) {
199  number ar = AspectRatio (*ielem, aaPos);
200  ari.min = min (ari.min, ar);
201  ari.max = max (ari.max, ar);
202  ari.mean += ar;
203  ++counter;
204  }
205 
206  ari.mean /= counter;
207 
208  if(counter > 1){
209  for(TElemIter ielem = elemsBegin; ielem != elemsEnd; ++ielem) {
210  number ar = AspectRatio (*ielem, aaPos);
211  ari.sd += sq(ar - ari.mean);
212  }
213 
214  ari.sd = sqrt(ari.sd / (counter));
215  }
216 
217  return ari;
218 }
219 
220 
221 template <class TElemIter, class TAAPos>
222 void
224  std::vector<int>& histoOut,
225  TElemIter elemsBegin,
226  TElemIter elemsEnd,
227  int histoSecs,
228  TAAPos& aaPos,
232  *paaHistoSec = NULL)
233 {
234  using std::min;
235  using std::max;
236 
237  if(histoSecs <= 0){
238  histoOut.resize(0);
239  return;
240  }
241 
242  histoOut.resize(histoSecs, 0);
243 
244  UG_COND_THROW(paaHistoSec && (!paaHistoSec->valid()),
245  "Invalid paaHistoSec supplied to 'GetFaceAspectRatioHistogram'");
246 
247  for(TElemIter ielem = elemsBegin; ielem != elemsEnd; ++ielem) {
248  number ar = AspectRatio (*ielem, aaPos);
249  int sec = static_cast<int> (ar * histoSecs);
250  sec = min (sec, histoSecs - 1);
251  sec = max (sec, 0);
252  ++histoOut[sec];
253  if(paaHistoSec)
254  (*paaHistoSec)[*ielem] = sec;
255  }
256 }
257 
258 }// end of namespace
259 
260 #endif //__H__UG_quality_util
Can be used to store information about an edge and to construct an edge.
Definition: grid_base_objects.h:464
virtual ConstVertexArray vertices() const
Definition: grid_base_objects.h:367
Definition: grid_base_objects.h:483
virtual ConstVertexArray vertices() const
Definition: grid_base_objects.h:487
virtual size_t num_vertices() const
Definition: grid_base_objects.h:488
the generic attachment-accessor for access to grids attachment pipes.
Definition: grid.h:182
Vertex *const * ConstVertexArray
Definition: grid_base_objects.h:319
the most simple volume-element.
Definition: grid_objects_3d.h:91
Volumes are 3-dimensional objects.
Definition: grid_base_objects.h:754
virtual uint num_edges() const
Definition: grid_base_objects.h:782
virtual EdgeDescriptor edge_desc(int index) const
Definition: grid_base_objects.h:780
virtual size_t num_vertices() const
Definition: grid_base_objects.h:729
static number GetMaxEdgeLength(TDomain &dom)
Definition: domain_bridge.cpp:342
number CalculateMinVolumeHeight(Tetrahedron *tet, Grid::VertexAttachmentAccessor< APosition > &aaPos)
calculates the minimal height of a volume element of type tetrahedron
Definition: volume_util.cpp:109
#define UG_THROW(msg)
Definition: error.h:57
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition: error.h:61
double number
Definition: types.h:124
number TriangleArea(const vector_t &p1, const vector_t &p2, const vector_t &p3)
calculates the are of the triangle defined by p1, p2 and p3
Definition: math_util_impl.hpp:914
number QuadrilateralArea(const vector_t &p1, const vector_t &p2, const vector_t &p3, const vector_t &p4)
calculates the are of the triangle defined by p1, p2 and p3
Definition: math_util_impl.hpp:924
TNumber sq(TNumber val)
returns the square of a value (val*val)
Definition: math_util_impl.hpp:91
vector_t::value_type VecDistanceSq(const vector_t &v1, const vector_t &v2)
returns the squared distance of two vector_ts.
Definition: math_vector_functions_common_impl.hpp:351
vector_t::value_type VecDistance(const vector_t &v1, const vector_t &v2)
returns the distance of two vector_ts.
Definition: math_vector_functions_common_impl.hpp:375
the ug namespace
number TriangleAspectRatio(FaceVertices *f, TAAPos &aaPos)
Returns the aspect ratio of a triangle.
Definition: quality_util.h:54
number AspectRatio(FaceVertices *f, TAAPos &aaPos)
Returns the aspect ratio of a face.
Definition: quality_util.h:105
AspectRatioInfo GetAspectRatioInfo(TElemIter elemsBegin, TElemIter elemsEnd, TAAPos &aaPos)
Computes the AspectRatioInfo for a sample of elements.
Definition: quality_util.h:181
number QuadrilateralAspectRatio(FaceVertices *f, TAAPos &aaPos)
Returns the aspect ratio of a quadrilateral.
Definition: quality_util.h:79
void GetAspectRatioHistogram(std::vector< int > &histoOut, TElemIter elemsBegin, TElemIter elemsEnd, int histoSecs, TAAPos &aaPos, Grid::AttachmentAccessor< typename PtrToValueType< typename TElemIter::value_type >::base_type, Attachment< int > > *paaHistoSec=NULL)
Definition: quality_util.h:223
number TetrahedronAspectRatio(Volume *vol, TAAPos &aaPos)
Definition: quality_util.h:133
Holds information on the min, max, mean, and standard deviation of a sample.
Definition: quality_util.h:168
number min
Definition: quality_util.h:169
number mean
Definition: quality_util.h:171
number sd
Definition: quality_util.h:172
number max
Definition: quality_util.h:170
std::string to_string()
Definition: quality_util.cpp:39
void base_type
Definition: grid_base_objects.h:1011