Adding burnup and state dependent cuts
These are sections were homogenization will be performed at different state and geometry conditions and burnup levels (if applicable). They are more akin to a traditional lattice calculation, and results will be used to form a state dependent homogenized library.
The application driver first performs pure burnup calculations for all defined depletion lines. It then goes back and performs the (more expensive) homogenization calculations at all geometry branches, and state conditions. This is illustrated by the following diagram:

For burnup dependent libraries, the application has the ability to calculate a homogenized microscopic cross sections at each state point. This enables the simulator to calculate reaction rates using the correct core spectrum, which is then used to re-calculate the transmutation chains.
Note
Burnup dependence is optional. These cuts can be also be used to calculate state dependent cross sections for non fuel assemblies.
Define burnable assemblies
If the cut is going to have depletion as one of its state parameters, the system needs to know which components in the
heterogeneous model should be depleted. For this, the model’s load_map
is used. Only named assemblies in the
load_map
will be depleted. For example, in a typical infinite environment problem, the heterogeneous model
will resemble the following:
fa = assemblies.MY_REACTOR_fuel_assembly(name='FA')
parameters.generator.model.load_map = \
[[ _, '1'],
['A', fa]]
parameters.generator.model.core_map = \
[[ _, '1'],
['A', _p]]
parameters.generator.model.core_pitches = 7.71 * units.cm, 8.1 * units.cm
Note
For lattice calculations, you should consider refining the deletable material mesh.
In larger colorset problems, the load_map
can be used to specify which assemblies should be depleted along
with the target assembly(s). For example,
f1 = assemblies.MY_REACTOR_fuel_assembly(name='FA1')
f2 = assemblies.MY_REACTOR_fuel_assembly(name='FA2')
ff = assemblies.MY_REACTOR_second_fuel_assembly(name='FF')
parameters.generator.model.load_map = \
[[ _, '1', '2', '3'],
['A', f1, ff, _]]
parameters.generator.model.core_map = \
[[ _, '1', '2', '3'],
['A', _p, _p, f2]]
Will burn the assemblies in the first two columns, but keep the last one fresh.
Burnable components that are not loaded directly in the core, but as facilities inside other components (e.g. rigs) are also allowed.
Add two dimensional cuts
As in static cuts, homogenization is performed on sections through the three dimensional model. State dependant cuts are added using the following method:
- parameters.add_lattice_cut(label, position=0.0 * units.cm, width=1.0 * units.cm, rng=None, description=None)
Defines a section on which homogenization will be performed for different state parameters, geometric configurations, and burnup. There must be some fissionable material present in the cut.
- Parameters:
label (str) – Name used to identify the section. It will be used to identify the cut on the command line. It is recommended to use a unique tag no longer than 12 characters.
position (length) – Center axial position of the section.
width (length) – Axial size of the section.
rng (tuple (length)) – Minimum and maximum axial position of the section.
description (str) – String giving more information about the cut (e.g. where it is located, why it was chosen, etc)
- Returns:
Two values, the first a parameter set which configures the calculation, and the second a standard cut reference, as returned by parameters.add_cut.
Example:
parm, cut = parameters.add_lattice_cut('LAT-ACT', 0.0 * units.cm, fa.active_height(), description='State dependent homogenization of active region')
The returned parm set is used to add burn lines, state conditions and branches.
Alternatively, if there is no fuel in the section of interest, use the following:
- parameters.add_reflector_lattice_cut(label, position=0.0 * units.cm, width=1.0 * units.cm, rng=None, description=None)
Defines a section on which homogenization will be performed for different state parameters and or geometric configurations.
- Parameters:
label (str) – Name used to identify the section. It will be used to identify the cut on the command line. It is recommended to use a unique tag no longer than 12 characters.
position (length) – Center axial position of the section.
width (length) – Axial size of the section.
rng (tuple (length)) – Minimum and maximum axial position of the section.
description (str) – String giving more information about the cut (e.g. where it is located, why it was chosen, etc)
- Returns:
Two values, the first a parameter set which configures the calculation, and the second a standard cut reference, as returned by parameters.add_cut.
Attention
Tabulation against burnup is not available for these cuts.
Set additional homogenization parameters
The returned set parm has methods for adding depletion lines, as well as the following parameters, which applies to all state conditions:
-
auxiliary_library
: string
= endfb-vii.1-172 Additional fine group library used to extract data (such as microscopic scattering exit distributions and kinetics parameters) not given by the chosen lattice solver. This must be the name of a valid multi-group library, in the native rapyds binary format. The system currently ships with the following options:
rapyds/data/endfb-vii.1-172: A 172 XMAS group structure microscopic library using ENDF-VII.1 evaluated data. This is the default value.
rapyds/data/jeff-3.1.2-172: A 172 XMAS group structure microscopic library using JEFF-3.1.2 evaluated data.
Note
With the exception of the
lump
isotopes, this library is not used to perform any cross section entry channel folding.
-
include_kinetics_data
: bool
= False Flag indicating if kinetics data (e.g. precursor yields, decay constants, and delayed fission spectrum) for actinides should be included in the homogenization data.
Note
When targeting newer versions of MGRAC with spatial kinetics, this flag is switched on automatically.
-
colorset
: Container
= NA Collects all parameters related to the geometry of the lattice calculation:
- target_assemblies = NA
Flags at which positions in the
load_map
homogenization should be performed. This should be a map containing the same assembly names appearing in the load map. For example, if the load map was defined asfa = assemblies.MY_REACTOR_fuel_assembly(name='FA') parameters.generator.model.load_map = \ [[ _, '1'], ['A', fa]]
Then,
parm.colorset.target_assemblies = \ [[ _, '1' ], ['A', 'FA']]
Note
The
target_assemblies
defaults to an empty load grid, so, instead of specifying a full map, you can also set the specific position(s), e.g,parm.colorset.target_assemblies['A1'] = 'FA'
This parameter is replaced with a different method for the special case when the target assembly is segmented.
- sub_node_mesh = NA
Defines pin cell mesh structures for positions in the colorset. These sub meshes are used for flux and power reconstruction.
Each entry in the map is a list of length two, with the first entry a list of \(x\) pitches, and the second a list of \(y\) pitches. This then defines the two dimensional grid over which pin cell powers and fluxes will be calculated.
Note
Like the
target_assemblies
parameters, this defaults to an empty load grid, so, instead of specifying a full map, you can also set the specific position(s), e.g,parm.colorset.sub_node_mesh['A1'] = mesh
The mesh can be specified manually, e.g.
mesh = [[0.7395] + [1.0383] * 6 +[0.7395], [1.061] + [0.427] * 16 + [1.061]]
Attention
The mesh will automatically be stretched to cover the entire nodal pitch, so relative values can be specified.
Alternatively, all of the fuel assembly macros provide a method which can be used to auto generate a mesh. For example, assuming the nodal pitch is 7.71 by 8.1 centimeter,
mesh = fa.fuel_bundle().pin_cell_mesh(dx=7.71 * units.cm, dy=8.1 * units.cm, radial_segments=6)
will create a mesh that ensures that each fueled primitive (plate or pin) is its own unique mesh, and subdivide the mesh radially along the primitive into 6 equal segments. Note that the radial_segment parameter only applies to plate type fuel, and is ignored for pins.
-
microscopic_isotopes
: list
= NA Defines isotopes for which microscopic cross sections will be calculated. A list of isotope must be specified for each burn bundle whose transmutation will be recalculated by the core solver (that is, is not fixed in the homogenized mixture).
The composition for fissionable material includes a number of actinides and fission products:
parm.colorset.microscopic_isotopes[bundle_tags.fuel] = \ ['U-234', 'U-235', 'U-236', 'U-237', 'U-238', 'Np-237', 'Np-239', 'Pu-238', 'Pu-239', 'Pu-240', 'Pu-241', 'Pu-242', 'Am-241', 'Am-243', 'Cm-242', 'Cm-243', 'Cm-244', 'Cm-245', 'I-135', 'Xe-135', 'Ce-141', 'Ce-142', 'Ce-144', 'Pr-143', 'Nd-143', 'Nd-144', 'Nd-145', 'Nd-146', 'Nd-147', 'Nd-148', 'Pm-147', 'Pm-148', 'Pm-148m', 'Pm-149', 'Sm-147', 'Sm-148', 'Sm-149', 'Cs-137']
Note
The isotopes list can have any number of isotopes, with the following restrictions:
Each isotope in the list that is not in the initial material composition must be a daughter of another isotope in the list.
For fuel mixtures I-135 and Xe-135 must always be present.
All isotopes not in the list will be lumped into a single (residual) cross section, which is fixed by the lattice calculation at all the state points, and can not be modified by the core solver.
For burnable absorbers, usually only the primary absorption isotope(s) are chosen. For example, if a cadmium based absorber is present:
parm.colorset.microscopic_isotopes[bundle_tags.ba] = ['Cd-113']
Note
To support future development, the interface can accept isotope list for any burn bundle. However, currently the nodal solver can only burn two bundles, fuel and burnable absorbers, independently.
- homogenization_weights = NA
Defines what node average quantity is used to collapse and later reconstruct the microscopic reaction rates for each position in the colorset. Currently the options are
- node_flux()
Use the node average flux to weight and reconstruct microscopic cross sections. This is the default.
- side_flux(*sides)
Use the side average flux to weight and reconstruct microscopic cross sections.
- Parameters:
sides (str) – A list of side indicators, e.g.
'north'
,'south'
, etc. The average side flux over all these sides will be used.
This option is more accurate for absorber located near the side of an assembly.
At each position, the weight is further connected to a burn bundle, e.g.
parm.colorset.homogenization_weights['1A'][bundle_tags.ba] = side_flux('east', 'west')
Note
Currently the side_flux option can only be used for burnable absorbers.
- lump
List of additional isotopes that can be used as a pseudo fission product when creating exposure libraries. This is intended to represent absorption by products not explicitly listed in
microscopic_isotopes
.Currently, lumping is only supported for the fuel bundle.
Note
Cross sections for isotopes in this list are calculated by folding the microscopic cross sections from the
auxiliary_library
with the homogenized flux.
Add a burn line
To initiate the homogenization at various state conditions, a burn line is added by invoking the following:
- parm.add_burn_line(tag='main')
- Parameters:
tag (str) – Name used to identify the depletion line.
- Returns:
A data object which collects the parameters defining the depletion calculation.
For example, the following will add a burn line using the default tag:
burn = parm.add_burn_line()
The burn object accepts all the standard application parameters as well as:
- burn.irradiation_history
Defines the amount and duration of depletion steps, as well as the state of the underlying model during each depletion step. This is a standard irradiation history object. For most lattice calculations, this is simply a list of day steps, at a constant power. For example:
steps = [ 0.1, 0.25, 0.5, 0.75, 1, 2, 3, 4, 6, 7, 8, 9, 10] for t in steps: burn.irradiation_history.add_step(duration=t * units.days, power=20.0 / 16.0 * units.MW) burn.irradiation_history.step_type = irradiations.cumulative()
However, the full complexity provided by the irradiation history object is supported.
-
at_steps
: list
List of burn step indices at which branch and off base calculations will be performed. If not specified, these calculations are performed at all depletion steps.
For example, the following will only perform branch homogenization calculations at burn steps 0 (fresh), 2 and 4:
burn.at_steps = [0, 2, 4]
The nominal state (fuel and moderator temperatures) at which depletion is performed can be modified using:
- burn.set_state(*state_parameters)
- Parameters:
state_parameters – Sequence of state parameter tags.
For example:
burn.set_state(state_parameter.fuel_temperature(60 * units.degC), state_parameter.moderator_temperature(40.0 * units.degC), state_parameter.moderator_density(0.99160 * units.g / units.cc))
Define off base conditions
An off base condition is defined as a perturbation in any state parameter from its nominal value, that is, the value used in the burn line. They are added to the burn line using:
The perturb method can be used to retrieve a state condition that perturbs a single parameter. For example,
nominal = burn.get_nominal_state() # retrieve the nominal state
burn.add_offbase(nominal.perturb(state_parameters.fuel_temperature, +40.0))
will add an off base which raises only the fuel temperature by 40 degrees, while keeping all other parameters fixed.
Note
Off base conditions are applied to all geometry branches <Add geometry branch>.
Attention
Although the interface is fairly generic (allowing one to add any combination of state point values), take note of the restrictions in the current generation of library processing tools described in Limitations when using the current library generation line.
Add geometry branches
Unlike off base conditions, branches involve a physical change in the geometry of the target assembly(s). Typical examples are
Insertion of a control rod
Insertion or removal of absorber
A branch is added to a burn line using:
- burn.add_branch(name='main')
- Parameters:
name (str) – The tag used to identify the branch.
- Returns:
A reference to the branch, which is used to modify the model geometry, and customise execution parameters.
The main branch must always be present. Thus, you script should contain a statement similar too:
main_branch = burn.add_branch('main')
main_branch.particles = 64000
main_branch.source_iteration = 25
main_branch.max_iteration = 625
Note
The execution parameters set here will apply to all the off base calculations at each selected depletion step.
Adding a rod branch usually takes the following form:
rod_branch = burn.add_branch('rodded')
rod_branch.model.set_banks(control.fully_inserted())
rod_branch.particles = 64000
rod_branch.source_iteration = 25
rod_branch.max_iteration = 725
Note
This assumes that a control rod was already added and configured in the model. See the section on configuring control structured.
Limitations when using the current library generation line
Although the lattice calculation interface is very generic, there are a number of limitations that must be adhered to when using the currently available library formats in OSCAR-5:
Only a single burnup line is supported.
The fitting tool POLX only supports a single state parameter perturbation in each off base. That is, no mixed state perturbations are allowed.
Only the following state parameters can be perturbed:
fuel temperature
moderator temperature
moderator density
boron concentration
A maximum of three geometry branches are allowed, and they must have the following tags:
'main'
'rodded'
or'control'
'burnable_absorber'
Treatment of segmented assemblies
The system has a few additional interface elements that facilitates lattice calculations for assemblies that are segmented, that is, the homogenization mesh splits the assembly into a number of pieces.
Note
Segmented assembly lattice calculations are required when the overlay nodal mesh for the entire model intersects these assemblies.
The segments themselves are defined in the usual fashion by setting the homogenization_grid
and
homogenization_grid_pitches
parameters. For example, the following will split the homogenization calculations
in a 3 x 3 mesh.
parameters.homogenization_grid =\
[[ _, 'A1', 'A2', 'A3'],
['11', 1, 1, 1],
['12', 1, 1, 1],
['13', 1, 1, 1]]
parameters.homogenization_grid_pitches = [[23.65 * units.mm, 34.2 * units.mm, 23.65 * units.mm],
[23.65 * units.mm, 34.2 * units.mm, 23.65 * units.mm]]
Attention
These segments must align with the actual nodal calculational mesh in all channels which can contain this assembly type.
When depleting a segmented assembly, first ensure that the depletion mesh is configured in such a way that each burn segment falls in a single sub segment.
Attention
Currently, segments lines are not allowed to intersect primitives (plates or pins)!
Instead of specifying a mixture name for each segment using the target_assemblies
parameter, the following
call can be used:
- parm.colorset.set_segments(name, segments, rows=None, columns=None)
- Parameters:
name (str) – Target assembly name.
segments (list) – A list or tuple of two entries, with the first entry a list of \(x\) pitches, and the second a list of \(y\) pitches.
rows (list) – List of consecutive row labels in the
homogenization_grid
containing the segmented target assembly.columns (list) – List of consecutive column labels in the
homogenization_grid
containing the segmented target assembly.
When the lattice calculation targets only a single segmented assembly, the
homogenization_grid_pitches
can be used, and the rows and columns parameters may be omitted. For example,parm.set_segments('TARGET', segments=parameters.homogenization_grid_pitches)
Otherwise, for multiple segmented assemblies, this call must be repeated for each target position.
Finally, how the different burnable components map to each segment must be specified:
- parm.colorset.set_burn_bundle_segments(name, distribution, bundle=bundle_tag.fuel)
- Parameters:
name (str) – Target assembly name.
distribution (list) – Describe how burnable primitives are mapped to the assembly segments. Given as a grid, with the same dimensions as the segment grid. Each entry in the grid describes which segments of fueled primitives are contained in the assembly segment. See below for more detail.
bundle (bundle_tag) – The target depletion bundle.
Each entry in the distribution grid must be a tuple with:
the first entry a list of primitive indices,
and the second a list of depletion mesh segment indices that intersects the assembly segment. Can be omitted if the all the depletion mesh segments fall into a mesh segment.
For example, the following illustrates the grouping of primitive segments in an plate type assembly broken into 3 by 3 segments:
# 3 by 3 grid mapping primitives to homogenization segments
# First cell contains plates 0 to 6 and the first radial segment, next cell contains plates 0 to 6 but the
# second radial segment etc
fuel_bundle_grid = \
[[(range(15, 21), [0]), (range(15, 21), [1]), (range(15, 21), [2])],
[(range(6, 15), [0]), (range(6, 15), [1]), (range(6, 15), [2])],
[(range(0, 6), [0]), (range(0, 6), [1]), (range(0, 6), [2])]]
param.colorset.set_burn_bundle_segments('TARGET', fuel_bundle_grid, assembly.burn_bundle.fuel)
Attention
Although the system has an algorithm that can compute this distribution from the segment mesh, it is time consuming (especially for assemblies with a large number of primitives), and the results are currently not cached, meaning that it will be repeated each time the script is run. The implementation will be improved in a future release, but in the meantime, it is recommended that the map be specified manually.
The mapping should be specified for each depletion bundle with tabulated microscopic_isotopes
.
Note
Although it requires more input, and produces more output, the method for homogenization segmented assemblies should not require any additional calculational time, as only a signal depletion and homogenization calculation is performed, irrespective of the number of segments.
Performing lattice calculations on the command line
This section focuses on cross section generation for lattice cuts, since it involves a lot more options than standard homogenization calculations. The general command line interaction is described in Running a cOMPoSe application module from the terminal.
Note
This only describes the generator mode functionality for these types of calculations. All other modes (library etc), has the same purpose and functionality as described in the general command line documentation
Burnup calculations
This takes the following form:
$ oscar5 MY_REACTOR.compose.my_module CUT_NAME generator [line] burn [options1] [mode] [options2]
Where:
line is the name of the burn line, which defaults to
'main'
if omitted.options1 are any standard application options.
mode is any of the standard application modes.
options2 any of the available options for the chosen mode.
For example, the typical usage sequence is (assuming the 'main'
burn line is targeted):
$ oscar5 MY_REACTOR.compose.my_module CUT_NAME generator burn --config-file my_config.cfg execute --threads 24
$ oscar5 MY_REACTOR.compose.my_module CUT_NAME generator burn --config-file my_config.cfg post
The
$ oscar5 MY_REACTOR.compose.my_module CUT_NAME generator burn post --show
command will open an interactive GUI, showing the burnup dependent \(k_{inf}\), and number densities for all
the microscopic_isotopes
.
Homogenization calculations
This takes the following form:
$ oscar5 MY_REACTOR.compose.my_module CUT_NAME generator [line] homogenization [branch] [options1] [mode] [options2]
Where:
line is the name of the burn line, which defaults to
'main'
if omitted.branch is the name of the geometry branch. If omitted, options1 and mode will be applied to all branches.
options1 are any standard application options.
mode is any of the standard application modes, or any burn step and/or off base case (see below).
options2 any of the available options for the chosen mode.
For example, the typical usage sequence is (assuming the 'main'
burn line is targeted):
$ oscar5 MY_REACTOR.compose.my_module CUT_NAME generator homogenization main --config-file my_config.cfg execute --threads 24
$ oscar5 MY_REACTOR.compose.my_module CUT_NAME generator homogenization main --config-file my_config.cfg post
which will launch all off base calculations at the selected depletion steps for the 'main'
branch. The calculations
at each burn step and off base conditions are available as sub modes burn-step-<i> and off-base-<i>. For example,
$ oscar5 MY_REACTOR.compose.my_module CUT_NAME generator homogenization main burn-step-0 --config-file my_config.cfg execute --force --threads 24
will recalculate all off base states for the base step (no burnup), and
$ oscar5 MY_REACTOR.compose.my_module CUT_NAME generator homogenization main burn-step-0 off-base-0 --config-file my_config.cfg execute --force --threads 24
will only recalculate the first off base condition at this step.