-
Notifications
You must be signed in to change notification settings - Fork 515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better infinite bound handling in Python API plot methods #3262
Comments
@jeinstei I believe As for |
Thanks @pshriwise -- I see the flow down on model.plot -> geometry.plot. I'll give that a try. |
For the |
Once I figure out a solid workflow for this, I will close out my (hopefully) unnecessary PR, and maybe instead convert this to a plotting example in the documentation then. Thanks for the assistance. |
I'm currently kit-bashing with a workaround function to create at least a plot in a programmatic manner. I know I could speed up this code with some fancy array work, but this is a MWE. I'll have a PR with some documentation updates for def determine_extents_from_model(model):
"""Takes a model with infinte bounds and finds extents automatically
Parameters
----------
model : openmc.Model
Model with infinite bounds to determine extent of
Returns
-------
work : openmc.BoundingBox
Bounding box (lower_left, upper_right) extents of model
width : (float, float, float)
Calculated width along each axis
origin : (float, float, float)
Calculated center of found extents
Raises
------
ValueError
If calculated extents is still unbounded
"""
base = model.geometry.bounding_box
work = openmc.BoundingBox(base[0], base[1])
# Determine indices where extents are infinite
base_infinite = np.isinf(base)
if not base_infinite.any():
# Calculate width and origin of original extents
width = base[1] - base[0]
origin = (width/2) + base[0]
return work, width, origin
active_tests = np.argwhere(base_infinite)
bboxes = []
for k,v in model.geometry.get_all_cells().items():
bboxes.append(np.asarray(v.bounding_box))
# Loop over bounding boxes for indices to test and determine max/min
# NOTE this could be done using masked array math, etc, but is not needed here
for ind in active_tests:
idx = tuple(ind)
for box in bboxes:
bval = work[idx]
tval = box[idx]
# Skip testing if test value is infinite itself
if np.isinf(tval):
continue
# If base value is infinite, save initial value
if np.isinf(bval):
work[idx] = tval
continue
if ind[0] == 0: # lower_left
if tval < bval:
work[idx] = tval
else: # upper_right
if tval > bval:
work[idx] = tval
if np.isinf(work).any():
raise ValueError("Unable to determine bounded extents from model cells")
# Calculate width and origin of new extents
width = work[1] - work[0]
origin = (width/2) + work[0]
return work, width, origin |
Description
Currently, the plot methods in the Python API rely on setting defaults or raising exceptions in cases where geometry is unbounded. in
model.plot()
the bbox currently is set byself.geometry.bounding_box
, while inPlot.from_geometry()
, an exception is raised. If we add an argument to these calls for a[width, height]
, we can immediately generate plots with user-generated extents for the basis or field instead of relying on a possibly unbounded dimension.Alternatives
This seems possibly similar to the discussions raised in #2632 where there are inconsistencies in BoundingBox handling between APIs. I'm not sure what the desired alternatives would be besides creating custom overrides. Possibly changing the
bounding_box
property or adding abounding_box_restricted
that handles infinite extents in a reproducible manner.Compatibility
This should add new arguments to some plotting APIs, but should also not change existing usage as they would have well-handled default values.
The text was updated successfully, but these errors were encountered: