Skip to content

Allow editing cell geometry definition#945

Open
digvijay-y wants to merge 11 commits intoidaholab:developfrom
digvijay-y:geometry-editing
Open

Allow editing cell geometry definition#945
digvijay-y wants to merge 11 commits intoidaholab:developfrom
digvijay-y:geometry-editing

Conversation

@digvijay-y
Copy link
Copy Markdown
Collaborator

@digvijay-y digvijay-y commented Apr 13, 2026

Pull Request Checklist for MontePy

Description

  • Add iter to HalfSpace and unit Halfspace
  • Add replace() to HalfSpace
  • Add _replace_recursive() to both classes
  • Add TestCases

Fixes #737


General Checklist

  • I have performed a self-review of my own code.
  • The code follows the standards outlined in the development documentation.
  • I have formatted my code with black version 25 or 26.
  • I have added tests that prove my fix is effective or that my feature works (if applicable).

LLM Disclosure

  1. Are you?

    • A human user
    • A large language model (LLM), including ones acting on behalf of a human
  2. Were any large language models (LLM or "AI") used in to generate any of this code?

  • Yes
    • Model(s) used: Claude sonnet 4.5 (anthropic) - Built Test cases.
  • No

Documentation Checklist

  • I have documented all added classes and methods.
  • For infrastructure updates, I have updated the developer's guide.
  • For significant new features, I have added a section to the getting started guide.

First-Time Contributor Checklist

  • If this is your first contribution, add yourself to pyproject.toml if you wish to do so.

Additional Notes for Reviewers

Ensure that:

  • This PR fully addresses and resolves the referenced issue(s).
  • The submitted code is consistent with the merge checklist outlined here.
  • The PR covers all relevant aspects according to the development guidelines.
  • 100% coverage of the patch is achieved, or justification for a variance is given.

📚 Documentation preview 📚: https://montepy--945.org.readthedocs.build/en/945/

@digvijay-y digvijay-y added the feature request An issue that improves the user interface. label Apr 25, 2026
…dd Test Cases

Signed-off-by: DIGVIJAY <144053736+digvijay-y@users.noreply.github.com>
@digvijay-y digvijay-y marked this pull request as ready for review April 26, 2026 03:53
Copilot AI review requested due to automatic review settings April 26, 2026 03:53
@digvijay-y digvijay-y self-assigned this Apr 26, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds user-facing utilities to traverse and edit a cell’s CSG geometry tree, addressing #737 by enabling divider replacement and leaf iteration.

Changes:

  • Added HalfSpace.replace() / _replace_recursive() to swap Surface/Cell dividers throughout a geometry tree.
  • Added __iter__ to HalfSpace and UnitHalfSpace for depth-first leaf traversal.
  • Added unit tests plus minor documentation/demo formatting updates.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
montepy/surfaces/half_space.py Implements replace() and iteration over geometry leaves; adjusts duplicate-surface remapping logic.
tests/test_geometry.py Adds test coverage for replace() and __iter__.
doc/source/changelog.rst Documents the new feature (but currently has RST formatting issues).
doc/source/conf.py Removes trailing whitespace in nitpick_ignore.
demo/_config.py Minor formatting (blank line).
demo/1_fusion_radial_build.ipynb Minor formatting fix (newline).
demo/answers/1_fusion_radial_build.ipynb Formatting cleanup in example code cells.

Comment thread montepy/surfaces/half_space.py Outdated
Comment thread doc/source/changelog.rst
Next Release
============

**Features Added**
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

The new "Next Release" section has a bullet list immediately following **Features Added** without a blank line. reStructuredText generally requires a blank line before lists; without it, Sphinx/docutils can emit warnings (and CI treats warnings as errors). Add a blank line between the bold heading and the * list to avoid doc build failures.

Suggested change
**Features Added**
**Features Added**

Copilot uses AI. Check for mistakes.
Comment thread doc/source/changelog.rst
Comment on lines +291 to +307
replaced = self._replace_recursive(old_divider, new_divider)
if not replaced:
raise ValueError(
f"{old_divider} (number: {old_divider.number}) not found in geometry tree."
)
# _cell is only set on UnitHalfSpace leaves, not on internal HalfSpace nodes.
# Find the parent cell via any leaf and remove the old divider from its collection.
for leaf in self:
if leaf._cell is not None:
container = (
leaf._cell.complements
if isinstance(old_divider, montepy.Cell)
else leaf._cell.surfaces
)
if old_divider in container:
container.remove(old_divider)
break
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

HalfSpace.replace() will remove old_divider from the parent cell container even when old_divider is new_divider (a no-op replacement). In that case the geometry still references the divider but it gets removed from cell.surfaces/cell.complements, leaving the cell’s containers inconsistent. Add an early-return when old_divider is new_divider, or at least skip the container cleanup in that case.

Copilot uses AI. Check for mistakes.
digvijay-y and others added 2 commits April 26, 2026 03:59
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 26, 2026 04:00
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Comment on lines +250 to +254
def replace(
self,
old_divider: montepy.surfaces.surface.Surface | montepy.Cell,
new_divider: montepy.surfaces.surface.Surface | montepy.Cell,
) -> None:
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

replace() is documented and typed to support swapping either Surface dividers or Cell complements, but the added tests cover only surface replacement. Add at least one test that replaces a complemented Cell divider and asserts both the geometry leaves and cell.complements are updated correctly (including removal of the old cell).

Copilot generated this review using guidance from repository custom instructions.
Comment thread doc/source/changelog.rst Outdated
Comment on lines +291 to +295
replaced = self._replace_recursive(old_divider, new_divider)
if not replaced:
raise ValueError(
f"{old_divider} (number: {old_divider.number}) not found in geometry tree."
)
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

replace() can be called with the same object for both arguments (old_divider is new_divider). In that case _replace_recursive() will report success, but the cleanup loop later will still remove old_divider from the parent cell’s surfaces/complements, leaving the geometry referencing a divider that is no longer in the cell collection. Add an early return/no-op when old_divider is new_divider (or skip container removal in that case).

Copilot uses AI. Check for mistakes.
Comment on lines +272 to +283
if not isinstance(
old_divider, (montepy.surfaces.surface.Surface, montepy.Cell)
):
raise TypeError(
f"old_divider must be a Surface or Cell. {old_divider} given."
)
if not isinstance(
new_divider, (montepy.surfaces.surface.Surface, montepy.Cell)
):
raise TypeError(
f"new_divider must be a Surface or Cell. {new_divider} given."
)
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

replace() currently assumes the geometry tree has been linked via update_pointers() (i.e., leaf dividers are Surface/Cell objects). If the tree still contains integer dividers from parsing, _replace_recursive() will fail to match and this raises a misleading ValueError (“not found”). Consider explicitly validating the tree is initialized (e.g., by calling _get_leaf_objects() up front, or checking for Integral dividers) and raising IllegalState with the existing “Run Cell.update_pointers” guidance instead.

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 26, 2026 04:05
@digvijay-y digvijay-y requested review from MicahGale and removed request for Copilot April 26, 2026 04:06
@MicahGale
Copy link
Copy Markdown
Collaborator

@digvijay-y thanks for doing this. It will be a few days before I will be able to review this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature request An issue that improves the user interface.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow editing cell geometry definition

3 participants