Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
dumux-repositories
dumux
Commits
e826db6b
Commit
e826db6b
authored
Jul 25, 2018
by
Timo Koch
Browse files
[geometry] Add epsilons in make geometry for increased robustness
parent
b9fb1feb
Changes
1
Hide whitespace changes
Inline
Side-by-side
dumux/common/geometry/makegeometry.hh
View file @
e826db6b
...
...
@@ -24,6 +24,7 @@
#include <vector>
#include <array>
#include <limits>
#include <dune/common/fvector.hh>
#include <dune/common/fmatrix.hh>
#include <dune/geometry/multilineargeometry.hh>
...
...
@@ -34,17 +35,39 @@ namespace Dumux {
//! Checks if four points lie within the same plane.
template
<
class
CoordScalar
>
bool
pointsAreCoplanar
(
const
std
::
vector
<
Dune
::
FieldVector
<
CoordScalar
,
3
>>&
points
,
CoordScalar
eps
=
1e-20
)
bool
pointsAreCoplanar
(
const
std
::
vector
<
Dune
::
FieldVector
<
CoordScalar
,
3
>>&
points
,
const
CoordScalar
scale
)
{
assert
(
points
.
size
()
==
4
);
// (see "Real-Time Collision Detection" by Christer Ericson)
Dune
::
FieldMatrix
<
CoordScalar
,
4
,
4
>
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
<
class
CoordScalar
>
bool
pointsAreCoplanar
(
const
std
::
vector
<
Dune
::
FieldVector
<
CoordScalar
,
3
>>&
points
)
{
Dune
::
FieldVector
<
CoordScalar
,
3
>
bBoxMin
(
std
::
numeric_limits
<
CoordScalar
>::
max
());
Dune
::
FieldVector
<
CoordScalar
,
3
>
bBoxMax
(
std
::
numeric_limits
<
CoordScalar
>::
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<Dune::FieldVector<CoordScalar, 3>>
if
(
!
enableSanityCheck
)
return
GeometryType
(
Dune
::
GeometryTypes
::
quadrilateral
,
points
);
// compute size
Dune
::
FieldVector
<
CoordScalar
,
3
>
bBoxMin
(
std
::
numeric_limits
<
CoordScalar
>::
max
());
Dune
::
FieldVector
<
CoordScalar
,
3
>
bBoxMax
(
std
::
numeric_limits
<
CoordScalar
>::
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<Dune::FieldVector<CoordScalar, 3>>
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
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment