openmc-dev / openmc

OpenMC Monte Carlo Code
https://docs.openmc.org
Other
745 stars 480 forks source link

Always write tally spec for writable tallies, even if not active #2762

Open pshriwise opened 10 months ago

pshriwise commented 10 months ago

Description

We currently only write tallies to a statepoint file if they're marked as active and writable. Relevant lines filtering out non-writeable, non-active tallies are here

https://github.com/openmc-dev/openmc/blob/bd1c2286f8b569bfc863a3da3c67894dcc22df62/src/state_point.cpp#L924-L929

I'm proposing here that we always write the tally specification if it's marked as writable, but not active. In the normal control flow of OpenMC this means the results are zero and I'll propose that for tallies that are writable but not active we write only the spec and not the results so we don't write a bunch of zeros to the statepoint file.

This would enable one to write tallies created programmatically with openmc.lib or C++ to the statepoint with the following lines:

import openmc.deplete
import openmc.lib

# create model
...

# initial tally setup from depletion (could also happen as part of a Cardinal/ENRICO initialization)
op = openmc.deplete.CoupledOperator(model, 'my_chain.xml')
op.inital_condition()

# this step is not always necessary
for t in openmc.lib.tallies.values():
    t.writable = True

openmc.lib.simulation_init()
openmc.lib.statepoint_write('my_statepoint.h5')

And then write them to XML with

import openmc
sp = openmc.StatePoint('my_statepoint.h5')

tallies = openmc.Tallies(list(sp.tallies.values()))
tallies.export_to_xml()

My motivation for this is to capture internally generated tallies from the depletion module or Cardinal/ENRICO in an XML file to execute a single transport step. It would be nice to be able to do this without needing to execute a run/timestep first.

It is also useful when extending tallies. For example in Cardinal we'd like to include depletion tallies in the Cardinal execution to incorporate multiphysics effects in depletion, but we need to run the depletion module independent of Cardinal due to the depletion runs being driven by openmc.lib, so we'd like to generate a tallies.xml file and have Cardinal add it's internal multiphysics tallies in addition to those and hand them to the depletion run alongside Cardinal with an in-memory transfer.

One complication is handling the Python Tally objects produced when loading a statepoint file. One thing I tried was not setting the Tally._sp_filename property if the results dataset isn't present in the statepoint file. Then the tally behaves exactly as if it were created on the Python side with the mean, std_dev, etc. properties returning None. I'll put some thought into a more elegant solution that provides some indication the tally is tied to a statepoint file.

Compatibility

The primary issue I see is how the Python Tally object interacts with the statepoint file. I'd like to do something better than what I've done so far. The documentation on the results group for the statepoint file would need an update, but given that this change would result in the tally spec appearing more often than it does now I don't foresee a compatibility issue.

pshriwise commented 10 months ago

My test implementation of this is here for reference: https://github.com/pshriwise/openmc/tree/write-tally-specs