Skip to content

Made a metaclass for building surface classes from specifications to handle almost all surface types. #940

Open
MicahGale wants to merge 66 commits intodevelopfrom
meta_surfaces
Open

Made a metaclass for building surface classes from specifications to handle almost all surface types. #940
MicahGale wants to merge 66 commits intodevelopfrom
meta_surfaces

Conversation

@MicahGale
Copy link
Copy Markdown
Collaborator

@MicahGale MicahGale commented Mar 30, 2026

Pull Request Checklist for MontePy

Description

This project started as a fun weekend project of me asking copilot for a prototype. After seeing what it made I realized it was actually pretty straight forward, so I made the metaclass myself (mostly). Then I bugged Claude to write all of the specifications. This was partially an experiment in having AI as an unpaid intern.

This created a MetaClass _SurfaceClassFactory that can create a Surface class from a minimal specification. The specification is given by @dataclasses (I wanted to play around with them) that primarily specifies what each surface parameter/constant means. These specifications are then used to make new properties that are attached to the class (via namespace) prior to the class being created, since it is a MetaClass after all.

In the documentation I gave guidance that users should start using ZCylinder instead of CylinderOnAxis, but that the latter won't be deprecated. Is this reasonable guidance?

Fixes #502, fixes #935

Questions:

  1. should the one-letter variable parameters, e.g., z, a, etc., be lower or upper_case?

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: Copilot for prototyping. Claude (Sonnet 4.6) for actual implementation.
  • 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--940.org.readthedocs.build/en/940/

@MicahGale MicahGale requested a review from tjlaboss March 30, 2026 04:01
@MicahGale MicahGale self-assigned this Mar 30, 2026
@MicahGale MicahGale added code improvement A feature request that will improve the software and its maintainability, but be invisible to users. feature request An issue that improves the user interface. labels Mar 30, 2026
@MicahGale
Copy link
Copy Markdown
Collaborator Author

MicahGale commented Mar 30, 2026

TODO:

  • update the tutorial guide in the documentation
  • Check over all the documentation
  • Write it up in the developer guide
  • Remove references to surface types in limitations.
  • Fix coverage.
  • Fix CX, CY, CZ
  • Fix K/X, K/Y, K/Z
  • Fix TX, TY, TZ
    • how to handle +/-1?
  • link to sign from discussion of nappe on cones.

Copy link
Copy Markdown
Collaborator

@tjlaboss tjlaboss left a comment

Choose a reason for hiding this comment

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

Overall a useful PR that replaces a lot of verbose code with some much-needed abstraction. A few nitpicks, a few small questions, and one big question.

How do we want to handle the parameter surface_type going forward?

Example: Consider ZCylinder. In the current implementation, this is a CylinderOnAxis on the $z$-axis: a CZ and not a C/Z.

>>> ZCylinder(number=1).mcnp_str()
montepy.exceptions.IllegalState: Surface: 1 does not have a surface type set.

>>> ZCylinder(number=1, surface_type="C/Z").mcnp_str()
ValueError: ZCylinder must be a surface of type: ['CZ']

It seems that this should do one of the following:

  • Delete the parameter surface_type, since it must always be CZ.
  • Support C/Z as an acceptable surface_type
  • Delete the parameter surface_type, and set the attribute to CZ if no coordinates are specified, or else C/Z: like openmc.ZCylinder.

That does not have to be addressed in this PR, as the interface change might necessitate a major release. A followon issue should be opened if not addressed here.

@tjlaboss
Copy link
Copy Markdown
Collaborator

tjlaboss commented Apr 1, 2026

Should the one-letter variable parameters, e.g., z, a, etc., be lower or upper_case?

The MCNP manual uses both uppercase and lowercase letters, depending on the variable. An argument could be made that MontePy should follow this convention. All-lowercase letters is less confusing and more Pythonic.

image

@MicahGale
Copy link
Copy Markdown
Collaborator Author

How do we want to handle the parameter surface_type going forward?
...

My initial thought is that we restrict the accepted values for surface_type to those listed, which is already done via surf_type_validator. Then for cases when one type is accepted PZ <-> ZPlane this is just defaulted to. This would avoid ambiguity and unnecessary IllegalState

As for CZ v. C/Z this is currently two classes: ZCylinder and ZCylinderParAxis. Right now we have no way to go between the two, which I think is fine for now. In the future it would need to be figured out for #73.

As for surface_type in __init__ yeah I think we should delete.

I'm thinking:

  1. default to the correct surface type when safe to do so.
  2. For these cases load a different __init__ that drops the surface_type arg.

Sound good @tjlaboss?

@MicahGale
Copy link
Copy Markdown
Collaborator Author

The MCNP manual uses both uppercase and lowercase letters, depending on the variable. An argument could be made that MontePy should follow this convention. All-lowercase letters is less confusing and more Pythonic.

I like the idea of this. The one thought I had was: is using x confusing because it's double in use? Like the equation for an x-plane would be: $x-x=0$. In the manual they like bar, I'm not sure I like that. Maybe: x_0, (or x_bar).

@MicahGale
Copy link
Copy Markdown
Collaborator Author

I like the idea of this. The one thought I had was: is using x confusing because it's double in use? ...

I went ahead with keeping them as x in context it is clear enough, and easy to use. I did switch the equations to use x_0, etc. though.

@MicahGale MicahGale requested a review from tjlaboss April 1, 2026 16:17
@tjlaboss
Copy link
Copy Markdown
Collaborator

tjlaboss commented Apr 1, 2026

Sound good @tjlaboss?

yes.

@MicahGale MicahGale mentioned this pull request Apr 2, 2026
@MicahGale
Copy link
Copy Markdown
Collaborator Author

@tjlaboss I deprecated all of those classes now.

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

Labels

code improvement A feature request that will improve the software and its maintainability, but be invisible to users. feature request An issue that improves the user interface.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for all surface types Implement Tori

2 participants