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
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)
- Change Operator attribute name for fission yield helper
- Use copy.deepcopy for constant_yields, fast_yields, and thermal_yields
- Change import location of openmc in tests
- Use bisect.bisect_left to find replacement fission yields on
FissionYieldCutoffHelper if thermal or fast energies not found
Renamed update_nuclides_from_operator -> update_tally_nuclides
to be more general.
The base method TalliedFissionYieldHelper.update_tally_nuclides will
raise an AttributeError if this method is called before the tallies
are generated. The inner logic for setting the tallied nuclides can
be streamlined given the assumption that the tally exists.
AveragedFissionYieldHelper.update_tally_nuclides has been improved
to set the nuclides for the weighted tally now. This was not captured
prior because the nuclides were copied over from the fission rate
tally during tally generation, prior to when nuclides were set.
Computes the effective fission yields for nuclides
with multiple sets of yields by
1) Tallying fission rate and energy-weighted fission rate
2) Determining average energy at which fission events occur
3) Interpolating [lin-lin] between adjacent fission yields based
on this average energy
Uses a second tally with an EnergyFunctionFilter to tally
E * sigma_f * phi.
Added unit tests with the proxy-style class that doesn't use the
C API to generate tallies but tests all other aspects of the
implementation. Tests cover three possible average energies
(below minimum supplied yield energy, above max supplied yield energy,
and between two)
The Operator uses fission_yield_mode="average" to select this helper.
The helper also has a from_operator class method.
TalliedFissionYieldHelper instances must be passed
the number of burnable materials at construction again.
To make things easier for the Operator, a from_operator
class method has been added to the FissionYieldHelper
and TalliedFissionYieldHelper abstract classes, as well
as more explicit versions on the ConstantFissionYieldHelper
and FissionYieldCutoffHelper. All have the call signature
cls.from_operator(operator, **kwargs)
The concrete classes have explicitely declared what the
allowed key word arguments are, while the abstract classes
forward kwargs directly onto __init__.
All explicit keyword arguments should have a counterpart
in the __init__ method.
A single argument, fission_yield_mode, is used to determine
what type of FissionYield to use on the Operator. The options
are
* "constant": ConstantFissionYieldHelper [default]
* "cutoff": FissionYieldCutoffHelper
An additional argument, fission_yield_opts, can be supplied
as a dictionary of keyword arguments to pass to the new
helper. This allows the user to have control over how
the private helper is created.
Given a requested energy, will take fission yields from that
energy on all nuclides and hold them as constant throughout
the simulation. If the requested energy is not found for a specific
nuclide, then the closest energy is used. The default is to
take the thermal 0.0253 eV yields.
This is now the helper attached to the Operator. The user can
select what energy of yields they would like to use.
API used by the Operator:
- generate_tallies
- weighted_yields [abstract]
- update_nuclides_from_operator
- unpack
generate_tallies and unpack are empty methods, provided
so that a consistent API can be found on helpers
with tallies.
Sorts nuclides into two dictionaries: those with a single
set of fission yields, and those with multiple sets.
The former can is exposed through the
constant_yields property, returning a copy of the fission
yield dictionary {parent: {product: yield}}
The Operator now looks for/uses the weighted_yields and
update_nuclides_from_operator methods instead of the old
compute_yields and set_fissionable_nuclides methods
Previously the yields were appended into the libraries
attribute. Now, the yields are returned directly and not
appended at all. It is up to the caller to place these yields
in the correct location.
The Operator maintains a list of of the libraries that is updated
through the unpacking method, and then set onto the Chain
after working through all local materials
Operator now has a new helper for tallying fission rates
and computing fission yields using energy dependency.
The FissionYieldHelper creates fission rate tallies across
burnable materials with an energy filter. The energy filter
corresponds to each energy group for which there are fission
yields.
During the operator's unpacking of tallies, this helper
computes a relative fission contribution by normalizing
fission rates, such that the sum of all group fission rates
in each material and each nuclide is unity.
A single fission yield for each parent nuclide is computed
by weighting the energy-dependent fission yields by
these relative contributions.
A nested dictionary {parent: {product: yield}} is added to
a library, and then attached to the depletion chain
at the end of the unpacking. These libraries are used
during the depletion process instead of the only-thermal
yields from before.
A test was added that creates a proxy helper that doesn't
use the C-API, but unpacks the "fission tally" and
computes the fission yield library in an identical manner
as the actual class. Since the proxy helper is a subclass
of the one used in real transport, the functionality
is consistent.
Called with a single integer corresponding to the current
depletion step. This method is intended to document the current
beginning-of-step calculations prior to any depletion at each step
and at the final simulation.
The Operator uses this method to write a statepoint using the
C API.
Also rename the Integrator _get_bos_data_from_openmc to
_get_bos_data_from_operator for generality. It is here that the
write_bos_data method is called.
Closes#1275 by passing reaction rates and numbers from
a previous result according to what materials are tracked
on an operator. A new method, Results.distribute, creates a new
Results object by
- directly copying over "global" data, like time, keff, and
maps describing where each material lives in the depletion_results
hdf5 file
- mapping volumes for local materials
- Extracting slices of numbers and reaction rates corresponding
to local material
This allows the Operator to create a unique ResultsList instance
containing reaction rates and compositions pertaining to
the materials tracked on this process (local).
This has been tested by comparing depletion_result files from restarts
1) using a serial restart run and 2) using two MPI process.
A quarter PWR assembly with 71 burnable materials was used.
Comparing with h5diff -r -p 0.01 <old> <new> <group> where
group=["eigenvalues", "number", "reaction rates"] and
-p 0.01 reports errors over 0.01% revealed no differences.
This allows the propagation of the uncertainty through
the SIE iterations, and alows the expressions for updating
k to be preserved. The OperatorResult.k was previous stored
as a tuple of two floats. The interface into the depletion_results
file is not changed, as the Results.save method, which writes the
OperatorResult data, breaks the ufloat into k and uncertainties.
Documentation has been updated on the OperatorResult.
The size of the Operator.reaction_rates does not change through
depletion, but the number of tallied nuclides for reaction
rates may or may not. The DirectReactionRateHelper returns
reaction rates according to the number of nuclides tallied,
a potential subset of all nuclides designated as burnable
by the Operator. This causes IndexErrors if a nuclide is not
tallied at a later step.
Example: 10 nuclides [0-9] are originally tracked by the Operator
and tallied by DirectReactionRateHelper. The Operator.reaction_rates
array will be of shape (n_mat, 10, n_react). Initially, the
DirectReactionRateHelper returns an array of size (10, n_react)
for each material. Then, if nuclide 5 is not in the list of nuclides
passed to the DirectReactionRateHelper at the next step, [decayed to
zero], DirectReactionRateHelper will return an array (9, n_react) and
try to pass tally data for nuclide 9 into row 9 of the reaction rate
array, causing an IndexError.
This commit instructs requires two integers, n_nucs and n_react, to be
passed to the initialization of any ReactionRateHelper, allocating
a single array for storing material-reaction rates. The method
get_material_rates uses this directly and does not re-allocate storage
if len(nuc_index) has changed [like if nuclide 9 has dropped out].
Users can now pass dilute_initial as an input
argument into the Operator, and directly set
Operator.dilute_initial. Documentation was updated to
include units on the initial default concentration, which
is 1000 atoms per cubic centimeter. The user is allowed
to set this value to zero.
Notes have been added to ResultsList.get_atoms
and get_reaction_rate methods, indicating why there may
be non-zero values when pulling data for isotopes not
initially present.
A similar note was added to the depletion_results.h5
io format file.
Closes#1288
Addressing comments in review for #1278
- Documentation cleanup
- Better naming convention regarding ReactionRateHelper
results cache
- The power in Operator tally unpacking and normalizing is
no longer converted to eV/s, since the EnergyHelper.energy
property is now returned in J/s/source neutron
EnergyHelper (was FissionEnergyHelper) has a new
``update`` method that replaces get_energy. This method
is no longer abstract and defaults to not performing any actions.
This works in conjunction with a new private ``_energy`` atribute
and ``reset`` method to streamline the energy normalization procedure.
For the current concrete ChainFissionHelper class, the reset method
sets _energy to zero, while the update method updates the energy
with the dot product fission_rates X fission_q_vector.
The total energy produced is made accessible, but not publically
writable with an energy property. After cycling through all
local materials on an operator, the total system energy is computed
by
energy = comm.allreduce(self._energy_helper.energy)
For a concrete class where the system energy is computed via tallies
and not with Q-values, the update methods could continue to do
nothing. The total system energy could be stored either in the
reset method or returned directly from the energy attribute/property.
Fix a bug introduced where the material iteration index,
for i, mat in enumerate(self.local_mats):
was used for the global __material__ index. The value of i
was used to extract reaction rate tallies for that material.
This causes an issue with multiple operators on MPI processes,
where an Operator`s material i does not equal the i-th burnable
material.
The cecm function has been removed from the python api.
In order to use the cecm integration scheme,
the following class based approach is now expected:
>>> from openmc.deplete import CECMIntegrator
>>> cecm = CECMIntegrator(operator, timesteps, power)
>>> cecm.integrate()
if the integrator is not needed, this above expression can be
one-lined with
>>> CECMIntegrator(operator, timesteps, power).integrate()
Unit tests have been updated to no longer use the cecm function,
and cecm has been removed from documentation.
The CECMIntegrator has been added to documentation.
When possible, replaced ``x[:, :, :] = y`` with ``x.fill(y)``.
Simple performance tests showed the approaches to be identical
with respect to process time. The latter maintains more
flexibility; whatever the shape of x becomes, no changes
need to be made, so long as x has a ``fill`` method.
Replaced ``rates[i, :, :] = ...`` with ``rates[i]`` per
reviewer comments
rate_helper responsible for passing reaction rates
onto the operator, while energy_helper is responsible
for computing the actual fission energy produced in each
material
Useful for benchmarking and other code to code comparisons.
The data is pulled right from the C api but now the uncertainties
are preserved and written to the depletion results file
openmc.deplete.tally_helers.ChainFissTallyHelper is responsible
for populating the fission_q vector, building the reaction rate
tallies, and updating the energy produced by fission per material.
This abstraction will be helpful as more methods for pulling
fission q values are introduced, namely as issue #1238, indirect
energy release, gets resolved
A dictionary of constant fission q values [eV] can be passed
into the initialization of deplete.Chain, deplete.Operator,
and model.Model objects. This can be used for direct
comparisons with other codes with readily available
constant Q-values.
Tests have been added on the Chain and Operator side.
The additional fiss_q_values passed into Model is forwarded
directly on to the Operator call.
If a chain_file is not passed when initializing an
openmc.deplete.Operator object, then the chain_file will
be read from the depletion_chain node from
$OPENMC_CROSS_SECTIONS. A deprecation warning is raised
if the environment variable OPENMC_DEPLETE_CHAIN is
still set, informing the users that this information
can instead be placed in their cross section file.
Documentation is updated describing the logic in the
chain_file search to reflect this in
- TransportOperator
- Operator
- Chain
.
Closes#1239