When trying to process Pa233 from ENDF/B-VIII.0, which has a threshold fission
reaction, I discovered that calculating heating numbers crashed because we were
trying to do arithmetic on arrays of different sizes. Re-evaluting the fission
cross section on the proper energy grid does the trick here.
Moved from deplete.abc into openmc.deplete.cram. CRAM16 and CRAM48
are aliases to __call__ methods for two instances of
IPFCramSolver: Cram16Solver and Cram48Solver, created using
16th and 48th order coefficients
Tallies created by internal depletion helpers are marked
as internal using the openmc.lib.Tally.writeable property.
This is done to resolve issue #1327 where statepoint files could
grow to be quite large after tallying reaction rates across many
burnable materials for all nuclides of interest.
A check is added in the depletion regression test to ensure that
no additional tallies are loaded to the StatePoint.
Add two functions to capi.h:
openmc_tally_set_writeable and openmc_tally_get_writeable
which are exposed to the Python API through the
openmc.lib.Tally.writeable property. These functions are very
similar to the set/get active counterparts as both act on a boolean
Tally attribute
A new unit test test_tally_writeable has been added that toggles
the writeable state of a tally. It is important to note that the
writeable state must be reset, otherwise tallies in subsequent
tests will be skewed. This is because the test_tally_writeable
function requires the capi_simulation_init fixture and the tallies
are shared by those functions that use the capi_run fixture
CRAM16 and CRAM48 are now aliases for __call__ methods
on two new classes: openmc.deplete.cram.Cram16Solver
and Cram48Solver. These are two concrete subclasses of
openmc.deplete.abc.IPFCramSolver and
openmc.deplete.abc.DepSystemSolver abstract classes.
The primary benefit of the class based approach is that the
16th and 48th order have nearly identical implementations. The only
differences are the alpha, theta, and alpha_0 coefficients used.
This allows both the Cram16Solver and Cram48Solver to have unique
sets of coefficient vectors, while relying on the IPFSolver base
class implementation.
The implementation of IPF CRAM has been cleaned up. The NxN identity
matrix is not re-created each iteration. Given the alpha and
theta attributes on the IPFCramSolver instances, one can
iterate through the orders using a zip command. By forcing concrete
classes to declared alpha and theta vectors, the need to re-declare
the vectors at each entrance into CRAM48 is also removed.
Using these classes, a 10% speedup is observed depleting up to 500
materials on a single MPI process. The function-based approach
took 62s, while the new classes required 52s.
Provide explicit __all__ lists for files in openmc/deplete
containing classes that should be brought into the "primary"
API. This prevents cluttering the openmc.deplete namespace
caused by the wildcard imports
```
from .nuclide import *
...
```
The abc, cram, and helpers modules are imported simply as
```
from . import abc
from . import cram
from . import helpers
```
If the system energy is found to be zero, then
Operator.__call__ will exit the simulation using
comm.Abort / sys.exit if no mpi4py. Without this, the
reaction rates will be scaled by power / 0, causing errors
downstream in setting material compositions.
Depending on settings.photon_transport, obtain the total
system energy from the 301 [heating] or 901 [heating-local]
scores. The former is used in coupled neutron-photon transport,
as this does not include any energy from neutrons or
photons, assuming these particles deposit their energy along
their life. MT901 is used for neutron transport and is the default,
e.g. if scores is None. This score includes energy from
prompt and delayed photons taken from MT458 data.
Related PR: #1344 - Ability to generate KERMAs assuming local
photon energy deposition
In using lists of containing integer reactions as
the scores, e.g.
```
t = openmc.lib.Tally()
t.scores = [901]
```
The setter would fail as the integers do not have an
encode method. This converts all incoming scores
to strings prior to passing values to the shared library.
Introduce a new subclass of EnergyHelper, EnergyScoreHelper,
that computes the system energy using the energy-deposition score.
This energy is fed back to the Operator to normalize reaction rates.
The energy from the tally is only stored on the helper on the
MPI process 0 as to avoid scaling the system energy by the number
of processes. During the Operator unpacking, the energy reported
by each process is reduced, as the previous implementations took
fission reaction rates from the "local materials", e.g. the
materials each process is responsible for depleting.
The tally results are shared across all processes and only
contains a single quantity, the tallied energy deposition across
all materials.
This mode is controlled by passing the "energy_mode" argument passed
to the Operator. The two options are "fission-q" [default and previous
behavior] and "energy-deposition" [new features]. If energy_mode indicates using
the energy deposition score, the user-supplied fission-q dictionary is not used.
(cherry picked from commit d566f3080f)