mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 06:05:58 -04:00
Polygon fix to better handle colinear points (#2935)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
This commit is contained in:
parent
c85ba93040
commit
463299d04a
2 changed files with 41 additions and 11 deletions
|
|
@ -635,7 +635,7 @@ class XConeOneSided(CompositeSurface):
|
|||
z-coordinate of the apex. Defaults to 0.
|
||||
r2 : float, optional
|
||||
Parameter related to the aperture [:math:`\\rm cm^2`].
|
||||
It can be interpreted as the increase in the radius squared per cm along
|
||||
It can be interpreted as the increase in the radius squared per cm along
|
||||
the cone's axis of revolution.
|
||||
up : bool
|
||||
Whether to select the side of the cone that extends to infinity in the
|
||||
|
|
@ -695,7 +695,7 @@ class YConeOneSided(CompositeSurface):
|
|||
z-coordinate of the apex. Defaults to 0.
|
||||
r2 : float, optional
|
||||
Parameter related to the aperture [:math:`\\rm cm^2`].
|
||||
It can be interpreted as the increase in the radius squared per cm along
|
||||
It can be interpreted as the increase in the radius squared per cm along
|
||||
the cone's axis of revolution.
|
||||
up : bool
|
||||
Whether to select the side of the cone that extends to infinity in the
|
||||
|
|
@ -749,7 +749,7 @@ class ZConeOneSided(CompositeSurface):
|
|||
z-coordinate of the apex. Defaults to 0.
|
||||
r2 : float, optional
|
||||
Parameter related to the aperture [:math:`\\rm cm^2`].
|
||||
It can be interpreted as the increase in the radius squared per cm along
|
||||
It can be interpreted as the increase in the radius squared per cm along
|
||||
the cone's axis of revolution.
|
||||
up : bool
|
||||
Whether to select the side of the cone that extends to infinity in the
|
||||
|
|
@ -1029,9 +1029,9 @@ class Polygon(CompositeSurface):
|
|||
-------
|
||||
None
|
||||
"""
|
||||
# Only attempt the triangulation up to 3 times.
|
||||
if depth > 2:
|
||||
raise RuntimeError('Could not create a valid triangulation after 3'
|
||||
# Only attempt the triangulation up to 5 times.
|
||||
if depth > 4:
|
||||
raise RuntimeError('Could not create a valid triangulation after 5'
|
||||
' attempts')
|
||||
|
||||
tri = Delaunay(points, qhull_options='QJ')
|
||||
|
|
@ -1039,7 +1039,7 @@ class Polygon(CompositeSurface):
|
|||
# included in the triangulation, break it into two line segments.
|
||||
n = len(points)
|
||||
new_pts = []
|
||||
for i, j in zip(range(n), range(1, n +1)):
|
||||
for i, j in zip(range(n), range(1, n + 1)):
|
||||
# If both vertices of any edge are not found in any simplex, insert
|
||||
# a new point between them.
|
||||
if not any([i in s and j % n in s for s in tri.simplices]):
|
||||
|
|
@ -1077,7 +1077,8 @@ class Polygon(CompositeSurface):
|
|||
return group
|
||||
# If group is empty, grab the next simplex in the dictionary and recurse
|
||||
if group is None:
|
||||
sidx = next(iter(neighbor_map))
|
||||
# Start with smallest neighbor lists
|
||||
sidx = sorted(neighbor_map.items(), key=lambda item: len(item[1]))[0][0]
|
||||
return self._group_simplices(neighbor_map, group=[sidx])
|
||||
# Otherwise use the last simplex in the group
|
||||
else:
|
||||
|
|
@ -1087,13 +1088,16 @@ class Polygon(CompositeSurface):
|
|||
# For each neighbor check if it is part of the same convex
|
||||
# hull as the rest of the group. If yes, recurse. If no, continue on.
|
||||
for n in neighbors:
|
||||
if n in group or neighbor_map.get(n, None) is None:
|
||||
if n in group or neighbor_map.get(n) is None:
|
||||
continue
|
||||
test_group = group + [n]
|
||||
test_point_idx = np.unique(self._tri.simplices[test_group, :])
|
||||
test_points = self.points[test_point_idx]
|
||||
# If test_points are convex keep adding to this group
|
||||
if len(test_points) == len(ConvexHull(test_points).vertices):
|
||||
test_hull = ConvexHull(test_points, qhull_options='Qc')
|
||||
pts_on_hull = len(test_hull.vertices) + len(test_hull.coplanar)
|
||||
# If test_points are convex (including coplanar) keep adding to
|
||||
# this group
|
||||
if len(test_points) == pts_on_hull:
|
||||
group = self._group_simplices(neighbor_map, group=test_group)
|
||||
return group
|
||||
|
||||
|
|
|
|||
|
|
@ -399,6 +399,32 @@ def test_polygon():
|
|||
with pytest.raises(ValueError):
|
||||
openmc.model.Polygon(rz_points)
|
||||
|
||||
# Test "M" shaped polygon
|
||||
points = np.array([[8.5151581, -17.988337],
|
||||
[10.381711000000001, -17.988337],
|
||||
[12.744357, -24.288728000000003],
|
||||
[15.119406000000001, -17.988337],
|
||||
[16.985959, -17.988337],
|
||||
[16.985959, -27.246687],
|
||||
[15.764328, -27.246687],
|
||||
[15.764328, -19.116951],
|
||||
[13.376877, -25.466951],
|
||||
[12.118039, -25.466951],
|
||||
[9.7305877, -19.116951],
|
||||
[9.7305877, -27.246687],
|
||||
[8.5151581, -27.246687]])
|
||||
|
||||
# Test points inside and outside by using offset method
|
||||
m_polygon = openmc.model.Polygon(points, basis='xz')
|
||||
inner_pts = m_polygon.offset(-0.1).points
|
||||
assert all([(pt[0], 0, pt[1]) in -m_polygon for pt in inner_pts])
|
||||
outer_pts = m_polygon.offset(0.1).points
|
||||
assert all([(pt[0], 0, pt[1]) in +m_polygon for pt in outer_pts])
|
||||
|
||||
# Offset of -0.2 will cause self-intersection
|
||||
with pytest.raises(ValueError):
|
||||
m_polygon.offset(-0.2)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("axis", ["x", "y", "z"])
|
||||
def test_cruciform_prism(axis):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue