Made changes from paulromano's 2nd round of comments

- Syntax improvements and fixes
- removed `flux` parameter from Integrator
- Moved generate_1g_cross_sections to a top level function in
  flux_operator.py
- changed normalization modes: constant-flux -> source-rate;
  constant-power -> fission-q
- fixed regression tests (fission-q reference solution was bad before,
  but is now much more reasonable and comparable to the source-rate
  reference solution)
- added `nuc_units` parameter to the `from_nuclides` method.
- docstring fixes
- RST doc fixes
- spelling fixes
This commit is contained in:
yardasol 2022-07-27 12:27:16 -05:00
parent 8102226e70
commit 4818a296d4
11 changed files with 178 additions and 175 deletions

View file

@ -19,10 +19,10 @@ transmutation equations and the method used for advancing time. At present, the
:class:`openmc.deplete.Operator` (which uses the OpenMC transport solver), but
in principle additional operator classes based on other transport codes could be
implemented and no changes to the depletion solver itself would be needed. The
operator class requires a :class:`openmc.model.Model` instance containing
operator class requires a :class:`~openmc.Model` instance containing
material, geometry, and settings information::
model = openmc.model.Model()
model = openmc.Model()
...
op = openmc.deplete.Operator(model)
@ -189,17 +189,18 @@ Transport-independent depletion
OpenMC supports running depletion calculations independent of the OpenMC
transport solver using the :class:`~openmc.deplete.FluxDepletionOperator` class.
This class supports both constant-flux and constant-power depletion.
This class supports both constant-flux (``source-rate`` normalization) and
constant-power depletion (``fission-q`` normalization).
.. important::
Make sure you set the correct parameter in the :class:`openmc.abc.Integrator` class. Use the ``flux`` parameter when ``normalization_mode == constant-flux``, and use ``power`` or ``power_density`` when ``normalization_mode == constant-power``.
Make sure you set the correct parameter in the :class:`openmc.abc.Integrator` class. Use the ``source_rates`` parameter when ``normalization_mode == source-rate``, and use ``power`` or ``power_density`` when ``normalization_mode == fission-q``.
.. warning::
The accuracy of results when using ``constant-power`` is entirely dependent on your depletion chain. Make sure it has sufficient data to resolve the dynamics of your particular scenario.
The accuracy of results when using ``fission-q`` is entirely dependent on your depletion chain. Make sure it has sufficient data to resolve the dynamics of your particular scenario.
This class has two ways to initalize it: the default constructor accepts an
This class has two ways to initialize it: the default constructor accepts an
:class:`openmc.Materials` object and one-group microscopic
cross sections as a :class:`pandas.DataFrame`, while the ``from_nuclides``
method accepts a volume and dictionary of nuclide concentrations in place of
@ -221,7 +222,8 @@ or from data arrays::
'O16': 4.64e22,
'O17': 1.76e19}
volume = 0.5
op = FluxDepletionOperator.from_nuclides(volume, nuclides, micro_xs, flux, chain_file)
op = FluxDepletionOperator.from_nuclides(volume, nuclides, 'atom/cm3',
micro_xs, flux, chain_file)
A user can then define an integrator class as they would for a coupled
transport-depletion calculation and follow the same steps from there.

View file

@ -524,11 +524,10 @@ class Integrator(ABC):
power_density : float or iterable of float, optional
Power density of the reactor in [W/gHM]. It is multiplied by
initial heavy metal inventory to get total power if ``power``
is not speficied.
flux : float or iterable of float, optional
neutron flux in [neut/s-cm^2] for each interval in :attr:`timesteps`
is not specified.
source_rates : float or iterable of float, optional
source rate in [neutron/sec] for each interval in :attr:`timesteps`
Source rate in [neutron/sec] or neutron flux in [neut/s-cm^2] for each
interval in :attr:`timesteps`
.. versionadded:: 0.12.1
timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'}
@ -579,7 +578,7 @@ class Integrator(ABC):
"""
def __init__(self, operator, timesteps, power=None, power_density=None,
flux=None, source_rates=None, timestep_units='s', solver="cram48"):
source_rates=None, timestep_units='s', solver="cram48"):
# Check number of stages previously used
if operator.prev_res is not None:
res = operator.prev_res[-1]
@ -601,10 +600,8 @@ class Integrator(ABC):
source_rates = power_density * operator.heavy_metal
else:
source_rates = [p*operator.heavy_metal for p in power_density]
elif flux is not None:
source_rates = flux
elif source_rates is None:
raise ValueError("Either power, power_density, flux, or source_rates must be set")
raise ValueError("Either power, power_density, source_rates must be set")
if not isinstance(source_rates, Iterable):
# Ensure that rate is single value if that is the case
@ -865,11 +862,10 @@ class SIIntegrator(Integrator):
power_density : float or iterable of float, optional
Power density of the reactor in [W/gHM]. It is multiplied by
initial heavy metal inventory to get total power if ``power``
is not speficied.
flux : float or iterable of float, optional
neutron flux in [neut/s-cm^2] for each interval in :attr:`timesteps`
is not specified.
source_rates : float or iterable of float, optional
Source rate in [neutron/sec] for each interval in :attr:`timesteps`
Source rate in [neutron/sec] or neutron flux in [neut/s-cm^2] for each
interval in :attr:`timesteps`
.. versionadded:: 0.12.1
timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'}
@ -924,12 +920,12 @@ class SIIntegrator(Integrator):
"""
def __init__(self, operator, timesteps, power=None, power_density=None,
flux=None, source_rates=None, timestep_units='s', n_steps=10,
source_rates=None, timestep_units='s', n_steps=10,
solver="cram48"):
check_type("n_steps", n_steps, Integral)
check_greater_than("n_steps", n_steps, 0)
super().__init__(
operator, timesteps, power, power_density, flux, source_rates,
operator, timesteps, power, power_density, source_rates,
timestep_units=timestep_units, solver=solver)
self.n_steps = n_steps
@ -1014,7 +1010,7 @@ class DepSystemSolver(ABC):
Parameters
----------
A : scipy.sparse.csr_matrix
Sparse transmutation matrix ``A[j, i]`` desribing rates at
Sparse transmutation matrix ``A[j, i]`` describing rates at
which isotope ``i`` transmutes to isotope ``j``
n0 : numpy.ndarray
Initial compositions, typically given in number of atoms in some

View file

@ -1,7 +1,7 @@
"""Pure depletion operator
This module implements a pure depletion operator that uses user- provided fluxes
and one-group cross sections.
This module implements a pure depletion operator that user-provided one-group
cross sections.
"""
@ -20,12 +20,84 @@ from openmc.mpi import comm
from openmc.mgxs import EnergyGroups, ArbitraryXS, FissionXS
from .abc import ReactionRateHelper, OperatorResult
from .chain import REACTIONS
from .openmc_operator import OpenMCOperator
from .openmc_operator import OpenMCOperator, _distribute
from .results import Results
from .helpers import ChainFissionHelper, ConstantFissionYieldHelper, SourceRateHelper
_valid_rxns = list(REACTIONS)
_valid_rxns.append('fission')
def generate_1g_cross_sections(model,
reaction_domain,
reactions=['(n,gamma)',
'(n,2n)',
'(n,p)',
'(n,a)',
'(n,3n)',
'(n,4n)',
'fission'],
energy_bounds=(0, 20e6),
write_to_csv=False,
filename='micro_xs.csv'):
"""Helper function to generate a one-group cross-section dataframe using
OpenMC. Note that the ``openmc`` executable must be compiled.
Parameters
----------
model : openmc.model.Model
OpenMC model object. Must contain geometry, materials, and settings.
reaction_domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain in which to tally reaction rates.
reactions : list of str, optional
Reaction names to tally
energy_bound : 2-tuple of float, optional
Bounds for the energy group.
write_to_csv : bool, optional
Option to write the DataFrame to a `.csv` file.
filename : str
Name for csv file. Only applicable if ``write_to_csv == True``
Returns
-------
None or pandas.DataFrame
"""
groups = EnergyGroups(energy_bounds)
# Set up the reaction tallies
original_tallies = model.tallies
tallies = openmc.Tallies()
xs = {}
for rxn in reactions:
if rxn == 'fission':
xs[rxn] = FissionXS(domain=reaction_domain, groups=groups, by_nuclide=True)
else:
xs[rxn] = ArbitraryXS(rxn, domain=reaction_domain, groups=groups, by_nuclide=True)
tallies += xs[rxn].tallies.values()
model.tallies = tallies
statepoint_path = model.run()
# Revert to the original tallies
model.tallies = old_tallies
with openmc.StatePoint(statepoint_path) as sp:
for rxn in xs:
xs[rxn].load_from_statepoint(sp)
# Build the DataFrame
micro_xs = pd.DataFrame()
for rxn in xs:
df = xs[rxn].get_pandas_dataframe(xs_type='micro')
df.index = df['nuclide']
df.drop(['nuclide', xs[rxn].domain_type, 'group in', 'std. dev.'], axis=1, inplace=True)
df.rename({'mean':rxn}, axis=1, inplace=True)
micro_xs = pd.concat([micro_xs, df], axis=1)
if write_to_csv:
micro_xs.to_csv(filename)
return micro_xs
class FluxDepletionOperator(OpenMCOperator):
"""Depletion operator that uses one-group
@ -50,14 +122,16 @@ class FluxDepletionOperator(OpenMCOperator):
Default is None.
prev_results : Results, optional
Results from a previous depletion calculation.
normalization_mode : {"constant-power", "constant-flux"}
normalization_mode : {"fission-q", "source-rate"}
Indicate how reaction rates should be calculated.
``"constant-power"`` uses the fission Q values from the depletion chain to
compute the flux based on the power. ``"constant-flux"`` uses the value stored in `_normalization_helper` as the flux.
``"fission-q"`` uses the fission Q values from the depletion chain to
compute the flux based on the power. ``"source-rate"`` uses a the
source rate (assumed to be neutron flux) to calculate the
reaction rates.
fission_q : dict, optional
Dictionary of nuclides and their fission Q values [eV]. If not given,
values will be pulled from the ``chain_file``. Only applicable
if ``"normalization_mode" == "constant-power"``.
if ``"normalization_mode" == "fission-q"``.
reduce_chain : bool, optional
If True, use :meth:`openmc.deplete.Chain.reduce` to reduce the
depletion chain up to ``reduce_chain_level``. Default is False.
@ -104,14 +178,14 @@ class FluxDepletionOperator(OpenMCOperator):
Results from a previous depletion calculation. ``None`` if no
results are to be used.
"""
"""
def __init__(self,
materials,
micro_xs,
chain_file,
keff=None,
normalization_mode = 'constant-flux',
normalization_mode='source-rate',
fission_q=None,
prev_results=None,
reduce_chain=False,
@ -126,7 +200,8 @@ class FluxDepletionOperator(OpenMCOperator):
self._keff = keff
helper_kwargs = dict()
if fission_yield_opts is None:
fission_yield_opts = {}
helper_kwargs = {'normalization_mode': normalization_mode,
'fission_yield_opts': fission_yield_opts}
@ -141,10 +216,11 @@ class FluxDepletionOperator(OpenMCOperator):
reduce_chain_level=reduce_chain_level)
@classmethod
def from_nuclides(cls, volume, nuclides, micro_xs,
def from_nuclides(cls, volume, nuclides, nuc_units,
micro_xs,
chain_file,
keff=None,
normalization_mode='constant-flux',
normalization_mode='source-rate',
fission_q=None,
prev_results=None,
reduce_chain=False,
@ -156,8 +232,10 @@ class FluxDepletionOperator(OpenMCOperator):
volume : float
Volume of the material being depleted in [cm^3]
nuclides : dict of str to float
,Dictionary with nuclide names as keys and nuclide concentrations as
values. Nuclide concentration units are [atom/cm^3].
Dictionary with nuclide names as keys and nuclide concentrations as
values.
nuc_units : {'atom/cm3', 'atom/b-cm'}
Units for nuclide concentration.
micro_xs : pandas.DataFrame
DataFrame with nuclides names as index and microscopic cross section
data in the columns. Cross section units are [cm^-2].
@ -166,15 +244,16 @@ class FluxDepletionOperator(OpenMCOperator):
keff : 2-tuple of float, optional
keff eigenvalue and uncertainty from transport calculation.
Default is None.
normalization_mode : {"constant-power", "constant-flux"}
normalization_mode : {"fission-q", "source-rate"}
Indicate how reaction rates should be calculated.
``"constant-power"`` uses the fission Q values from the depletion
chain to compute the flux based on the power. ``"constant-flux"``
uses the value stored in `_normalization_helper` as the flux.
``"fission-q"`` uses the fission Q values from the depletion
chain to compute the flux based on the power. ``"source-rate"`` uses
the source rate (assumed to be neutron flux) to calculate the
reaction rates.
fission_q : dict, optional
Dictionary of nuclides and their fission Q values [eV]. If not
given, values will be pulled from the ``chain_file``. Only
applicable if ``"normalization_mode" == "constant-power"``.
applicable if ``"normalization_mode" == "fission-q"``.
prev_results : Results, optional
Results from a previous depletion calculation.
reduce_chain : bool, optional
@ -191,7 +270,7 @@ class FluxDepletionOperator(OpenMCOperator):
"""
check_type('nuclides', nuclides, dict, str)
materials = cls._consolidate_nuclides_to_material(nuclides, volume)
materials = cls._consolidate_nuclides_to_material(nuclides, nuc_units, volume)
return cls(materials,
micro_xs,
chain_file,
@ -205,14 +284,20 @@ class FluxDepletionOperator(OpenMCOperator):
@staticmethod
def _consolidate_nuclides_to_material(nuclides, volume):
def _consolidate_nuclides_to_material(nuclides, nuc_units, volume):
"""Puts nuclide list into an openmc.Materials object.
"""
openmc.reset_auto_ids()
mat = openmc.Material()
for nuc, conc in nuclides.items():
mat.add_nuclide(nuc, conc * 1e-24) # convert to at/b-cm
if nuc_units == 'atom/b-cm':
for nuc, conc in nuclides.items():
mat.add_nuclide(nuc, conc)
elif nuc_units == 'atom/cm3':
for nuc, conc in nuclides.items():
mat.add_nuclide(nuc, conc * 1e-24) # convert to at/b-cm
else:
raise ValueError(f"Unit '{nuc_units}' is invalid.")
mat.volume = volume
mat.depletable = True
@ -273,13 +358,12 @@ class FluxDepletionOperator(OpenMCOperator):
mat_index : int
Material index
"""
"""
volume = self._op.number.get_mat_volume(mat_index)
densities = np.empty(np.shape(fission_rates))
for i_nuc in self.nuc_ind_map:
nuc = self.nuc_ind_map[i_nuc]
densities = np.empty_like(fission_rates)
for i_nuc, nuc in self.nuc_ind_map.items():
densities[i_nuc] = self._op.number.get_atom_density(mat_index, nuc)
fission_rates = fission_rates * volume * densities
fission_rates *= volume * densities
super().update(fission_rates)
@ -294,10 +378,6 @@ class FluxDepletionOperator(OpenMCOperator):
Parameters
----------
n_nucs : int
Number of burnable nuclides tracked by :class:`openmc.deplete.Operator`
n_react : int
Number of reactions tracked by :class:`openmc.deplete.Operator`
op : openmc.deplete.FluxDepletionOperator
Reference to the object encapsulate _FluxDepletionRateHelper.
We pass this so we don't have to duplicate the ``number`` object.
@ -312,9 +392,9 @@ class FluxDepletionOperator(OpenMCOperator):
"""
def __init__(self, n_nuc, n_react, op):
super().__init__(n_nuc, n_react)
def __init__(self, op):
rates = op.reaction_rates
super().__init__(rates.n_nuc, rates.n_react)
self.nuc_ind_map = {ind: nuc for nuc, ind in rates.index_nuc.items()}
self.rxn_ind_map = {ind: rxn for rxn, ind in rates.index_rx.items()}
@ -349,7 +429,7 @@ class FluxDepletionOperator(OpenMCOperator):
return self._results_cache
def _get_helper_classes(self, helper_kwargs):
"""Get helper classes for calculating reation rates and fission yields
"""Get helper classes for calculating reaction rates and fission yields
Parameters
----------
@ -359,19 +439,16 @@ class FluxDepletionOperator(OpenMCOperator):
"""
normalization_mode = helper_kwargs['normalization_mode']
fission_yield_opts = helper_kwargs.get('fission_yield_opts', {})
fission_yield_opts = helper_kwargs['fission_yield_opts']
self._rate_helper = self._FluxDepletionRateHelper(
self.reaction_rates.n_nuc, self.reaction_rates.n_react, self)
if normalization_mode == "constant-power":
self._rate_helper = self._FluxDepletionRateHelper(self)
if normalization_mode == "fission-q":
self._normalization_helper = self._FluxDepletionNormalizationHelper(self)
else:
self._normalization_helper = SourceRateHelper()
# Select and create fission yield helper
fission_helper = ConstantFissionYieldHelper
if fission_yield_opts is None:
fission_yield_opts = {}
self._yield_helper = fission_helper.from_operator(
self, **fission_yield_opts)
@ -395,7 +472,7 @@ class FluxDepletionOperator(OpenMCOperator):
vec : list of numpy.ndarray
Total atoms to be used in function.
source_rate : float
Power in [W] or source rate in [neutron/sec]
Power in [W] or flux in [neut/s-cm^2]
Returns
-------
@ -444,11 +521,11 @@ class FluxDepletionOperator(OpenMCOperator):
print(f'WARNING: nuclide {nuc} in material'
f'{mat} is negative (density = {val}'
' at/barn-cm)')
' atom/b-cm)')
number_i[mat, nuc] = 0.0
@staticmethod
def create_micro_xs_from_data_array(nuclides, reactions, data, units='barn'):
def create_micro_xs_from_data_array(nuclides, reactions, data):
"""
Creates a ``micro_xs`` parameter from a dictionary.
@ -458,12 +535,10 @@ class FluxDepletionOperator(OpenMCOperator):
List of nuclide symbols for that have data for at least one
reaction.
reactions : list of str
List of reactions. All reactions must match those in ``chain.REACTONS``
List of reactions. All reactions must match those in ``chain.REACTIONS``
data : ndarray of floats
Array containing one-group microscopic cross section information for each
nuclide and reaction.
units : {'barn', 'cm^2'}, optional
Units of cross section values in ``data`` array. Defaults to ``barn``.
Array containing one-group microscopic cross section values, in
[barn], for each nuclide and reaction.
Returns
-------
@ -483,8 +558,7 @@ class FluxDepletionOperator(OpenMCOperator):
nuclides, reactions, data)
# Convert to cm^2
if units == 'barn':
data *= 1e-24
data *= 1e-24
return pd.DataFrame(index=nuclides, columns=reactions, data=data)
@ -497,9 +571,7 @@ class FluxDepletionOperator(OpenMCOperator):
----------
csv_file : str
Relative path to csv-file containing microscopic cross section
data.
units : {'barn', 'cm^2'}, optional
Units of cross section values in the ``.csv`` file array. Defaults to ``barn``.
data. Cross section values should be in [barn].
Returns
-------
@ -514,8 +586,7 @@ class FluxDepletionOperator(OpenMCOperator):
list(micro_xs.columns),
micro_xs.to_numpy())
if units == 'barn':
micro_xs *= 1e-24
micro_xs *= 1e-24
return micro_xs
@ -528,67 +599,3 @@ class FluxDepletionOperator(OpenMCOperator):
for reaction in reactions:
check_value('reactions', reaction, _valid_rxns)
@staticmethod
def generate_1g_cross_sections(model, reaction_domain, reactions=['(n,gamma)', '(n,2n)', '(n,p)', '(n,a)', '(n,3n)', '(n,4n)', 'fission'], energy_bounds=(0, 20e6), write_to_csv=True, filename='micro_xs.csv'):
"""Helper function to generate a one-group cross-section dataframe
using OpenMC. Note that the ``openmc`` C executable must be compiled.
Parameters
----------
model : openmc.model.Model
OpenMC model object. Must contain geometry, materials, and settings.
reaction_domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain in which to tally reaction rates.
reactions : list of str, optional
Reaction names to tally
energy_bound : 2-tuple of float, optional
Bounds for the energy group.
write_to_csv : bool, optional
Option to write the DataFrame to a `.csv` file. If `False`,
returns the dataframe object.
filename : str
Name for csv file. Only applicable if ``write_to_csv == True``
Returns
-------
None or pandas.DataFrame
"""
groups = EnergyGroups()
groups.group_edges = np.array(list(energy_bounds))
# Set up the reaction tallies
tallies = openmc.Tallies()
xs = dict()
for rxn in reactions:
if rxn == 'fission':
xs[rxn] = FissionXS(domain=reaction_domain, groups=groups, by_nuclide=True)
else:
xs[rxn] = ArbitraryXS(rxn, domain=reaction_domain, groups=groups, by_nuclide=True)
tallies += xs[rxn].tallies.values()
model.tallies = tallies
statepoint_path = model.run()
sp = openmc.StatePoint(statepoint_path)
for rxn in xs:
xs[rxn].load_from_statepoint(sp)
sp.close()
# Build the DataFrame
micro_xs = pd.DataFrame()
for rxn in xs:
df = xs[rxn].get_pandas_dataframe(xs_type='micro')
df.index = df['nuclide']
df.drop(['nuclide', xs[rxn].domain_type, 'group in', 'std. dev.'], axis=1, inplace=True)
df.rename({'mean':rxn}, axis=1, inplace=True)
micro_xs = pd.concat([micro_xs, df], axis=1)
if write_to_csv:
micro_xs.to_csv(filename)
return None
else:
return micro_xs

View file

@ -612,7 +612,7 @@ class FissionYieldCutoffHelper(TalliedFissionYieldHelper):
Default: 0.0253 [eV]
fast_energy : float, optional
Energy of yield data corresponding to fast yields.
Default: 500 [kev]
Default: 500 [KeV]
Attributes
----------
@ -634,7 +634,7 @@ class FissionYieldCutoffHelper(TalliedFissionYieldHelper):
Array of fission rate fractions with shape
``(n_mats, 2, n_nucs)``. ``results[:, 0]``
corresponds to the fraction of all fissions
that occured below ``cutoff``. The number
that occurred below ``cutoff``. The number
of materials in the first axis corresponds
to the number of materials burned by the
:class:`openmc.deplete.Operator`
@ -790,7 +790,7 @@ class FissionYieldCutoffHelper(TalliedFissionYieldHelper):
class AveragedFissionYieldHelper(TalliedFissionYieldHelper):
r"""Class that computes fission yields based on average fission energy
Computes average energy at which fission events occured with
Computes average energy at which fission events occurred with
.. math::
@ -908,7 +908,7 @@ class AveragedFissionYieldHelper(TalliedFissionYieldHelper):
Use the computed average energy of fission
events to determine fission yields. If average
energy is between two sets of yields, linearly
interpolate bewteen the two.
interpolate between the two.
Otherwise take the closet set of yields.
Parameters

View file

@ -103,7 +103,7 @@ class CECMIntegrator(Integrator):
op_results : list of openmc.deplete.OperatorResult
Eigenvalue and reaction rates from transport simulations
"""
# deplete across first half of inteval
# deplete across first half of interval
time0, x_middle = self._timed_deplete(conc, rates, dt / 2)
res_middle = self.operator(x_middle, source_rate)

View file

@ -90,7 +90,6 @@ class OpenMCOperator(TransportOperator):
cross_sections : str or pandas.DataFrame
Path to continuous energy cross section library, or object
containing one-group cross-sections.
dilute_initial : float
Initial atom density [atoms/cm^3] to add for nuclides that
are zero in initial condition to ensure they exist in the decay
@ -527,7 +526,9 @@ class OpenMCOperator(TransportOperator):
# Accumulate energy from fission
if fission_ind is not None:
self._normalization_helper.update(tally_rates[:, fission_ind], mat_index=mat_index)
self._normalization_helper.update(
tally_rates[:, fission_ind],
mat_index=mat_index)
# Divide by total number and store
rates[i] = self._rate_helper.divide_by_adens(number)

View file

@ -225,7 +225,10 @@ class Operator(OpenMCOperator):
self.cleanup_when_done = True
helper_kwargs = dict()
if reaction_rate_opts is None:
reaction_rate_opts = {}
if fission_yield_opts is None:
fission_yield_opts = {}
helper_kwargs = {
'reaction_rate_mode': reaction_rate_mode,
'normalization_mode': normalization_mode,
@ -329,17 +332,14 @@ class Operator(OpenMCOperator):
reaction_rate_mode = helper_kwargs['reaction_rate_mode']
normalization_mode = helper_kwargs['normalization_mode']
fission_yield_mode = helper_kwargs['fission_yield_mode']
reaction_rate_opts = helper_kwargs.get('reaction_rate_opts', {})
fission_yield_opts = helper_kwargs.get('fission_yield_opts', {})
reaction_rate_opts = helper_kwargs['reaction_rate_opts']
fission_yield_opts = helper_kwargs['fission_yield_opts']
# Get classes to assist working with tallies
if reaction_rate_mode == "direct":
self._rate_helper = DirectReactionRateHelper(
self.reaction_rates.n_nuc, self.reaction_rates.n_react)
elif reaction_rate_mode == "flux":
if reaction_rate_opts is None:
reaction_rate_opts = {}
# Ensure energy group boundaries were specified
if 'energies' not in reaction_rate_opts:
raise ValueError(
@ -365,8 +365,6 @@ class Operator(OpenMCOperator):
# Select and create fission yield helper
fission_helper = self._fission_helpers[fission_yield_mode]
if fission_yield_opts is None:
fission_yield_opts = {}
self._yield_helper = fission_helper.from_operator(
self, **fission_yield_opts)
@ -489,7 +487,7 @@ class Operator(OpenMCOperator):
print(f'WARNING: nuclide {nuc} in material'
f'{mat} is negative (density = {val}'
' at/barn-cm)')
' atom/b-cm)')
number_i[mat, nuc] = 0.0

View file

@ -3,8 +3,8 @@
from math import floor
import shutil
from pathlib import Path
from difflib import unified_diff
import numpy as np
import pytest
import openmc
@ -12,7 +12,6 @@ from openmc.data import JOULE_PER_EV
import openmc.deplete
from openmc.deplete import FluxDepletionOperator
from tests.regression_tests import config
@ -22,7 +21,7 @@ def fuel():
fuel.add_element("U", 1, percent_type="ao", enrichment=4.25)
fuel.add_element("O", 2)
fuel.set_density("g/cc", 10.4)
fuel.depletable=True
fuel.depletable = True
fuel.volume = np.pi * 0.42 ** 2
@ -30,14 +29,14 @@ def fuel():
@pytest.mark.parametrize("multiproc, from_nuclides, normalization_mode, power, flux", [
(True, True,'constant-flux', None, 1164719970082145.0),
(False, True, 'constant-flux', None, 1164719970082145.0),
(True, True, 'constant-power', 174, None),
(False, True, 'constant-power', 174, None),
(True, False,'constant-flux', None, 1164719970082145.0),
(False, False, 'constant-flux', None, 1164719970082145.0),
(True, False, 'constant-power', 174, None),
(False, False, 'constant-power', 174, None)])
(True, True,'source-rate', None, 1164719970082145.0),
(False, True, 'source-rate', None, 1164719970082145.0),
(True, True, 'fission-q', 174, None),
(False, True, 'fission-q', 174, None),
(True, False,'source-rate', None, 1164719970082145.0),
(False, False, 'source-rate', None, 1164719970082145.0),
(True, False, 'fission-q', 174, None),
(False, False, 'fission-q', 174, None)])
def test_no_transport_from_nuclides(run_in_tmpdir, fuel, multiproc, from_nuclides, normalization_mode, power, flux):
"""Transport free system test suite.
@ -53,10 +52,10 @@ def test_no_transport_from_nuclides(run_in_tmpdir, fuel, multiproc, from_nuclide
if from_nuclides:
nuclides = {}
for nuc, dens in fuel.get_nuclide_atom_densities().items():
nuclides[nuc] = dens * 1e24
nuclides[nuc] = dens
op = FluxDepletionOperator.from_nuclides(
fuel.volume, nuclides, micro_xs, chain_file, normalization_mode=normalization_mode)
fuel.volume, nuclides,'atom/b-cm', micro_xs, chain_file, normalization_mode=normalization_mode)
else:
op = FluxDepletionOperator(openmc.Materials([fuel]), micro_xs, chain_file, normalization_mode=normalization_mode)
@ -67,14 +66,14 @@ def test_no_transport_from_nuclides(run_in_tmpdir, fuel, multiproc, from_nuclide
# Perform simulation using the predictor algorithm
openmc.deplete.pool.USE_MULTIPROCESSING = multiproc
openmc.deplete.PredictorIntegrator(
op, dt, power=power, flux=flux, timestep_units='d').integrate()
op, dt, power=power, source_rates=flux, timestep_units='d').integrate()
# Get path to test and reference results
path_test = op.output_dir / 'depletion_results.h5'
if flux is not None:
ref_path = 'test_reference_constant_flux.h5'
ref_path = 'test_reference_source_rate.h5'
else:
ref_path = 'test_reference_constant_power.h5'
ref_path = 'test_reference_fission_q.h5'
path_reference = Path(__file__).with_name(ref_path)
# Load the reference/test results

View file

@ -71,7 +71,7 @@ def test_operator_init():
'O17': 1.7588724018066158e+19}
micro_xs = FluxDepletionOperator.create_micro_xs_from_csv(ONE_GROUP_XS)
nuclide_flux_operator = FluxDepletionOperator.from_nuclides(
volume, nuclides, micro_xs, CHAIN_PATH)
volume, nuclides, 'atom/cm3', micro_xs, CHAIN_PATH)
fuel = Material(name="uo2")
fuel.add_element("U", 1, percent_type="ao", enrichment=4.25)