Skip to content
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

fix - 2939 #3007

Open
wants to merge 16 commits into
base: develop
Choose a base branch
from
Open

fix - 2939 #3007

wants to merge 16 commits into from

Conversation

caderache2014
Copy link
Contributor

Adding basic contains functionality for cell in Geometry and Universe.

Fixes # (2939)

Checklist

  • [x]x] I have performed a self-review of my own code
  • I have run clang-format (version 15) on any C++ source files (if applicable)
  • I have followed the style guidelines for Python source files (if applicable)
  • I have made corresponding changes to the documentation (if applicable)
  • I have added tests that prove my fix is effective or that my feature works (if applicable)

if self.cells is None:
return False
else:
return cell.id in self.cells.keys()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can just be cell.id in self.cells

@MicahGale
Copy link
Contributor

To link it to the issue just say : fixes #2939

@caderache2014
Copy link
Contributor Author

@MicahGale @paulromano @pshriwise Hi all... looks like we have a failure.

Screenshot from 2024-05-21 17-58-56

It looks the like unit_tests/test_tracks.py has failed which is outside the remit this fix. Thoughts all?

Copy link
Contributor

@paulromano paulromano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes here don't really match what was proposed in #2939 since they only check for containment against cells in the immediate universe (rather than all cells that are potentially contained within a universe, which would require calling get_all_cells())

@caderache2014
Copy link
Contributor Author

@paulromano @MicahGale Please take a look at this revised PR. Am I on the right track?

Copy link
Contributor

@MicahGale MicahGale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this is a good second attempt. I think it could just be made more efficient.

Comment on lines 63 to 64
if cell is None:
return False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be valid. It should raise a TypeError. This could be:

if not isinstance(cell, openmc.Cell):
   raise TypeError(...)

but I think there's check_value, which is the preferred way to do type enforcement.

Comment on lines 72 to 78
if cell in set(self.get_all_cells().values()):
return True

if cell in set(self.get_all_universes().values()):
return True

return False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should all be punted to the Universe implementation.

Comment on lines 69 to 70
if cell in self.root_universe:
return True
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just do return cell in self.root_universe.

Comment on lines 55 to 56
if cell is None:
return False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once again check_value?

Comment on lines 58 to 73
local_cells = self.get_all_cells().values()

if local_cells is None:
return False



if cell in local_cells:
return True


for univ in self.get_all_universes().values():
if cell in univ:
return True

return False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this because it requires the entire tree to be flattened prior any searching being performed, which is very time consuming (#2953). This should be a short-circuited depth-first search (sorry C.S. people for butchering that).

I think it should be something like:

def __contains__(self, cell):
   ... type stuff
   
    # succeed in constant time if the cell is a leaf
   if cell.id in self.cells:
      return True

    # otherwise start a depth-first search
    for child_cell in self.cells.values():
        if isinstance(child_cell.fill, openmc.Universe):
           if cell in child_cell.fill: 
              return True
    return False

Comment on lines 9 to 50
def test_contains_cell():

c1 = openmc.Cell()
c2 = openmc.Cell()
c3 = openmc.Cell()
c3 = openmc.Cell()
c4 = openmc.Cell()


geom1= openmc.Geometry([c1, c2, c3])

assert (c1 in geom1)
assert (c2 in geom1)
assert (c3 in geom1)
assert not (c4 in geom1)


univ1 = openmc.Universe(name='univ1', cells=[c1, c2, c3])
geom2 = openmc.Geometry(univ1)

assert (c1 in geom2)
assert (c2 in geom2)
assert (c3 in geom2)
assert not (c4 in geom2)


c5 = openmc.Cell()
c6 = openmc.Cell()
univ2 = openmc.Universe(name='univ2', cells=[c5, c6])
c7 = openmc.Cell(fill=univ2)
c8 = openmc.Cell(fill=univ1)
univ_comp = openmc.Universe(name='composed universe',cells=[c7, c8])
geom_comp = openmc.Geometry(univ_comp)

assert c5 in geom_comp
assert c6 in geom_comp
assert c7 in geom_comp
assert c8 in geom_comp
assert c1 in geom_comp



Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few thoughts:

  1. I don't think this is quite PEP8, but I don't have the style off the top of my head.
  2. Line 27 could just be geom1.root_universe = univ1 but isn't essential.
  3. The test suite looks really good for having wide coverage of all possible scenarios.
  4. There is some repeated code, I can't decide if the effort of making it DRY is worth it here though. It is a test suite after all.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also you should test that nonsense fails, like testing that an error is raised for "hi" in geometry.

@caderache2014
Copy link
Contributor Author

@MicahGale @paulromano next draft submitted. All tests have passed. Any thoughts?

Copy link
Contributor

@MicahGale MicahGale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is getting really close, I just think TypeError (or whatever exception check_type raises shouldn't be suppressed.

I think this is mature enough for @paulromano, @pshriwise, or another core dev to review.

Comment on lines 63 to 66
try:
check_type('cell', cell, openmc.Cell)
except:
return False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's appropriate to silently suppress a TypeError. This shouldn't be in a try-except block IMO.

Comment on lines +60 to +68
if cell.id in self.cells:
return True

#otherwise do a depth-first search
for child_cell in self.cells.values():
if isinstance(child_cell.fill, openmc.Universe):
if cell in child_cell.fill:
return True
return False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code looks great... and familiar 😆.

assert c9 in u_composed
assert not c4 in u_composed

assert not 'hi' in u_composed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be:

with pytest.raises(TypeError): #error type might be different I'm just assuming
    'hi' in u_composed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MicahGale I'm not sure I understand. I altered the lines of test_universe.py to:
error_test_uni

This indeed triggers the TypeError exception from the logic of universe.py to
universe_contains_TypeError

This produced the following lone error when I run pytest test_universe.py:
TypeError1

Is there example of raising TypeError within the in another test script that I could look at? I assume I'm missing some syntax to.... contain the TypeError exception within the assert statement (analougous to a try-catch block)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MicahGale never mind. I figured it out

Copy link
Contributor

@MicahGale MicahGale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I said I think you added some tests that aren't relevant here and should be their own PR. They seem to be in commit: a88be0f.

To move them to a new branch you should:

  1. Make a new branch from develop: git checkout develop && git checkout -b <foo>. Though you are making this PR from your develop branch so tracking so making a new branch from the upstream develop will be tricky. You can make a new branch from your develop the more I think about it. It's not best practice as the PR for the other branch will include changes from this PR, but then you will just have to make sure the PRs are merged in the correct order.
  2. Cherry pick the commit to the new branch: git cherry-pick a88be0f602f897abe7406f83a9bf1709587d68cb
  3. Revert the commit on this branch. git checkout develop && git revert a88be0f602f897abe7406f83a9bf1709587d68cb

You will see people online saying you should do a hard reset, in general they are wrong and git reset should only be used if you really know what you're doing.

Comment on lines 996 to 1028

def test_boundingbox_consistency():

s19 = openmc.YCylinder(0, 0, 17.7)
s48 = openmc.Plane(0.7071067811865476, 6.123233995736766e-17, 0.7071067811865476, 11.45)
s58 = openmc.Plane(0.7071067811865476, 6.123233995736766e-17, 0.7071067811865476, 14.35)
s62 = openmc.Plane(6.123233995736766e-17, 1.0, 6.123233995736766e-17, 1.5999999999999999)
s64 = openmc.Plane(6.123233995736766e-17, 1.0, 6.123233995736766e-17, -1.3)
s65 = openmc.Plane(-0.7071067811865475, 6.123233995736766e-17, 0.7071067811865476, 1.45)
s68 = openmc.Plane(-0.7071067811865475, 6.123233995736766e-17, 0.7071067811865476, -1.45)
s101 = openmc.YPlane(5.6, boundary_type='vacuum')

region = +s64 & -s101 & -s19 & +s48 & (+s58 | +s62 | -s64 | +s65 | -s68)
cell = openmc.Cell(region=region)

univ = openmc.Universe(cells=[cell])
geometry = openmc.Geometry(root=univ)
settings = openmc.Settings(particles=100, batches=100)
model = openmc.model.Model(geometry=geometry, settings=settings)
model.export_to_model_xml()

openmc.lib.init()
#print(cell.bounding_box)
py_lowerleft, py_upperright = cell.bounding_box
assert tuple(py_lowerleft) == (-17.7, -1.3, -17.7)
assert tuple(py_upperright) == (17.7, 5.6, 17.7)
#print(openmc.lib.cells[1].bounding_box)

cpp_lowerleft, cpp_upperright = openmc.lib.cells[1].bounding_box
assert tuple(cpp_lowerleft) == (-17.7, -inf, -17.7)
assert tuple(cpp_upperright) == (17.7, 5.6, 17.7)

openmc.lib.finalize()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. How is this topical to this PR?
  2. What value is this adding beyond those already in tests/unit_tests/test_bounding_box.py?
  3. Generally it's bad practice to have something that must always run to free resources (i.e., finalize) outside of a try... finally. with openmc.lib.run_in_memory(): is an option.
  4. Don't use == with a floating point for testing.

If you moved this to a separate PR I'd be ready to approve.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MicahGale sorry this is not relevant to this PR. This is one single part of a separate bug I'm working on. I do have a separate local branch called fix_2939 but.... somehow something got corrupted into my develop branch. I'll rebase and figure it out. Again, apologies

@caderache2014
Copy link
Contributor Author

@MicahGale approved? CI testing isn't done yet..... @paulromano @pshriwise thoughts?

@caderache2014
Copy link
Contributor Author

@paulromano did you have any notes? I think @MicahGale is satisfied...?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants