The basic auto-compose module
Basic structure of the auto-compose module
In order to accelerate the development of a nodal model, and in cases where typical assumptions are made in the model preparation, an option exists to automate the construction of the nodal model - namely the auto-compose interface. It should be noted that this interface does not stand independent of the rest of the compose system, but simply builds upon it. The user can still include any traditional compose input into an auto-compose input file.
The auto-compose philosophy relies on a single input file to define a complete and usable nodal model. This includes the full-core nodalisation, as well as the nodalisation for each of the loadable components. For more information on the general philosophy of the compose and auto-compose process please consult the OSCAR-5 tutorial set, and specifically Tutorial 2 part B.
Auto-compose is structured into two kinds of input blocks - one input block for the full core nodalisation, and one additional input block per loadable component.
Looking firstly at the generic input block for the full core nodalisation, the following structure is required:
parameters = AutoCompose()
#set series of parameter values
....
....
....
parameters.build_compose_model()
Note
This block refers to the development of a nodalisation of the full core, from which nodal cross-sections for non-loadable components will be taken. Not all cross-sections from this full core nodalisation will necessarily be used, as nodal cross-sections for loadable components will be generated in approximate environments and will then replace cross-sections from the full core model as these components are loaded into the core.
This block introduces two important constructs:
- AutoCompose()
Defines a full-core auto-compose application.
- Returns:
An auto-compose model application for defining the full-core nodal model
- parameters.build_compose_model()
Process the set of defined parameters, auto-generate all necessary core cuts (active and reflector), generate compose test cases and construct full-core nodal models. These compose models are then ready to go through the typical compose path, such as generator, library, equivalence, reconf, deploy and test.
- Returns:
An auto-compose model application for defining the full-core nodal model
In the section between these two constructs, a series of parameter values are specified to define the nodal model. Following this block, one additional input block is required per loadable component. The basic structure of of the loadable component is given by:
loadable_component = parameters.create_loadable()
...
...
...
loadable_component.build_compose_model()
Each loadable is created, and connected to the parent structure via:
- parameters.create_loadable()
Defines a loadable component sub-application, and inherits relevant properties from the defined core nodal model. Inherited properties may be overwritten per loadable.
- Returns:
A compose model application for defining the nodalisation of the loadable component
Attention
As the loadable component inherits relevant parameters from the parent compose application, it must be defined after the call to
parameters.build_compose_model
.
- loadable_component.build_compose_model()
Process the set of defined parameters, auto-generate necessary loadable cuts (active and reflector), auto-generate replacement cases and construct loadable component nodal model. These loadable compose models are then ready to go through the typical compose process relevant to loadables, such as generator, library and equivalence.
- Returns:
An auto-compose model application for defining the full-core nodal model
Setting the full-core nodal parameters
This section describes the series of input keywords which can be set within the full-core part of the application -
thus to be placed between the parameters = AutoCompose()
and parameters.build_compose_model()
constructs.
- working_directory
: str default:N/A
This variable has to be set, and defines the top level working directory for the full-core nodal model. Furthermore, the name given to the top level of the working directory is taken as the project name, and the first two letters of the project name is automatically used as naming tag for the nodal model within the rapyds system.
A typical example of the usage of this parameter:
parameters.working_directory = utilities.path_relative_to(__file__,'CORE')
- heterogeneous_model
: ModelBuilder default:N/A
This variable has to be set, and defines the underlying heterogeneous reactor model to be used for this core
A typical example of the usage of this parameter:
parameters.heterogeneous_model = model
- homogenization_grid
: labeledgrid default:N/A
This variable has to be set, and defines the overlay radial grid on which nodal cross-sections should be generated
A typical example of the usage of this parameter:
parameters.homogenization_grid = \ [['0' ,'W2','W1', '1', '2', '3', 'E1', 'E2'], ['N2', 0, 0, 0, 0, 0, 0, 0], ['N1', 0, 0, 0, 0, 0, 0, 0], ['A' , 0, 0, 1, 1, 1, 0, 0], ['B' , 0, 0, 1, 2, 1, 0, 0], ['C' , 0, 0, 1, 1, 0, 0, 0], ['S1', 0, 0, 0, 0, 0, 0, 0], ['S2', 0, 0, 0, 0, 0, 0, 0]]The grid is labelled with the desired row and column labels, must should match row and column labels assigned to loadable positions in the heterogeneous model for the sake of retrieving component types which reside in these positions.
Non-zero entries entries in this grid are utilized to identify loadable positions, with positions of the same component type filled with the same integer identifier. Each loadable component block will typically refer to an unique index in this grid.
- homogenization_grid_pitches
: list of lists default:N/A
This variable has to be set, and defines the grid sizes associated with the
homogenization_grid
A typical example of the usage of this parameter:
parameters.homogenization_grid_pitches = [[7.71 * units.cm] * 7, [8.1 * units.cm] * 7]
- homogenization_grid_center
: point default:
(0,0,0)
The parameter defines the center of the homogenization grid.
A typical example of the usage of this parameter:
parameters.homogenization_grid_center = parameters.heterogeneous_model.pool.core_center
- boundary_condition
: BoundaryCondition default:vacuum
The parameter defines the boundary condition to be placed at the outer edge of the homogenization grid
A typical example of the usage of this parameter:
parameters.set_boundary_condition(boundary_conditions.albedo)Typical values for this parameter include
reflective
,vacuum
oralbedo
. In the case of the latter, albedo boundary conditions will be extracted from the full core cut transport calculations. However, in the current implementation, the albedo boundary conditions will be averaged over the available set of active core cuts to produce a single set of radial position- and energy-dependent boundary conditions applied to all axial layers.
- homogenization_axial_mesh
Each tuple is given as: [label<str>, height<float>]
This variable has to be set, and defines the overlay axial grid on which nodal cross-sections should be generated. Each entry defines a single 2D core cut (either active or reflector - which is automatically deduced) which will be axially stacked to build the 3D nodal model. This axial grid is floating, and has to be anchored by setting the
axial_mesh_bottom
.A typical example of the usage of this parameter:
parameters.homogenization_axial_mesh = \ [['TO' , 10 * units.cm], ['TI' , 10 * units.cm], ['ACT', 59.37 * units.cm], ['BI' , 10 * units.cm], ['BO' , 10 * units.cm]]The mesh is specified from top to bottom.
- axial_mesh_bottom
: float default:0.0
The parameter defines the distance from the heterogeneous model zero position (which is typically at the center of the active core) to the bottom of the
homogenization_axial_mesh
A typical example of the usage of this parameter:
parameters.axial_mesh_bottom = (-59.37 / 2 - 20) * units.cm
- add_test
: bool default:False
This parameter defines whether 3D tests should be added to the generated nodal model
A typical example of the usage of this parameter:
parameters.add_test = True
- isotopes
: list default:see example below
Define the set of isotopes to deplete microscopically in the nodal model.
A typical example of the usage of this parameter:
self._isotopes = \ ['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']
- set_state(fuel_temperature, moderator_temperature, moderator_density, rodded=False)
Defines the state of the core model to be used for homogenization - in particular fuel temperature, moderator temperature, moderator density and the position of the control rods.
- Parameters:
fuel_temperature – StateParameter: The nominal fuel temperature
moderator_temperature – StateParameter: The nominal moderator temperature
moderator_density – StateParameter: The nominal moderator density
rodded – bool: True of False to set the rodded state of the core
- Returns:
N/A
A typical example of the usage of this parameter:
parameters.set_state(fuel_temperature = 60 * units.degC, moderator_density=LightWater.density_at(40 * units.degC,1.8 * units.bars), moderator_temperature=40 * units.degC)This method is used to over-ride the nominal core state set in the core configuration and is optional here.
Setting the loadable component parameters
Since a loadable component is simply another compose application, it requires, in principle, the same input as the full-core nodal model. However, given that we know for which core model the loadable is intended, a large amount of the loadable component information can be directly inherited from the full-core application.
The following parameters must be defined for each loadable, and if they are by default inherited from the core model, the default value of the parameter will be indicated as inherited.
- working_directory
: str default:N/A
This variable has to be set, and defines the top level working directory for the loadable nodal model. It should differ from the the full-core working directory, as it will be created alongside it.
A typical example of the usage of this parameter:
loadable.working_directory = utilities.path_relative_to(__file__,'INF_F')The first six letters of the name of the loadable working directory will be extracted for the nodal component base file name and should be unique.
- homogenization_axial_mesh
: list of tuple default:inherited
This parameter is inherited from the full-core nodalisation if not specified.
Each tuple is given as: [label<str>, height<float>, optional: HED file <str>]
This variable has to be set, and defines the overlay axial grid on which nodal cross-sections should be generated. Each entry defines a single 2D loadable cut (either active or reflector - which is automatically deduced) which will be axially stacked to build the 3D loadable nodal model. This axial grid is floating, and has to be anchored by setting the
axial_mesh_bottom
, which is also inherited from the full-core model.Note here an additional optional tuple component containing the name of an external HED file which will then be imported as cross-section set for that given layer of this specific loadable, as opposed to the cross-sections calculated from the defined cut. This is useful if a HED file has already been produced with an external lattice code, typically for a fuel mixture.
It is also possible to specify: Each tuple is given as: [label<str>, height<float>, mixture <mixture>] when importing a mixture directly from another compose application, such as a compose lattice cut.
A typical example of the usage of this parameter:
loadable.homogenization_axial_mesh = \ [['TO' , 10 * units.cm], ['TI' , 10 * units.cm], ['ACT', 59.37 * units.cm, utilities.path_relative_to(__file__, '../model/lattice/FUEL_LEU----.HED')], ['BI' , 10 * units.cm], ['BO' , 10 * units.cm]]The mesh is specified from top to bottom.
- axial_mesh_bottom
: float default:inherited
This parameter is inherited from the full-core nodalisation if not specified.
The parameter defines the distance from the heterogeneous model zero position (which is typically at the center of the active core) to the bottom of the
homogenization_axial_mesh
A typical example of the usage of this parameter:
loadable.axial_mesh_bottom = (-59.37 / 2 - 20) * units.cm
- grid_id
: int default:N/A
This parameter must be specified, and it must be a legal grid id from the set of non-zero ids given in the full-core
homogenization_grid
. Based on the selected grid id, thehomogenization_grid_pitches
for the loadable will be set, and the instance of the actual heterogeneous component will be extracted.A typical example of the usage of this parameter:
loadable.grid_id = 1
- component
: Assembly default:inherited
This parameter is by default populated by matching the heterogeneous component residing in the core grid at the position of the
grid_id
. However, if for some reason it is desired to explicitly define the component otherwise, it is supported. This might be the case when the core grid is populated directly from the facility loading database (see setting thetime_stamp
parameter). In such cases it may not be clear where a given component type resides. The component can then be set here.A typical example of the usage of this parameter:
loadable.component = assemblies.fuel_assembly_batch_1()
- external_lattice
: str default:N/A
This parameter defines, if given, a previously generated HED file (if string) or mixture (if mixture type) to be applied as mixture for all active nodal cross-section layers in the loadable assembly.
A typical example of the usage of this parameter:
loadable.external_lattice = utilities.path_relative_to(__file__, '../model/lattice/FUEL_LEU----.HED')
- lattice_calculation
: bool default:False
This parameter defines whether this auto-compose module will generate a full input specification for a fuel lattice calculation, as opposed to importing a pre-generated lattice mixture or HED file. This option requires the specification of a number of further parameters to define the lattice calculation, for example the burn-up and off-base ranges of the target assembly. Currently the automated lattice calculation only supports infinite lattice calculations.
A typical example of the usage of this parameter:
loadable.lattice_calculation = True
- colourset_type
: LatticeType default: InfiniteLattice
The parameter defines the environment in which the target assembly will be homogenized. The default and only automated option currently supported is the InfiniteLattice option. However, if a non-infinite-lattice mixture has been created via an external/compose lattice calculation, such a HED file or mixture may be imported in the auto-compose module either via the
homogenization_axial_mesh
orexternal_lattice
parameters.This parameter is of particular use when the
lattice_calculation
parameter is set to True, and additional cards are specified to launch a compose lattice calculation, as opposed to importing a previously generated mixture or HED fileIn future this card will include the option to trigger the auto-generation of non-infinite lattice coloursets in 3x3 environments directly from full-core model.
A typical example of the usage of this parameter:
loadable.colourset_type = InfiniteLattice
- assembly_type
: AssemblyType default: assembly.fueled
This parameter sets the assembly type to be assigned to the nodal assembly model for this loadable. Typical values would be
assembly.fueled
,assembly.control
orassembly.intra_assembly_control
A typical example of the usage of this parameter:
loadable.assembly_type = assembly.fueled
- burn_meshes
: int default: 8
This parameter defines the number of burn-up meshes to be assigned to each active cut in the axial cut structure for this loadable.
A typical example of the usage of this parameter:
loadable.burn_meshes = 8
- core_mixtures
Each tuple is given as: [label<str>, position<str>, rod_pos <Travel>]
Each tuple entry defines a layer from the loadable under consideration, for which nodal cross-sections should not be taken from the generated 2D cut of this loadable, but rather from a new cut from the full-core nodalisation. This option exists specifically for non-fuel layers for which a infinite environment approximatation of that loadable layer would insufficiently accurate, and where a more realistic environment is needed for for homogenization. The control rod position is allowed to specified here to ensure proper placement of the mixture in question in the core, and the auto-compose module will automatically add the new full-core cut to the already defined set of full-core cuts. The appropriate mixture will then be extracted from the specified core position and used when the nodal model for this loadable is constructed.
A typical example of the usage of this parameter:
loadable.core_mixtures = \ [['ABS', 'B2', control.percentage_inserted(30.0)], ['CPL', 'B2', control.percentage_inserted(30.0)]]This card is typically needed when generating control-rod absorber cross-sections for follower type control assemblies
- use_as_core_mesh
: bool default: False
This parameter sets defines whether this loadable should be used to extract the core neutronic calculational mesh from. As it is good practice to align the neutronic calculational mesh with the typical core depletion mesh, the user can decide from which loadable to extract this mesh, as the depletion mesh is allocated per loadable (see the
burn_meshes
card)Although such an alignment between material and calculational meshes is not theoretically required due to the use of the axial homogenization scheme in the nodal solver, it does produce a more stable numerical solution when aligned.
If no loadable has this parameter set to true, the axial neutronic mesh will be extracted from the first loadable.
A typical example of the usage of this parameter:
loadable.use_as_core_mesh = True
- intra_control_rod
: Assembly default: None
This parameter is defined along with asemblies of type
intra_assembly_control
and indicates which component should be inserted into the assembly when it is rodded. The component must be specified as information such as travel distance of the rod is extracted from this heterogeneous component definition. If this component is not specified, auto-compose will attempt to fetch the control rod component from the loaded state of the intra-control fuel assembly into which it is intended for insertion, but this may fail if the rod was not actually loaded during the construction of the intra control fuel assembly component. It is therefor better practice to specify this parameter.A typical example of the usage of this parameter:
loadable.intra_control_rod = assemblies.control_rod_element()
- seating
: float default: 0.0 cm
This parameter defines any additional seating you would like to apply to the loadable component, which will shift its base position, relative to the overall core model, axially. This is typically only needed for control rod type components, for which the nodal model must be re-seated to its full-in position. If not specified, control rod components will be reseated with the assumption that the rod tip matches the top of the actice core when fully extracted.
A typical example of the usage of this parameter:
loadable.seating = 18.75 * units.cm
Running the auto-compose module
The running of the commands for the auto-compose module is identical to that of of normal compose commands (see Running a cOMPoSe application module from the terminal. There is however one exception. Since both the full-core nodalisation and loadable component definitions reside in the same input file, you have to specify on which of these you intend to operate as an additional mode in the command. The mode name is defined by the project name of the component, which was automatically extracted from the working directory of the full-core or loadable blocks. For example, to see which modes are available, you could still use:
$ oscar5 MY_REACTOR.compose.my_auto_module --help
This should give you the name of your cull-core project, and names of your loadable as options. If you then want to proceed to, for example run the library mode on all cuts in your full-core model (lets say you named it CORE), you would enter:
$ oscar5 MY_REACTOR.compose.my_auto_module CORE library
If you named one of your loadables (or rather named its working directory) MYFUEL, you could run library mode on all cuts in your MYFUEL loadable with:
$ oscar5 MY_REACTOR.compose.my_auto_module MYFUEL library
In this way all standard compose commands would then follow.