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

Cleanup group handling and make many functions into properties #17

Merged
merged 14 commits into from
Apr 8, 2024

Conversation

gonuke
Copy link
Member

@gonuke gonuke commented Mar 30, 2024

Improve group handling to ensure that duplicate groups with the same name are never created.

Keep a cache of Surface/Volume/Group ids to ensure that we don't reuse an ID already in use.

Makes many getter functions into properties and updates their calls.

Closes #12
Closes #15

@gonuke gonuke changed the title Make many functions into properties Cleanup group handling and make many functions into properties Mar 31, 2024
@gonuke gonuke marked this pull request as ready for review March 31, 2024 19:51
@gonuke gonuke requested a review from pshriwise March 31, 2024 19:51
dagmc/dagnav.py Outdated
Comment on lines 22 to 24
self.used_ids[Surface._geom_dimension] = set(self.surfaces_by_id.keys())
self.used_ids[Volume._geom_dimension] = set(self.volumes_by_id.keys())
self.used_ids[Group._geom_dimension] = set(group.id for group in self.groups.values())
Copy link
Member

Choose a reason for hiding this comment

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

Small thing, but using the types themselves as the keys here will insulate us from any changes to properties of the types down the line:

Suggested change
self.used_ids[Surface._geom_dimension] = set(self.surfaces_by_id.keys())
self.used_ids[Volume._geom_dimension] = set(self.volumes_by_id.keys())
self.used_ids[Group._geom_dimension] = set(group.id for group in self.groups.values())
self.used_ids[Surface] = set(self.surfaces_by_id.keys())
self.used_ids[Volume] = set(self.volumes_by_id.keys())
self.used_ids[Group] = set(group.id for group in self.groups.values())

Other changes may be required elsewhere to comply with this change.

dagmc/dagnav.py Outdated

@property
def volumes_by_id(self):
return {v.id: v for v in self.volumes}

@property
def groups(self) -> Dict[str, Group]:
Copy link
Member

Choose a reason for hiding this comment

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

Along the lines of the discussion in #12, to be consistent with the volumes and surfaces properties this should probably return a list of Group instances and we can add a another method called groups_by_name to get the name --> Group instance mapping.

dagmc/dagnav.py Outdated
@@ -198,6 +214,12 @@ def id(self) -> int:
@id.setter
def id(self, i: int):
"""Set the DAGMC set's ID."""
if i in self.model.used_ids[self.geom_dimension]:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if i in self.model.used_ids[self.geom_dimension]:
if i in self.model.used_ids[type(self)]:

dagmc/dagnav.py Outdated
if i in self.model.used_ids[self.geom_dimension]:
raise ValueError(f'{self.category} ID {i} is already in use in this model.')
else:
self.model.used_ids[self.geom_dimension].discard(self.id)
Copy link
Member

Choose a reason for hiding this comment

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

Didn't know about this set method. Nice!

dagmc/dagnav.py Outdated
@@ -420,53 +446,54 @@ def groups(self) -> list[Group]:
"""Get list of groups containing this volume."""
return [group for group in self.model.groups.values() if self in group]

def _material_group(self):
for group in self.groups:
if self in group and group.name.startswith("mat:"):
Copy link
Member

Choose a reason for hiding this comment

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

A couple of updates here.

  • The Volume.groups property already asserts that the volume is contained in the gruops, no need to recheck it here.
  • Double check me on this maybe, but I believe that our group name properties aren't required to be in a specific order, so as long as the keyword mat: appears somewhere in the group name it indicates a material assignment group.
Suggested change
if self in group and group.name.startswith("mat:"):
if 'mat:' in group.name:

return group.name[4:]
group = self._material_group
if group is not None:
return group.name[4:]
Copy link
Member

Choose a reason for hiding this comment

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

Along the lines of the comment above, we might require some more sophisticated parsing here if the material assignment doesn't come first in the group name. This is a pre-existing issue though, so I'll note it and we can clean it up in a subsequent PR.


@property
def volume(self):
"""Returns the volume of the volume"""
volume = 0.0
for surface in self.get_surfaces().values():
for surface in self.surfaces:
Copy link
Member

Choose a reason for hiding this comment

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

A nice simplification as a result of the conversation in #12 :)

@@ -500,6 +527,9 @@ def name(self) -> Optional[str]:

@name.setter
def name(self, val: str):
if val.lower() in self.model.group_names:
Copy link
Member

Choose a reason for hiding this comment

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

The suggestion above about adding a DAGModel.groups_by_name method might change how this is approacched.

Copy link
Member Author

Choose a reason for hiding this comment

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

I left this method in since it is slightly cleaner than requesting by name and then taking only the keys.

or return an existing group if one exists."""

# return existing group if one exists with this name
if name is not None:
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure what to do with Group IDs. Part of me thinks we should notify if the group_id paramter is set and it doesn't match the returned Group.id if the group already exists. Functionally, the Group IDs really don't matter to DAGMC, but it still makes them complete in the eyes of MOAB. Thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

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

I was on the fence about this, too. I'm happy to add it - it's pretty easy. I'll see what others have to say....

Copy link
Member

@pshriwise pshriwise left a comment

Choose a reason for hiding this comment

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

Thanks for tackling these updates @gonuke! Some minor thoughts on method purposes and line notes here.

Copy link
Member

@pshriwise pshriwise left a comment

Choose a reason for hiding this comment

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

Thank you for these design updates @gonuke!

@pshriwise pshriwise merged commit 7ecdd45 into svalinn:main Apr 8, 2024
1 check passed
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.

Confirm safety of setting global ID Make get_* methods properties
2 participants