Commit e826db6b by Timo Koch

### [geometry] Add epsilons in make geometry for increased robustness

parent b9fb1feb
 ... ... @@ -24,6 +24,7 @@ #include #include #include #include #include #include ... ... @@ -34,17 +35,39 @@ namespace Dumux { //! Checks if four points lie within the same plane. template bool pointsAreCoplanar(const std::vector>& points, CoordScalar eps = 1e-20) bool pointsAreCoplanar(const std::vector>& points, const CoordScalar scale) { assert(points.size() == 4); // (see "Real-Time Collision Detection" by Christer Ericson) Dune::FieldMatrix M; for(int i = 0; i < 3; ++i ) M[i] = {points[0][i], points[1][i], points[2][i], points[3][i]}; M[3] = {1.0, 1.0, 1.0, 1.0}; M[3] = {1.0*scale, 1.0*scale, 1.0*scale, 1.0*scale}; using std::abs; return abs(M.determinant()) < eps; return abs(M.determinant()) < 1.5e-7*scale*scale*scale*scale; } //! Checks if four points lie within the same plane. template bool pointsAreCoplanar(const std::vector>& points) { Dune::FieldVector bBoxMin(std::numeric_limits::max()); Dune::FieldVector bBoxMax(std::numeric_limits::lowest()); for (const auto& p : points) { for (int i=0; i<3; i++) { using std::min; using std::max; bBoxMin[i] = min(bBoxMin[i], p[i]); bBoxMax[i] = max(bBoxMax[i], p[i]); } } const auto size = (bBoxMax - bBoxMin).two_norm(); return pointsAreCoplanar(points, size); } /*! ... ... @@ -127,8 +150,24 @@ auto makeDuneQuadrilaterial(const std::vector> if(!enableSanityCheck) return GeometryType(Dune::GeometryTypes::quadrilateral, points); // compute size Dune::FieldVector bBoxMin(std::numeric_limits::max()); Dune::FieldVector bBoxMax(std::numeric_limits::lowest()); for (const auto& p : points) { for (int i=0; i<3; i++) { using std::min; using std::max; bBoxMin[i] = min(bBoxMin[i], p[i]); bBoxMax[i] = max(bBoxMax[i], p[i]); } } const auto size = (bBoxMax - bBoxMin).two_norm(); // otherwise, perform a number of checks and corrections if(!pointsAreCoplanar(points)) if(!pointsAreCoplanar(points, size)) DUNE_THROW(Dune::InvalidStateException, "Points do not lie within a plane"); // make sure points conform with dune ordering ... ... @@ -140,8 +179,8 @@ auto makeDuneQuadrilaterial(const std::vector> const auto quadrilateral = GeometryType(Dune::GeometryTypes::quadrilateral, corners); const auto eps = 1e-20; if(quadrilateral.volume() < eps) const auto eps = 1e-7; if(quadrilateral.volume() < eps*size*size) DUNE_THROW(Dune::InvalidStateException, "Something went wrong, geometry has area of zero"); return quadrilateral; ... ...
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!