mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 13:45:36 -04:00
simplified offset method
This commit is contained in:
parent
13b1bb88d0
commit
299525984f
1 changed files with 32 additions and 18 deletions
|
|
@ -662,7 +662,8 @@ class Polygon(CompositeSurface):
|
|||
points = points[:-1, :]
|
||||
check_length('points', points, 3)
|
||||
|
||||
self._points = points
|
||||
# Order the points counter-clockwise (necessary for offset method)
|
||||
self._points = self._make_ccw(points)
|
||||
|
||||
# Create a triangulation of the points.
|
||||
self._tri = Delaunay(self._points, qhull_options='QJ')
|
||||
|
|
@ -724,6 +725,29 @@ class Polygon(CompositeSurface):
|
|||
def region(self):
|
||||
return self._region
|
||||
|
||||
def _make_ccw(self, points):
|
||||
"""Order a set of points counter-clockwise.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
points : np.ndarray (Nx2)
|
||||
An Nx2 array of coordinate pairs describing the vertices.
|
||||
|
||||
Returns
|
||||
-------
|
||||
ordered_points : the input points ordered counter-clockwise
|
||||
"""
|
||||
vector = np.empty(points.shape[0])
|
||||
this_x, this_y = points[:-1, 0], points[:-1, 1]
|
||||
next_x, next_y = points[1:, 0], points[1:, 1]
|
||||
vector[:-1] = (next_x - this_x)*(next_y + this_y)
|
||||
vector[-1] = (this_x[0] - next_x[-1])*(this_y[0] + next_y[-1])
|
||||
|
||||
if np.sum(vector) < 0:
|
||||
return points
|
||||
|
||||
return points[::-1, :]
|
||||
|
||||
def _group_simplices(self, neighbor_map, group=None):
|
||||
"""Generate a convex grouping of simplices.
|
||||
|
||||
|
|
@ -883,25 +907,15 @@ class Polygon(CompositeSurface):
|
|||
The distance to offset the polygon by. Positive is outward
|
||||
(expanding) and negative is inward (shrinking).
|
||||
|
||||
|
||||
Returns
|
||||
-------
|
||||
offset_polygon : openmc.model.Polygon
|
||||
"""
|
||||
# Get the points of the polygon and outward normals such that
|
||||
# normals[i] corresponds to the edge between points[i-1] and points[i]
|
||||
points = self.points
|
||||
normals = self._normals
|
||||
normals = np.insert(normals, 0, normals[-1, :], axis=0)
|
||||
ndotv1 = np.sum(normals[:-1, :]*(points + distance*normals[:-1, :]),
|
||||
axis=-1, keepdims=True)
|
||||
ndotv2 = np.sum(normals[1:, :]*(points + distance*normals[1:, :]),
|
||||
axis=-1, keepdims=True)
|
||||
normals = np.insert(self._normals, 0, self._normals[-1, :], axis=0)
|
||||
cos2theta = np.sum(normals[1:, :]*normals[:-1, :], axis=-1, keepdims=True)
|
||||
costheta = np.cos(np.arccos(cos2theta) / 2)
|
||||
nvec = (normals[1:, :] + normals[:-1, :])
|
||||
unit_nvec = nvec / np.linalg.norm(nvec, axis=-1, keepdims=True)
|
||||
disp_vec = distance / costheta * unit_nvec
|
||||
|
||||
new_points = np.empty_like(points)
|
||||
denom = normals[:-1, 0]*normals[1:, 1] - normals[:-1, 1]*normals[1:, 0]
|
||||
new_points[:, 0] = normals[1:, 1]*ndotv1.T - normals[:-1, 1]*ndotv2.T
|
||||
new_points[:, 1] = -normals[1:, 0]*ndotv1.T + normals[:-1, 0]*ndotv2.T
|
||||
new_points /= denom[:, None]
|
||||
|
||||
return type(self)(new_points, basis=self.basis)
|
||||
return type(self)(self.points + disp_vec, basis=self.basis)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue