Skip to content

Add HalfSpace.mcnp_str and format_for_mcnp_input - #1033

Open
SpaceOceanCorp wants to merge 8 commits into
idaholab:developfrom
SpaceOceanCorp:halfspace-mcnp-str
Open

SpaceOceanCorp wants to merge 8 commits into
idaholab:developfrom
SpaceOceanCorp:halfspace-mcnp-str

Conversation

@SpaceOceanCorp

@SpaceOceanCorp SpaceOceanCorp commented Oct 31, 2026 •

Copy link
Copy Markdown

Pull Request Checklist for MontePy

Description

cell.geometry.mcnp_str() now prints just the geometry as it appears in the cell card, e.g. -123 234 for 1 0 -123 234 imp:n=1 u=2. HalfSpace.format_for_mcnp_input() returns the wrapped lines, so long geometries split the same way as any other input. Without an explicit version, mcnp_str() uses the version of the problem the geometry's cell belongs to, then montepy.MCNP_VERSION.

Cell.format_for_mcnp_input() still formats the geometry through the cell's syntax tree. Calling the new method from there would wrap the geometry lines a second time, so I left the cell path unchanged. Happy to restructure if you prefer that.

Tests cover parsed geometries (intersections, unions, groups, complements), geometry built from surfaces with & and |, a cell whose geometry is replaced, and line wrapping. Changelog entry added under Next Version.

Fixes #942


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 Opus 5.5
    • Harness used: Claude Code
    • Reasoning effort: high
  • No

Documentation Checklist

  • I have documented all added classes and methods.
  • I have added type hints to all functions as needed.
  • I have marked all changes with the .. versionchanged:: or .. versionadded:: directives.

Infrastructure Changes

  • For infrastructure updates, I have updated the developer's guide.

N/A, no infrastructure changes.

Significant features or Behavior changes

  • For significant new features, I have added a section to the getting started guide.

N/A, small API addition; the method docstring has a doctest example.


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--1033.org.readthedocs.build/en/1033/

Print just a cell's geometry as it appears in the MCNP input, e.g. cell.geometry.mcnp_str() -> '-123 234'. The version defaults to the linked cell's problem, then montepy.MCNP_VERSION. Long geometries wrap like any other input.
@MicahGale

MicahGale commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

Closed for not using the PR template; you can re-open this if the description is updated to use the template.

@MicahGale MicahGale closed this Oct 31, 2026
@SpaceOceanCorp

Copy link
Copy Markdown
Author

@MicahGale Thanks, I've updated the description to use the PR template. GitHub won't let me reopen it since a maintainer closed it, so could you reopen it when you get a chance? The branch is unchanged.

@MicahGale MicahGale reopened this Nov 1, 2026
Put the testcode block in the default group so its testoutput is
checked, and use a literal for montepy.MCNP_VERSION, which has no
Sphinx target.
@MicahGale MicahGale added the feature request An issue that improves the user interface. label Nov 1, 2026

@MicahGale MicahGale left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The code looks good. However, it introduces a new uncovered line: https://coveralls.io/jobs/190688554

Covers the branch that takes the default version from the cell's
problem, which coveralls reported as uncovered.
@SpaceOceanCorp

Copy link
Copy Markdown
Author

Thanks. The uncovered line was the branch in mcnp_str that takes the version from the cell's problem. I added test_halfspace_mcnp_str_uses_problem_version, which wraps a long geometry at 80 characters for a 6.1.0 problem and at 128 for 6.3.0. Local coverage now reports that line as hit, and the test fails if the branch is changed to ignore the problem.

One limit I found while writing it: a cell made with montepy.Cell("...") and then appended to a problem keeps geometry._cell as None, because that link is only set by update_pointers or by assigning cell.geometry. Its mcnp_str() therefore uses montepy.MCNP_VERSION rather than the problem's version. Cells from read_input and cells with an assigned geometry do use the problem's version. I left that as it is, since it comes from how the link is set today, but I can narrow the docstring if you prefer.

@MicahGale

Copy link
Copy Markdown
Collaborator

One limit I found while writing it: a cell made with montepy.Cell("...") and then appended to a problem keeps geometry._cell as None, because that link is only set by update_pointers or by assigning cell.geometry. Its mcnp_str() therefore uses montepy.MCNP_VERSION rather than the problem's version. Cells from read_input and cells with an assigned geometry do use the problem's version. I left that as it is, since it comes from how the link is set today, but I can narrow the docstring if you prefer.

This sounds like a bug, and why don't you investigate if the link needs to be made when using the geometry setter.

MicahGale and others added 2 commits November 2, 2026 15:51
The geometry setter only linked the root node, parsed cells were not
linked at all, and clones kept a link to a deep copy of the original
cell. So HalfSpace.replace and the divider setter could skip
Cell.surfaces, replace could raise KeyError on a clone, and mcnp_str
could ignore the version of the cell's problem.

Add HalfSpace._link_to_cell, which links every node without resolving
dividers, and use it in the setter and _parse_geometry. Seed the
deepcopy memo in Cell.clone with the new cell.
@SpaceOceanCorp

Copy link
Copy Markdown
Author

I looked into it, and you're right that it's a bug. The setter does make the link, but only on the root node, so the leaves keep _cell = None. That means replace() and the divider setter skip cell.surfaces after cell.geometry = .... A surface swapped in before the cell is appended never reaches problem.surfaces, while the geometry still references it. There are two related gaps: _parse_geometry sets no link at all, and clone() leaves the geometry pointing at a deep copy of the original cell, so replace() on a clone of a read_input cell raises KeyError.

The setter can't be used from _parse_geometry because it raises IllegalState on unresolved dividers. So I added HalfSpace._link_to_cell, which links the whole tree without touching dividers, and call it from both places. clone() now seeds its deepcopy memo with the new cell. There are six new tests, which fail without the change, and Cell("...") appended to a problem now uses that problem's version in mcnp_str().

Two related things I left alone: reassigning cell.geometry leaves old surfaces in cell.surfaces, and replace() on a cell already in a problem does not add the new surface to problem.surfaces. I can open an issue for those if you'd like.

Separately, test_multiply_fortran_floats failed locally on the example 0000.00m, which lexes as ZAID rather than NUM_MULTIPLY. It came in with the develop merge and doesn't touch this change, so it may show up as an occasional Hypothesis failure.

@MicahGale

Copy link
Copy Markdown
Collaborator

This linking bug is significant enough that we should document it in an issue as well.

@MicahGale

Copy link
Copy Markdown
Collaborator

Actually could you cherry-pick the bug fix into it's own branch? I want to split this into to separate PRs: one for the bug, and the other for the feature.

@EmbryoSpace

Copy link
Copy Markdown

Will do next week.

@SpaceOceanCorp

Copy link
Copy Markdown
Author

Filed as #1054, and the fix is now in its own PR, #1055, as you asked. It also covers the two related problems I had left alone, and the left and right setters. I'll take the fix out of this branch next.

As requested in review, the bug fix is now in idaholab#1055, so this pull
request only adds the feature. This reverts f493a2f.
@SpaceOceanCorp

Copy link
Copy Markdown
Author

55a199f takes the link fix out of this branch, so this PR now only adds HalfSpace.mcnp_str and format_for_mcnp_input. That also removes test_halfspace_mcnp_str_parsed_cell_uses_problem_version, since a parsed cell only has the link with #1055. Until that merges, mcnp_str() on a Cell("...") falls back to montepy.MCNP_VERSION. I can add that test back once it does.

This branch has not been deployed

No deployments
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.

Implement HalfSpace.mcnp_str() and HalfSpace.format_for_mcnp_input()

3 participants