22#ifndef DUMUX_GEOMETRY_MAKE_GEOMETRY_HH
23#define DUMUX_GEOMETRY_MAKE_GEOMETRY_HH
28#include <dune/common/fvector.hh>
29#include <dune/common/fmatrix.hh>
30#include <dune/common/exceptions.hh>
31#include <dune/geometry/multilineargeometry.hh>
41template<
class CoordScalar>
42bool pointsAreCoplanar(
const std::vector<Dune::FieldVector<CoordScalar, 3>>& points,
const CoordScalar scale)
44 if (points.size() != 4)
45 DUNE_THROW(Dune::InvalidStateException,
"Check only works for 4 points!");
48 Dune::FieldMatrix<CoordScalar, 4, 4> M;
49 for (
int i = 0; i < 3; ++i )
50 M[i] = {points[0][i], points[1][i], points[2][i], points[3][i]};
51 M[3] = {1.0*scale, 1.0*scale, 1.0*scale, 1.0*scale};
54 return abs(M.determinant()) < 1.5e-7*scale*scale*scale*scale;
61template<
class CoordScalar>
64 Dune::FieldVector<CoordScalar, 3> bBoxMin(std::numeric_limits<CoordScalar>::max());
65 Dune::FieldVector<CoordScalar, 3> bBoxMax(std::numeric_limits<CoordScalar>::lowest());
66 for (
const auto& p : points)
68 for (
int i=0; i<3; i++)
72 bBoxMin[i] = min(bBoxMin[i], p[i]);
73 bBoxMax[i] = max(bBoxMax[i], p[i]);
77 const auto size = (bBoxMax - bBoxMin).two_norm();
89template<
class CoordScalar>
90std::vector<Dune::FieldVector<CoordScalar, 3>>
getReorderedPoints(
const std::vector<Dune::FieldVector<CoordScalar, 3>>& points)
92 std::array<int, 4> tmp;
103template<
class CoordScalar>
104std::vector<Dune::FieldVector<CoordScalar, 3>>
getReorderedPoints(
const std::vector<Dune::FieldVector<CoordScalar, 3>>& points,
105 std::array<int, 4>& orientations)
107 if(points.size() == 4)
109 auto& p0 = points[0];
110 auto& p1 = points[1];
111 auto& p2 = points[2];
112 auto& p3 = points[3];
124 const bool diagonalsIntersect = (orientations[0] != orientations[1]) && (orientations[2] != orientations[3]);
127 if(diagonalsIntersect)
131 using GlobalPosition = Dune::FieldVector<CoordScalar, 3>;
132 if(!diagonalsIntersect && orientations[0] == 1)
133 return std::vector<GlobalPosition>{p1, p0, p2, p3};
134 else if(!diagonalsIntersect && orientations[0] == -1)
135 return std::vector<GlobalPosition>{p3, p1, p0, p2};
137 DUNE_THROW(Dune::InvalidStateException,
"Could not reorder points");
140 DUNE_THROW(Dune::NotImplemented,
"Reorder for " << points.size() <<
" points.");
151template<
class CoordScalar,
bool enableSanityCheck = true>
154 if (points.size() != 4)
155 DUNE_THROW(Dune::InvalidStateException,
"A quadrilateral needs 4 corner points!");
157 using GlobalPosition = Dune::FieldVector<CoordScalar, 3>;
158 static constexpr auto coordDim = GlobalPosition::dimension;
159 static constexpr auto dim = coordDim-1;
160 using GeometryType = Dune::MultiLinearGeometry<CoordScalar, dim, coordDim>;
163 if (!enableSanityCheck)
164 return GeometryType(Dune::GeometryTypes::quadrilateral, points);
167 Dune::FieldVector<CoordScalar, 3> bBoxMin(std::numeric_limits<CoordScalar>::max());
168 Dune::FieldVector<CoordScalar, 3> bBoxMax(std::numeric_limits<CoordScalar>::lowest());
169 for (
const auto& p : points)
171 for (
int i = 0; i < 3; i++)
175 bBoxMin[i] = min(bBoxMin[i], p[i]);
176 bBoxMax[i] = max(bBoxMax[i], p[i]);
180 const auto size = (bBoxMax - bBoxMin).two_norm();
184 DUNE_THROW(Dune::InvalidStateException,
"Points do not lie within a plane");
186 auto corners = grahamConvexHull<2>(points);
187 if (corners.size() != 4)
188 DUNE_THROW(Dune::InvalidStateException,
"Points do not span a strictly convex polygon!");
191 std::array<int, 4> orientations;
194 if (std::any_of(orientations.begin(), orientations.end(), [](
auto i){ return i == 0; }))
195 DUNE_THROW(Dune::InvalidStateException,
"More than two points lie on the same line.");
197 const auto quadrilateral = GeometryType(Dune::GeometryTypes::quadrilateral, corners);
199 const auto eps = 1e-7;
200 if (quadrilateral.volume() < eps*size*size)
201 DUNE_THROW(Dune::InvalidStateException,
"Something went wrong, geometry has area of zero");
203 return quadrilateral;
Define some often used mathematical functions.
A function to compute the convex hull of a point cloud and a function to triangulate the polygon area...
auto makeDuneQuadrilaterial(const std::vector< Dune::FieldVector< CoordScalar, 3 > > &points)
Creates a dune quadrilateral geometry given 4 corner points.
Definition: makegeometry.hh:152
int getOrientation(const Dune::FieldVector< ctype, 3 > &a, const Dune::FieldVector< ctype, 3 > &b, const Dune::FieldVector< ctype, 3 > &c, const Dune::FieldVector< ctype, 3 > &normal)
Returns the orientation of a sequence a-->b-->c in one plane (defined by normal vector)
Definition: grahamconvexhull.hh:47
Vector normal(const Vector &v)
Create a vector normal to the given one (v is expected to be non-zero)
Definition: normal.hh:36
std::vector< Dune::FieldVector< CoordScalar, 3 > > getReorderedPoints(const std::vector< Dune::FieldVector< CoordScalar, 3 > > &points)
Returns a vector of points following the dune ordering. Convenience method that creates a temporary o...
Definition: makegeometry.hh:90
bool pointsAreCoplanar(const std::vector< Dune::FieldVector< CoordScalar, 3 > > &points, const CoordScalar scale)
Checks if four points lie within the same plane.
Definition: makegeometry.hh:42
Dune::FieldVector< Scalar, 3 > crossProduct(const Dune::FieldVector< Scalar, 3 > &vec1, const Dune::FieldVector< Scalar, 3 > &vec2)
Cross product of two vectors in three-dimensional Euclidean space.
Definition: math.hh:654