Skip to content

Refactoring moltres_xs to be able to use mgxs.Library() functionality. #340

Open
Jeremyb8707bigbrain wants to merge 22 commits intoarfc:develfrom
Jeremyb8707bigbrain:devel
Open

Refactoring moltres_xs to be able to use mgxs.Library() functionality. #340
Jeremyb8707bigbrain wants to merge 22 commits intoarfc:develfrom
Jeremyb8707bigbrain:devel

Conversation

@Jeremyb8707bigbrain
Copy link

@Jeremyb8707bigbrain Jeremyb8707bigbrain commented Feb 2, 2026

Summary of changes

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Required for Merging

  • I have read the CONTRIBUTING document.
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
    • CI tests pass
    • Local tests pass (including Serpent2 integration tests)

Associated Issues and PRs

Associated Developers

Checklist for Reviewers

Reviewers should use this link to get to the
Review Checklist before they begin their review.

@Jeremyb8707bigbrain
Copy link
Author

Jeremyb8707bigbrain commented Feb 2, 2026

Hey everyone,

I ran local tests myself for the godiva.json files, mostly everything lines up like it should.
The main issue is my cross sections that I had myself only are 6 delayed groups, and I really dont know how to get the 8 that godiva.json used.

Another discrepancy that may be noted is the version, I am on OpenMC version 0.15.2 so the numbers are within std. dev, but for the smaller values it had a bit more range.

99% of everything works as it should, and I plan to add support for multiple statepoints and summaries soon. I added the openmc_mgxslib class so even if it is not 100% it can be added (maybe).

Also I forgot to say, this one does not require an input file that specifies energy groups delayed etc, that all comes with a properly configured mgxs.Library(). Also I am working on ordering the files consistently in the.json.

…ned up spacing, extra lines, and more type checking and error catching.
…. Tweaked division by zero handling to be more readable and less complex.
… added back the consistent nu-scatter matrix requirement because I was testing stuff and forgot to add that back.
…sted the consistent nu-scatter matrix processing to allow all legendre_order types.
@smpark7
Copy link
Collaborator

smpark7 commented Feb 6, 2026

Hey @Jeremyb8707bigbrain thanks again for working on this PR. I have been very busy, but I have some general feedback:

  • Your code should replace the existing class openmc_xs, not create a new class.
  • The new version should maintain compatibility with the existing workflow for group constant generation for backward compatibility and user-friendliness. Current workflow:
    • Use openmc_xs.generate_openmc_tallies_xml to configure tallies (currently through individual mgxs tallies, to be migrated to mgxs.Library())
    • Run OpenMC, potentially at multiple reactor temperatures
    • Run $MOLTRES/python/moltres_xs.py input.inp to parse and generate json group constant file.
  • It should continue to have the openmc_xs.generate_openmc_tallies_xml function that helps beginner users automatically configure mgxs.Library() such that the generated group constants are compatible with the neutronics solvers in Moltres. Advanced users can choose to ignore this function and configure mgxs.Library() in their own way if they wish.
  • It should be compatible with the existing approach of using .inp files for users to specify which material group constants and temperature values they want.
  • You'll find how totalxs and nuscattermatrix group constants are extracted in moltres_xs.py for the new SN solver in Moltres.
  • You're missing remxs values that are needed by the neutron diffusion solver.
  • If possible, the mgxs.Library() configuration settings should be compatible with OpenMC mgxs generation for its own multigroup solver (https://nbviewer.org/github/openmc-dev/openmc-notebooks/blob/main/mg-mode-part-ii.ipynb). This would avoid having duplicate mgxs tallies that would otherwise significantly increase OpenMC simulation time.

@Jeremyb8707bigbrain
Copy link
Author

Perfect I can do all of that!
I will put another comment when I would like it to be reviewed, for now I will start working on that feedback!

Jeremyb8707bigbrain and others added 2 commits February 7, 2026 10:27
Changed main openmc (0.15.3) calls to run new function rather than the old one, added a way to manually build old case logic via inputs and inspecting python file for the mgxs.Library
Added better logging for errors at mgxslib.load_from_statepoints....
Adapted it so that it will correctly use burn_idexes to comply with read_input() formatting.
Set generate_openmc_talies_xml as a staticmethod explicitly
@Jeremyb8707bigbrain Jeremyb8707bigbrain marked this pull request as draft February 8, 2026 23:00
@Jeremyb8707bigbrain Jeremyb8707bigbrain marked this pull request as ready for review February 9, 2026 19:14
@Jeremyb8707bigbrain
Copy link
Author

Jeremyb8707bigbrain commented Feb 9, 2026

Hey @smpark7, everything for the most part is in order!

I kept the openmc_xs class still available just in case you wanted to mark it for deprecation so users know that they will need to change their parameters slightly.

I have a few questions, did you want me to include the SPN calculation? I can easily (I hope) include that I was just wondering if you would like me to. I also added TOTXS which is not present in the reference godiva.json file, but I see it in the code, would you like me to keep that or remove it? Last question, for your suggestion of having the mgxs.Library() be compatible with OpenMC's own multigroup mode, it would require an additional tally (Absorption), would you like me to add that and add the OpenMC Function check_library_for_openmc_mgxs() to the process_mgxslib() function to ensure advanced users must also meet that requirement?

I did a few tests with multiple statepoints and summaries, here are the results, again I do not have access to all 8 delayed groups so some areas will be off very slightly.

If you have any other concerns or questions please reach out! I also credit my research partner @rafainn for help with the input file work, very helpful!

Example Python File: (I again dont have the cross sections at 900K or 1200K so I made them myself, which means sadly only 6 delayed groups)

import openmc
import sys
sys.path.insert(1,"/moltres_test/moltres_xs-Refactor-MGXS/python/")
from moltres_xs import openmc_mgxslib

fuel_mat = openmc.Material(name='fuel', material_id=1)
fuel_mat.set_density('atom/b-cm', 4.7984E-02)
fuel_mat.temperature = 900
fuel_mat.add_nuclide("U235", 4.4994E-02, percent_type='ao')
fuel_mat.add_nuclide("U238", 2.4984E-03, percent_type='ao')
fuel_mat.add_nuclide("U234", 4.9184E-04, percent_type='ao')

mats = openmc.Materials([fuel_mat])
mats.cross_sections = "/workspace/moltensaltsim/Material_Data/OpenMC_XMLs/cross_sections_godiva.xml"
mats.export_to_xml()

sph = openmc.Sphere(r=8.7407, boundary_type='vacuum')

fuel_core = openmc.Cell(fill=fuel_mat, region=-sph)

geom = openmc.Geometry([fuel_core])
geom.export_to_xml()

settings = openmc.Settings()
settings.batches = 100
settings.inactive = 20
settings.particles = 50000
settings.temperature = {"multipole": True, "method": "interpolation"}
point = openmc.stats.Point((0, 0, 0))
src = openmc.IndependentSource(space=point) # Source was deprecated and it said that IndependentSource was preferred.
settings.source = src
settings.export_to_xml()

tallies = openmc.Tallies()
mgxs_library = openmc_mgxslib.generate_openmc_tallies_xml([1e-5, 748.5, 5.5308e3, 24.7875e3, 0.4979e6, 2.2313e6, 20e6], 6, [fuel_mat], geom, tallies)

#openmc.run() # Used before the input parsing

Input File:

[TITLE]
  godiva_openmc.json

[MAT]
  1
  fuel_mat

[BRANCH]
  2
  fuel_mat            900 1 1 1 1
  fuel_mat            1200 2 1 1 1

[FILES]
  2
  statepoint.900.h5  openmc godiva_openmc_900.py summary.900.h5
  statepoint.1200.h5  openmc godiva_openmc_1200.py summary.1200.h5

Output:

{
  "fuel_mat": {
      "1200": {
          "BETA_EFF": [
              0.0013479328874237927,
              0.006967492815569392,
              0.006662378531992382,
              0.014980452683184708,
              0.006185780669768732,
              0.0025887417681020298
          ],
          "CHI_D": [
              0.004809526109315934,
              0.38523354014508626,
              0.5815938982198151,
              0.02705814752389195,
              0.001287967194123611,
              1.6920807767085327e-05
          ],
          "CHI_P": [
              0.35204067796316474,
              0.5198257797155467,
              0.12648480548441765,
              0.0014890020136668451,
              0.00015066478799014937,
              8.817408027798893e-06
          ],
          "CHI_T": [
              0.34979280230108517,
              0.5190903735269962,
              0.1293235561075548,
              0.0016233017887243154,
              0.00016070460416726674,
              9.01067875604564e-06
          ],
          "DECAY_CONSTANT": [
              0.013336176998594657,
              0.0327254618353869,
              0.12082517735113926,
              0.3032033227763606,
              0.8513219627189227,
              2.8585311502702324
          ],
          "DIFFCOEF": [
              1.6182274998401185,
              1.3642728170826015,
              0.8320405266913466,
              0.47149354286848477,
              0.37859622913474406,
              0.24662342775124388
          ],
          "FISSE": [
              193.4961292932816,
              193.4201252841644,
              193.40357471688122,
              193.4053366134499,
              193.40537155138682,
              193.40490127356847
          ],
          "FISSXS": [
              0.05681875825825768,
              0.05459421736631732,
              0.05989063772559673,
              0.11294273814778086,
              0.21003655994907477,
              0.5462213108029339
          ],
          "GTRANSFXS": [
              0.22297533231163758,
              0.06473700684651243,
              0.025494746342081185,
              0.00012158922962522632,
              1.7835373598058595e-05,
              1.7149397690440947e-06,
              0.0,
              0.24890051397716456,
              0.037612649690256794,
              0.00016779278544005614,
              1.3686567897544017e-05,
              1.1342459583600008e-06,
              0.0,
              0.0,
              0.4182846249650026,
              0.0005928935677351931,
              2.807852088832213e-05,
              6.239671308516024e-07,
              0.0,
              0.0,
              0.0,
              0.5611416177989257,
              0.0004900411079539684,
              0.0,
              0.0,
              0.0,
              0.0,
              0.0,
              0.5978057420724365,
              0.00029062019546545275,
              0.0,
              0.0,
              0.0,
              0.0,
              0.0,
              0.596995317950723
          ],
          "NSF": [
              0.1640887563798374,
              0.13935790334891593,
              0.1475426911619574,
              0.27305712757940975,
              0.5094169312840311,
              1.3270890801602042
          ],
          "RECIPVEL": [
              3.907802458936875e-10,
              7.172622496270246e-10,
              1.5763527517103987e-09,
              5.78055071193088e-09,
              1.2647622630278322e-08,
              3.541697580573283e-08
          ],
          "REMXS": [
              0.14636069574186267,
              0.03258761538964927,
              0.010312236818636855,
              0.1549538266064593,
              0.2923357653247477,
              0.7945967414514843
          ],
          "TOTXS": [
              0.36933602805350024,
              0.3462251362133263,
              0.49170425781597743,
              0.7169777199881855,
              0.8906911489675221,
              1.391886152750531
          ]
      },
      "900": {
          "BETA_EFF": [
              0.0013477713361262679,
              0.0069667815244903765,
              0.006661711171558475,
              0.014978986450907898,
              0.006185223565016153,
              0.0025885180877550065
          ],
          "CHI_D": [
              0.004816108092933141,
              0.38402391400673824,
              0.5856802013789721,
              0.02386435661906883,
              0.0015985756139615993,
              1.6844288325974322e-05
          ],
          "CHI_P": [
              0.3519712083405351,
              0.5196815853363649,
              0.12668408955805868,
              0.0014885401949253701,
              0.00016500443737073363,
              9.572132698102343e-06
          ],
          "CHI_T": [
              0.34973414403563124,
              0.518934845488141,
              0.1295304380302617,
              0.001614356008810987,
              0.0001764556951631939,
              9.76074194393403e-06
          ],
          "DECAY_CONSTANT": [
              0.013336178367893413,
              0.03272544257848398,
              0.12082523103059183,
              0.30320384982572396,
              0.8513242055280581,
              2.8585382538647544
          ],
          "DIFFCOEF": [
              1.6173834566424388,
              1.3649771588306194,
              0.832532085680547,
              0.4703894981397496,
              0.37537053465658565,
              0.2466560322416023
          ],
          "FISSE": [
              193.49611687720707,
              193.42016116893532,
              193.4035711786227,
              193.40533535036857,
              193.40537484654888,
              193.40528883089382
          ],
          "FISSXS": [
              0.056824395601165534,
              0.054599320358540586,
              0.059874071674284796,
              0.1133143820087574,
              0.20895953468659575,
              0.5505401846941079
          ],
          "GTRANSFXS": [
              0.2228272763898503,
              0.06487676994616874,
              0.0255169429779392,
              0.00012301955320388736,
              1.713364250750522e-05,
              2.741382801200833e-06,
              0.0,
              0.24901044262918903,
              0.03747253621834822,
              0.0001626484510271523,
              1.550834053147492e-05,
              8.321548577864581e-07,
              0.0,
              0.0,
              0.41817719524685815,
              0.0005780702327768786,
              2.6275919671676323e-05,
              6.256171350399119e-07,
              0.0,
              0.0,
              0.0,
              0.5614697598556467,
              0.00047028079639904497,
              0.0,
              0.0,
              0.0,
              0.0,
              0.0,
              0.5955691163233789,
              0.0,
              0.0,
              0.0,
              0.0,
              0.0,
              0.0,
              0.5651209691677761
          ],
          "NSF": [
              0.16409209454954332,
              0.1393737082256517,
              0.14750442373233597,
              0.2739559869142277,
              0.5068196900715216,
              1.3383945829450208
          ],
          "RECIPVEL": [
              3.9087078730945797e-10,
              7.170785092953576e-10,
              1.5751041684526634e-09,
              5.792145962218262e-09,
              1.2766578207104842e-08,
              3.893844194513065e-08
          ],
          "REMXS": [
              0.1465241546944975,
              0.03230783902029771,
              0.010384167333425842,
              0.15546259631531867,
              0.28971530681046687,
              0.8187096717946637
          ],
          "TOTXS": [
              0.3693514310843478,
              0.3461950515956555,
              0.4915508417765714,
              0.7177960944079733,
              0.8858136218329555,
              1.3838348401172338
          ]
      },
      "temp": [
          900,
          1200
      ]
  }
}

I did another test with a different material, and same temperature and it worked as it should.

importing where required rather than global to save compute for non-openmc based input functions
Changed add_to_tallies_file to the newest non-deprecated version
@rafainn
Copy link

rafainn commented Feb 9, 2026

Compatible until openMC 0.15.3 - since not mentioned explicitly elsewhere.

@smpark7
Copy link
Collaborator

smpark7 commented Feb 9, 2026

Thanks @rafainn for also contributing to this PR. Yes SPN and TOTXS should be included. They're missing in the godiva files because the godiva test case was created before SPN and TOTXS were required for the new SN solver. (You can use this 1-D MSRE test case for an example that generates SPN and TOTXS)

I see now that there are some incompatibilities between Moltres and multigroup OpenMC (OpenMC-MG) regarding required group constants:

  • As you mentioned, OpenMC-MG requires absorption XS while Moltres uses removal XS. We originally used Serpent which provided removal XS directly. When we adopted OpenMC, we chose to continue using removal XS.
  • Moltres wants ScatterMatrixXS with nu=True but the default is nu = False. This may be why OpenMC gave tally merging errors when I tried to have it generate group constants for both Moltres and OpenMC-MG with mgxs_lib.add_to_tallies_file(tallies, merge=True) after running generate_openmc_tallies_xml(...).

One solution may be to stick with group constants that Moltres requires (as you have done) and let advanced users who want to use the same library for multigroup OpenMC add absorption, nu-scatter matrix, and multiplicity matrix.

I think you need the JEFF cross section library to get 8 delayed groups, but that's not a big deal.

…t becomes deprecated in a future update, because no version other than latest has that new name, and it still works with the latest version.
… for advanced users to match moltres input-file generated list.
@Jeremyb8707bigbrain
Copy link
Author

@smpark7 I got the SPN Stuff down, adding new constants is quite easy with the library method.
Is there anything else you need us to do?

@smpark7
Copy link
Collaborator

smpark7 commented Feb 17, 2026

Thanks! I hope to have time next week to review this in detail.

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.

3 participants