mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 06:05:58 -04:00
Immediately resolve complement operators for regions (#3145)
This commit is contained in:
parent
579777a3e5
commit
91fd60be69
10 changed files with 24 additions and 31 deletions
|
|
@ -778,12 +778,6 @@ class XConeOneSided(CompositeSurface):
|
|||
def __neg__(self):
|
||||
return -self.cone & (+self.plane if self.up else -self.plane)
|
||||
|
||||
def __pos__(self):
|
||||
if self.up:
|
||||
return (+self.cone & +self.plane) | -self.plane
|
||||
else:
|
||||
return (+self.cone & -self.plane) | +self.plane
|
||||
|
||||
|
||||
class YConeOneSided(CompositeSurface):
|
||||
"""One-sided cone parallel the y-axis
|
||||
|
|
@ -836,7 +830,6 @@ class YConeOneSided(CompositeSurface):
|
|||
self.up = up
|
||||
|
||||
__neg__ = XConeOneSided.__neg__
|
||||
__pos__ = XConeOneSided.__pos__
|
||||
|
||||
|
||||
class ZConeOneSided(CompositeSurface):
|
||||
|
|
@ -890,7 +883,6 @@ class ZConeOneSided(CompositeSurface):
|
|||
self.up = up
|
||||
|
||||
__neg__ = XConeOneSided.__neg__
|
||||
__pos__ = XConeOneSided.__pos__
|
||||
|
||||
|
||||
class Polygon(CompositeSurface):
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
from abc import ABC, abstractmethod
|
||||
from collections.abc import MutableSequence
|
||||
from copy import deepcopy
|
||||
|
|
@ -30,8 +31,9 @@ class Region(ABC):
|
|||
def __or__(self, other):
|
||||
return Union((self, other))
|
||||
|
||||
def __invert__(self):
|
||||
return Complement(self)
|
||||
@abstractmethod
|
||||
def __invert__(self) -> Region:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def __contains__(self, point):
|
||||
|
|
@ -442,6 +444,9 @@ class Intersection(Region, MutableSequence):
|
|||
self.append(other)
|
||||
return self
|
||||
|
||||
def __invert__(self) -> Union:
|
||||
return Union(~n for n in self)
|
||||
|
||||
# Implement mutable sequence protocol by delegating to list
|
||||
def __getitem__(self, key):
|
||||
return self._nodes[key]
|
||||
|
|
@ -530,6 +535,9 @@ class Union(Region, MutableSequence):
|
|||
self.append(other)
|
||||
return self
|
||||
|
||||
def __invert__(self) -> Intersection:
|
||||
return Intersection(~n for n in self)
|
||||
|
||||
# Implement mutable sequence protocol by delegating to list
|
||||
def __getitem__(self, key):
|
||||
return self._nodes[key]
|
||||
|
|
@ -603,7 +611,7 @@ class Complement(Region):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, node):
|
||||
def __init__(self, node: Region):
|
||||
self.node = node
|
||||
|
||||
def __contains__(self, point):
|
||||
|
|
@ -622,6 +630,9 @@ class Complement(Region):
|
|||
"""
|
||||
return point not in self.node
|
||||
|
||||
def __invert__(self) -> Region:
|
||||
return self.node
|
||||
|
||||
def __str__(self):
|
||||
return '~' + str(self.node)
|
||||
|
||||
|
|
@ -637,18 +648,7 @@ class Complement(Region):
|
|||
|
||||
@property
|
||||
def bounding_box(self) -> BoundingBox:
|
||||
# Use De Morgan's laws to distribute the complement operator so that it
|
||||
# only applies to surface half-spaces, thus allowing us to calculate the
|
||||
# bounding box in the usual recursive manner.
|
||||
if isinstance(self.node, Union):
|
||||
temp_region = Intersection(~n for n in self.node)
|
||||
elif isinstance(self.node, Intersection):
|
||||
temp_region = Union(~n for n in self.node)
|
||||
elif isinstance(self.node, Complement):
|
||||
temp_region = self.node.node
|
||||
else:
|
||||
temp_region = ~self.node
|
||||
return temp_region.bounding_box
|
||||
return (~self.node).bounding_box
|
||||
|
||||
def get_surfaces(self, surfaces=None):
|
||||
"""Recursively find and return all the surfaces referenced by the node
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
from abc import ABC, abstractmethod
|
||||
from collections.abc import Iterable
|
||||
from copy import deepcopy
|
||||
|
|
@ -2631,7 +2632,7 @@ class Halfspace(Region):
|
|||
else:
|
||||
return Union((self, other))
|
||||
|
||||
def __invert__(self):
|
||||
def __invert__(self) -> Halfspace:
|
||||
return -self.surface if self.side == '+' else +self.surface
|
||||
|
||||
def __contains__(self, point):
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
</materials>
|
||||
<geometry>
|
||||
<cell id="1" material="1" region="1 -2 3 -4 10 -9" universe="1"/>
|
||||
<cell id="2" material="2" region="~(1 -2 3 -4) (5 -6 7 -8) 10 -9" universe="1"/>
|
||||
<cell id="2" material="2" region="(-1 | 2 | -3 | 4) (5 -6 7 -8) 10 -9" universe="1"/>
|
||||
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane"/>
|
||||
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane"/>
|
||||
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane"/>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
</materials>
|
||||
<geometry>
|
||||
<cell id="1" material="1" region="1 -2 3 -4 10 -9" universe="1"/>
|
||||
<cell id="2" material="2" region="~(1 -2 3 -4) (5 -6 7 -8) 10 -9" universe="1"/>
|
||||
<cell id="2" material="2" region="(-1 | 2 | -3 | 4) (5 -6 7 -8) 10 -9" universe="1"/>
|
||||
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane"/>
|
||||
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane"/>
|
||||
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane"/>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
</materials>
|
||||
<geometry>
|
||||
<cell id="1" material="1" region="1 -2 3 -4 10 -9" universe="1"/>
|
||||
<cell id="2" material="2" region="~(1 -2 3 -4) (5 -6 7 -8) 10 -9" universe="1"/>
|
||||
<cell id="2" material="2" region="(-1 | 2 | -3 | 4) (5 -6 7 -8) 10 -9" universe="1"/>
|
||||
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane"/>
|
||||
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane"/>
|
||||
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane"/>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<geometry>
|
||||
<cell id="1" material="void" region="-1 2 -3" universe="1"/>
|
||||
<cell id="2" material="1" region="-1 3 -4" universe="1"/>
|
||||
<cell id="3" material="void" region="~(-1 2 -4)" universe="1"/>
|
||||
<cell id="3" material="void" region="1 | -2 | 4" universe="1"/>
|
||||
<surface boundary="vacuum" coeffs="0.0 0.0 1.0" id="1" type="x-cylinder"/>
|
||||
<surface boundary="vacuum" coeffs="-1.0" id="2" type="x-plane"/>
|
||||
<surface coeffs="1.0" id="3" type="x-plane"/>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<geometry>
|
||||
<cell id="1" material="void" region="-1 2 -3" universe="1"/>
|
||||
<cell id="2" material="1" region="-1 3 -4" universe="1"/>
|
||||
<cell id="3" material="void" region="~(-1 2 -4)" universe="1"/>
|
||||
<cell id="3" material="void" region="1 | -2 | 4" universe="1"/>
|
||||
<surface boundary="vacuum" coeffs="0.0 0.0 1.0" id="1" type="x-cylinder"/>
|
||||
<surface boundary="vacuum" coeffs="-1.0" id="2" type="x-plane"/>
|
||||
<surface coeffs="1.0" id="3" type="x-plane"/>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
</materials>
|
||||
<geometry>
|
||||
<cell id="1" material="1" region="1 -2 3 -4 10 -9" universe="1"/>
|
||||
<cell id="2" material="2" region="~(1 -2 3 -4) (5 -6 7 -8) 10 -9" universe="1"/>
|
||||
<cell id="2" material="2" region="(-1 | 2 | -3 | 4) (5 -6 7 -8) 10 -9" universe="1"/>
|
||||
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane"/>
|
||||
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane"/>
|
||||
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane"/>
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ def test_complement(reset):
|
|||
assert_unbounded(outside_equiv)
|
||||
|
||||
# string represention
|
||||
assert str(inside) == '~(1 | -2 | 3)'
|
||||
assert str(inside) == '(-1 2 -3)'
|
||||
|
||||
# evaluate method
|
||||
assert (0, 0, 0) in inside
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue