Available Plugins#
MOOSE Plugin#
The PluginMOOSE
class enables MOOSE simulations using a
templated input file. This is demonstrated here for a SAM application, but the
plugin would apply equally well to other MOOSE applications such as BISON. For a
MOOSE-based application, a templated input file might look as follows:
[GlobalParams]
global_init_P = {{ He_Pressure }}
global_init_V = {{ He_velocity }}
global_init_T = {{ He_inlet_temp }}
gravity = '-9.8 0 0'
scaling_factor_var = '1 1e-3 1e-6'
Tsolid_sf = 1e-3
[]
If the templated input file is sam_template.inp
, the SAM code will rely on
the general MOOSE plugin that can be created as:
moose_plugin = watts.PluginMOOSE('sam_template.inp')
If you need to specify additional input files / templates, see Specifying Input Files.
The MOOSE plugin defaults to using the executable moose-opt
but can also be
specified explicitly
moose_plugin = watts.PluginMOOSE(..., executable="/path/to/sam-opt")
OpenMC Plugin#
The PluginOpenMC
class operates slightly differently than other
plugins since OpenMC doesn’t primarily rely on text-based inputs. For OpenMC,
inputs are generated programmatically through the OpenMC Python API. Instead of
writing a text template, for this plugin you need to write a function that
accepts an instance of Parameters
and generates the necessary
XML files. For example:
def jezebel_model(params):
model = openmc.Model()
pu_metal = openmc.Material()
pu_metal.add_nuclide('Pu239', 3.7047e-02)
pu_metal.add_nuclide('Pu240', 1.7512e-03)
pu_metal.add_nuclide('Pu241', 1.1674e-04)
pu_metal.add_element('Ga', 1.3752e-03)
model.materials.append(pu_metal)
sph = openmc.Sphere(r=params['radius'], boundary_type='vacuum')
cell = openmc.Cell(fill=pu_metal, region=-sph)
model.geometry = openmc.Geometry([cell])
model.settings.batches = 50
model.settings.inactive = 10
model.settings.particles = 1000
model.export_to_xml()
With this function, the PluginOpenMC
class can be
instantiated:
openmc_plugin = watts.PluginOpenMC(godiva_model)
Note how the function object itself is passed to the plugin. When the
PluginOpenMC()
instance is called, the “template” function is
called and passed the user-specified Parameters
:
params = watts.Parameters(radius=6.0)
results = openmc_plugin(params)
This will generate the OpenMC input files using the template parameters, run
OpenMC, and collect the results. Note that any extra keyword arguments passed to
the plugin are forwarded to the openmc.run()
function. For example:
results = openmc_plugin(params, mpi_args=["mpiexec", "-n", "16"])
By default, the OpenMC plugin will only call the openmc.run()
function,
but you can customize the execution by passing an arbitrary function as the
function
keyword argument. For example, if you wanted to additionally call
openmc.plot_geometry()
each time the plugin is called, this could be
accomplished as follows:
import openmc
def run_function():
openmc.plot_geometry()
openmc.run()
results = openmc_plugin(params, function=run_function)
PyARC Plugin#
The PluginPyARC
class handles PyARC execution in a similar
manner to the PluginMOOSE
class for MOOSE. PyARC use text-based
input files which can be templated as follows:
surfaces{
hexagon ( hex ){ orientation=y normal = z pitch = {{ assembly_pitch }} }
plane ( z0 ) { z = 0.0 }
plane ( z10 ) { z = {{ assembly_length }} }
}
If the templated input file is pyarc_template, then the PyARC plugin can be instantiated with following command line:
pyarc_plugin = watts.PluginPyARC('pyarc_template')
The path to the PyARC module can be specified explicitly:
pyarc_plugin = watts.PluginPyARC(
'pyarc_template',
executable="/path/to/PyARC/PyARC.py"
)
To execute PyARC, the PluginPyARC()
instance is called directly the
same way as other plugins. Extra input files and templates can be specified as
described in Specifying Input Files.
SAS4A/SASSY-1 Plugin#
The PluginSAS
class handles SAS4A/SASSY-1 execution in a similar
manner to the PluginMOOSE
class for MOOSE. SAS4A/SASSY-1 uses
text-based input files which can be templated as follows:
47 1 {{ flow_per_pin }}
3 1 {{ total_reactor_power }}
7 1 {{ tmax }}
If the templated input file is sas_template, then the SAS4A/SASSY-1 plugin can be instantiated with the following command line:
sas_plugin = watts.PluginSAS('sas_template')
The name of the SAS executable is OS-dependent. It defaults to sas.x
but can
be changed if you are running on Windows:
sas_plugin = watts.PluginSAS('sas_template', executable='sas.exe')
Furthermore, the paths to the SAS utilities that convert the “.dat” files to
“.csv” files must be specified with the conv_channel
and conv_primar4
attributes:
sas_plugin.conv_channel = "/path/to/CHANNELtoCSV.x"
sas_plugin.conv_primar4 = "/path/to/PRIMAR4toCSV.x"
By default, the plugin will try to find these utilities based on the location of
the SAS executable. To execute SAS, the PluginSAS()
instance is
called directly in the same way as other plugins.
The SAS plugin can sometimes generates multiple “.csv” files. The data from each “.csv” file are saved into an individual dictionary named after the file, and these individual dictionaries are saved under csv_data. To access a specific data, you can do:
sas_result.csv_data['name_of_csv_file']['name_of_specific_data']
RELAP5-3D Plugin#
The PluginRELAP5
class handles execution of RELAP5-3D. Note that
the plugin is designed for the execution of RELAP5-3D v4.3.4 and thus may not be
compatible with other version of RELAP5-3D. RELAP5-3D uses text-based input
files that can be templated as follows:
* Time Power
20250001 -1.0 0.0
20250002 0.0 {{ heater_power_1 }}
20250003 1.0e3 {{ heater_power_2 }}
If the templated input file is relap5_template, then the RELAP5-3D plugin can be instantiated with the following command line:
relap5_plugin = watts.PluginRELAP5('relap5_template')
RELAP5-3D requires the executable, license key, and the input file to be in the
same directory to run. Thus, before running the RELAP5-3D plugin, you need to
specify the directory that the executable and the license key are in (they must
be in the same directory). This can be done by adding the RELAP5_DIR
variable to the environment or by explicitly specifying the path in the Python
script as:
relap5_plugin.relap5_dir = "/path/to/relap5_dir/"
The RELAP5 executable is OS-dependent. It defaults to relap5.x
(assumed to
be present on your PATH
) for Linux and macOS, and relap5.exe
for
Windows.
As with other plugins, extra input files and templates can be specified as
described in Specifying Input Files. Note that the fluid property files can be
specified via extra_args
. Another approach is to simply put them in the same
directory as the executable and license key before running the plugin.
For the postprocessing of RELAP5-3D results, the plugin converts the default “plotfl” plot file generated by RELAP5-3D into a “.CSV” file. Card-104 must be specified as “ascii” in the RELAP5-3D input file as:
104 ascii
to ensure that the “plotfl” is in ASCII format instead of the default binary
format. As the conversion process could be computationally expensive, user can
turn it off by omitting Card-104 in the RELAP5-3D input file and adding
plotfl_to_csv=False
when instantiating the plugin as follows:
relap5_plugin = watts.PluginRELAP5('relap5_template', plotfl_to_csv=False)
MCNP Plugin#
The PluginMCNP
class handles execution of MCNP. As with other
plugins, MCNP input files can be templated as described in
Templated Inputs. By default, this plugin will try to call mcnp6
but
this can be changed if needed:
mcnp_plugin = watts.PluginMCNP('mcnp_input', executable='mcnp5')
Natural Element Expansion#
The PluginMCNP
class allows you to specify natural elements in
MCNP material definitions that are automatically expanded based on what
naturally occurring isotopes appear in your xsdir
file. In your templated
MCNP input file, this feature can be utilized by adding a filter section:
{% filter expand_element %}
m1 24000.70c -0.17
26000.70c -0.79
28000.70c -0.10
42000.70c -0.02
{% endfilter %}
Natural elements can be represented using the standard ZAID identifiers as above (e.g., 26000 represents natural iron) or using their atomic symbol:
{% filter expand_element %}
m1 Cr.70c -0.17
Fe.70c -0.79
Ni.70c -0.10
Mo.70c -0.02
{% endfilter %}
The expand_element
custom filter also accepts a single argument specifying
what cross section suffix to apply by default when one is missing:
{% filter expand_element('70c') %}
m1 Cr -0.17
Fe -0.79
Ni -0.10
Mo -0.02
{% endfilter %}
By default, PluginMCNP
will look for the xsdir
file found
under the directory specified by the DATAPATH
environment variable to
determine what nuclides are available. However, you can explicitly specify a
different xsdir
file at the time PluginMCNP
is
instantiated:
mcnp_plugin = watts.PluginMCNP('mcnp_input', xsdir='xsdir_jendl5')
Serpent Plugin#
The PluginSerpent
class handles execution of Serpent 2. As with
other plugins, Serpent input files can be templated as described in
Templated Inputs. By default, this plugin will try to call sss2
. After
running Serpent:
serpent_plugin = watts.PluginSerpent('serpent_input')
result = serpent_plugin()
the Serpent output files will be available to you through the
outputs
attribute:
>>> result.outputs
[PosixPath('serpent_input_det0.m'),
PosixPath('serpent_log.txt'),
PosixPath('serpent_input.seed'),
PosixPath('serpent_input.out'),
PosixPath('serpent_input_res.m')]
At this point, we recommend using the serpentTools package for interacting with the output files. For example:
results_reader = serpentTools.ResultsReader(str(result.outputs[-1]))
ABCE Plugin#
The PluginABCE
class enables simulations with the Agent Based Capacity
Expansion (ABCE) code using a templated input file. Since watts
relies on the Jinja templating engine, any parameter in the ABCE settings
file could be updated with watts
. For example:
num_steps: {{ N_STEPS }} # The number of timesteps
run_ALEAF: {{ run_ALEAF }} # Toggles the A-LEAF dispatch model
natural_gas_price: {{ NATURAL_GAS_PRICE }} # Sets the price of natural gas in [$/MMBTU]
conv_nuclear_FOM: {{ NFOM_VALUE }} # Sets the fixed operating costs of conventional nuclear plants.
As with other plugins, PluginABCE
is easily used by:
abce_plugin = watts.PluginABCE(template_file, show_stdout=True, show_stderr=True)
abce_result = abce_plugin(params, extra_args=['-f'])
Note
ABCE is still under active development.
Dakota Plugin#
The PluginDakota
class handles execution of Dakota. Dakota uses
text-based input files that can be templated as follows:
real = {{ real }}
work_directory named = {{ workdir }}
Note that the execution of the Dakota plugin is slightly different and involves more steps than the execution of the other plugins. Dakota is an optimization and uncertainty quantification tool that needs to be coupled to other external tools or software.
The execution of Dakota with WATTS is a two-step process. In the first step, WATTS creates Dakota’s input file using the user-provided template and runs Dakota. In the second step, Dakota drives the execution of the coupled code (PyARC, SAM, SAS, etc.) via a Python script known as the “Dakota driver”. The Dakota driver also facilitates the exchange of information between Dakota and the coupled code. Note that this is done through Dakota’s interfacing library. The user needs to ensure that this library is available prior to running Dakota with WATTS.
To run Dakota with WATTS, the user needs to provide a number of files including the input file for Dakota, the WATTS Python script for executing Dakota, the input file for the coupled code, the WATTS script for executing the coupled code (note that this can involve complex workflows with several codes or iterations), and the Dakota driver Python script, in addition to any file necessary to run the coupled code. Note that all of these files could be templated automatically by WATTS using the template_file and extra_template_inputs options, provided they are text-based.
If the templated Dakota input file is dakota_watts_opt.in, then the Dakota plugin can be instantiated with the following command line:
dakota_plugin = watts.PluginDakota('dakota_watts_opt.in')
If the coupled code has a text-based input file, users can also template this file (or other necessary files) with the extra_template_inputs options:
dakota_plugin = watts.PluginDakota(
template_file='dakota_watts_opt.in',
extra_template_inputs=['extra_template_file_name', 'other_necessary_files'])
During the execution of WATTS, the working directory is switched to a temporary location. Non-templated files needed by the coupled code (license file, data file, etc.) can be copied to the temporary location with the extra_inputs option:
dakota_plugin = watts.PluginDakota(
template_file='dakota_watts_opt.in',
extra_template_inputs=['extra_template_file_name', 'other_necessary_files'],
extra_inputs=['file_1', 'file_2'])
In the Dakota input file, users need to provide the names of required files to the link_files or the copy_files options where these files will be copied by Dakota to the working directory during each iteration. Users can choose to input the names of these files manually or they can choose to have WATTS automatically include all file names in the extra_template_inputs and extra_inputs options. To do so, simply use the auto_link_files option:
dakota_plugin = watts.PluginDakota(
template_file='dakota_watts_opt.in',
extra_template_inputs=['extra_template_file_name', 'other_necessary_files'],
auto_link_files='<string_name_for_files>',
extra_inputs=['file_1', 'file_2'])
And set:
link_files = {{ <string_name_for_files> }}
in the Dakota input file. Note that the same <string_name_for_files> must be used in the two locations mentioned above.
As mentioned earlier, Dakota drives the execution of the coupled code through a Python script known as the Dakota driver. A template for the Dakota driver is provided in the example. Just like the other files mentioned earlier, the Dakota driver can also be templated using the approach described above.
Furthermore, the path to the ‘dakota.sh’ shell script
needs to be provided either by setting the DAKOTA_DIR
environment
variable to the directory containing dakota.sh or by adding it through the
input file as:
dakota_plugin.dakota_exec = "path/to/dakota.sh"
Once the execution is complete, WATTS saves the results from all iterations as
individual objects and the final results as a separate object known as finaldata1
in the Parameters
class.
The setup of WATTS-Dakota coupling is more involved than other codes. Users are strongly encouraged to visit the example case Optimization_PyARC_DAKOTA for detailed explanation on how to prepare the input files.
Note: Users are advised to use Dakota v6.18 or latest, as earlier versions may potentially lead to complications or issues with WATTS.
ACCERT Plugin#
The PluginACCERT
class enables simulations with the Algorithm for the
Capital Cost Estimation of Reactor Technologies (ACCERT) code using a templated input
file such as the following:
power(Thermal){ value = {{ thermal_power }} unit = MW }
power(Electric){ value = {{ electric_power }} unit = MW }
l0COA(2){
l1COA(21){
l2COA(217){
total_cost{value = {{ cost_217 }} unit = dollar}
}
}
}
Before running the ACCERT plugin, the directory that the executable ‘Main.py’
must be set. This can be done by adding the ACCERT_DIR
variable to the environment:
export ACCERT_DIR='/path/to/accert/src'
Or the path to the ACCERT module can be specified explicitly:
accert_plugin = watts.PluginACCERT(
'accert_template',
executable="/path/to/accert/src/Main.py"
)
As with other plugins, PluginACCERT
is used by:
accert_plugin = watts.PluginACCERT('accert_template')
accert_result = accert_plugin(params)