3.3.0
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
geometry/distance.hh
Go to the documentation of this file.
1/*****************************************************************************
2 * See the file COPYING for full copying permissions. *
3 * *
4 * This program is free software: you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation, either version 3 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
16 *****************************************************************************/
22#ifndef DUMUX_GEOMETRY_DISTANCE_HH
23#define DUMUX_GEOMETRY_DISTANCE_HH
24
25#include <dune/common/fvector.hh>
26#include <dune/geometry/quadraturerules.hh>
27
28namespace Dumux {
29
34template<class Geometry>
35inline typename Geometry::ctype
36averageDistancePointGeometry(const typename Geometry::GlobalCoordinate& p,
37 const Geometry& geometry,
38 std::size_t integrationOrder = 2)
39{
40 typename Geometry::ctype avgDist = 0.0;
41 const auto& quad = Dune::QuadratureRules<typename Geometry::ctype, Geometry::mydimension>::rule(geometry.type(), integrationOrder);
42 for (const auto& qp : quad)
43 avgDist += (geometry.global(qp.position())-p).two_norm()*qp.weight()*geometry.integrationElement(qp.position());
44 return avgDist/geometry.volume();
45}
46
51template<class Point>
52inline typename Point::value_type
53distancePointLine(const Point& p, const Point& a, const Point& b)
54{
55 const auto ab = b - a;
56 const auto t = (p - a)*ab/ab.two_norm2();
57 auto proj = a;
58 proj.axpy(t, ab);
59 return (proj - p).two_norm();
60}
61
68template<class Geometry>
69inline typename Geometry::ctype
70distancePointLine(const typename Geometry::GlobalCoordinate& p, const Geometry& geometry)
71{
72 static_assert(Geometry::mydimension == 1, "Geometry has to be a line");
73 const auto& a = geometry.corner(0);
74 const auto& b = geometry.corner(1);
75 return distancePointLine(p, a, b);
76}
77
82template<class Point>
83inline typename Point::value_type
84distancePointSegment(const Point& p, const Point& a, const Point& b)
85{
86 const auto ab = b - a;
87 auto t = (p - a)*ab;
88
89 if (t <= 0.0)
90 return (a - p).two_norm();
91
92 const auto lengthSq = ab.two_norm2();
93 if (t >= lengthSq)
94 return (b - p).two_norm();
95
96 auto proj = a;
97 proj.axpy(t/lengthSq, ab);
98 return (proj - p).two_norm();
99}
100
105template<class Geometry>
106inline typename Geometry::ctype
107distancePointSegment(const typename Geometry::GlobalCoordinate& p, const Geometry& geometry)
108{
109 static_assert(Geometry::mydimension == 1, "Geometry has to be a segment");
110 const auto& a = geometry.corner(0);
111 const auto& b = geometry.corner(1);
112 return distancePointSegment(p, a, b);
113}
114
119template<class Geometry>
120inline typename Geometry::ctype
121averageDistanceSegmentGeometry(const typename Geometry::GlobalCoordinate& a,
122 const typename Geometry::GlobalCoordinate& b,
123 const Geometry& geometry,
124 std::size_t integrationOrder = 2)
125{
126 typename Geometry::ctype avgDist = 0.0;
127 const auto& quad = Dune::QuadratureRules<typename Geometry::ctype, Geometry::mydimension>::rule(geometry.type(), integrationOrder);
128 for (const auto& qp : quad)
129 avgDist += distancePointSegment(geometry.global(qp.position()), a, b)*qp.weight()*geometry.integrationElement(qp.position());
130 return avgDist/geometry.volume();
131}
132
137template<class ctype, int dimWorld>
138inline ctype distance(const Dune::FieldVector<ctype, dimWorld>& a,
139 const Dune::FieldVector<ctype, dimWorld>& b)
140{ return (a-b).two_norm(); }
141
142
143
144namespace Detail {
145
146// helper struct to compute distance between two geometries, specialized below
147template<class Geo1, class Geo2,
148 int dimWorld = Geo1::coorddimension,
149 int dim1 = Geo1::mydimension, int dim2 = Geo2::mydimension>
151{
152 static_assert(Geo1::coorddimension == Geo2::coorddimension, "Geometries have to have the same coordinate dimensions");
153 static auto distance(const Geo1& geo1, const Geo2& geo2)
154 {
155 DUNE_THROW(Dune::NotImplemented, "Geometry distance computation not implemented for dimworld = "
156 << dimWorld << ", dim1 = " << dim1 << ", dim2 = " << dim2);
157 }
158};
159
160// distance point-point
161template<class Geo1, class Geo2, int dimWorld>
162struct GeometryDistance<Geo1, Geo2, dimWorld, 0, 0>
163{
164 static_assert(Geo1::coorddimension == Geo2::coorddimension, "Geometries have to have the same coordinate dimensions");
165 static auto distance(const Geo1& geo1, const Geo2& geo2)
166 { return Dumux::distance(geo1.corner(0), geo2.corner(0)); }
167};
168
169// distance segment-point
170template<class Geo1, class Geo2, int dimWorld>
171struct GeometryDistance<Geo1, Geo2, dimWorld, 1, 0>
172{
173 static_assert(Geo1::coorddimension == Geo2::coorddimension, "Geometries have to have the same coordinate dimensions");
174 static auto distance(const Geo1& geo1, const Geo2& geo2)
175 { return distancePointSegment(geo2.corner(0), geo1); }
176};
177
178// distance point-segment
179template<class Geo1, class Geo2, int dimWorld>
180struct GeometryDistance<Geo1, Geo2, dimWorld, 0, 1>
181{
182 static_assert(Geo1::coorddimension == Geo2::coorddimension, "Geometries have to have the same coordinate dimensions");
183 static auto distance(const Geo1& geo1, const Geo2& geo2)
184 { return distancePointSegment(geo1.corner(0), geo2); }
185};
186
187} // end namespace Detail
188
193template<class Geo1, class Geo2>
194inline auto distance(const Geo1& geo1, const Geo2& geo2)
196
197} // end namespace Dumux
198
199#endif
Geometry::ctype averageDistanceSegmentGeometry(const typename Geometry::GlobalCoordinate &a, const typename Geometry::GlobalCoordinate &b, const Geometry &geometry, std::size_t integrationOrder=2)
Compute the average distance from a segment to a geometry by integration.
Definition: geometry/distance.hh:121
Geometry::ctype averageDistancePointGeometry(const typename Geometry::GlobalCoordinate &p, const Geometry &geometry, std::size_t integrationOrder=2)
Compute the average distance from a point to a geometry by integration.
Definition: geometry/distance.hh:36
Point::value_type distancePointLine(const Point &p, const Point &a, const Point &b)
Compute the distance from a point to a line through the points a and b.
Definition: geometry/distance.hh:53
Point::value_type distancePointSegment(const Point &p, const Point &a, const Point &b)
Compute the distance from a point to the segment connecting the points a and b.
Definition: geometry/distance.hh:84
ctype distance(const Dune::FieldVector< ctype, dimWorld > &a, const Dune::FieldVector< ctype, dimWorld > &b)
Compute the shortest distance between two points.
Definition: geometry/distance.hh:138
Definition: adapt.hh:29
Definition: geometry/distance.hh:151
static auto distance(const Geo1 &geo1, const Geo2 &geo2)
Definition: geometry/distance.hh:153
static auto distance(const Geo1 &geo1, const Geo2 &geo2)
Definition: geometry/distance.hh:165
static auto distance(const Geo1 &geo1, const Geo2 &geo2)
Definition: geometry/distance.hh:174
static auto distance(const Geo1 &geo1, const Geo2 &geo2)
Definition: geometry/distance.hh:183