Getting Started#
What is watts
?#
WATTS (Workflow and Template Toolkit for Simulation) consists of a set of Python classes that can manage simulation workflows for one or multiple codes. It provides the following capabilities:
An isolated execution environment when running a code;
The ability to use placeholder values in input files that are filled in programmatically;
Seamless unit conversions when working with multiple codes;
A managed database that simulation inputs and outputs are automatically saved to; and
Python classes that provide extra post-processing and analysis capabilities for each code.
Basic Execution#
There are four major types of classes within watts
. The
Plugin
class (and its subclasses) provide the main interface to
codes. As an example, let’s say we have the following input file for MCNP that
we want to run:
Bare sphere of plutonium
1 1 0.04 -1 imp:n=1
2 0 1 imp:n=0
1 so 6.5
m1 94239.70c 0.04
kcode 10000 1.0 50 150
ksrc 0 0 0
If the filename of the input file is sphere_model
, we start by creating a
watts.PluginMCNP
object:
plugin_mcnp = watts.PluginMCNP("sphere_model")
Calling the plugin class then executes the code:
result = plugin_mcnp()
When a plugin is called, any input files are copied to a temporary directory to
create an isolated execution environment. Once the code is finished executing,
all input and output files are moved to a database, and you are provided a
Results
object that provides an interface to the simulation
artifacts and methods for common post-processing tasks. In the example above,
calling the PluginMCNP
instance returns a
ResultsMCNP
object, which we can use to get a list of the output
files or determine the resulting \(k_\text{eff}\) value:
>>> result.outputs
[PosixPath('MCNP_log.txt'),
PosixPath('srctp')
PosixPath('outp')
PosixPath('runtpe')]
>>> result.keff
1.0007+/-0.00053
Templates and Parameters#
The input file shown above is just a normal MCNP input file. However, you can
also put placeholders in an input file and have watts
fill them in using
the Parameters
class. Let’s say we change the input file as
follows:
Bare sphere of plutonium
1 1 0.04 -1 imp:n=1
2 0 1 imp:n=0
1 so {{ radius }}
m1 94239.70c 0.04
kcode 10000 1.0 50 {{ cycles }}
ksrc 0 0 0
We’ve added two placeholders, {{ radius }}
and {{ cycles }}
, that will
be filled in. Before creating and calling our plugin, we now need to specify
these parameters:
params = watts.Parameters()
params['radius'] = 6.0
params['cycles'] = 200
As before, we create an instance of PluginMCNP
but instead of
calling it with no arguments, we pass it the Parameters
instance:
plugin_mcnp = watts.PluginMCNP("sphere_model")
result = plugin_mcnp(params)
If we wanted to run this model with a series of different radii, it’s now as simple as changing the corresponding parameter and calling the plugin:
for r in [2.0, 4.0, 6.0, 8.0, 10.0]:
params['radius'] = r
result = plugin_mcnp(params)
Results Database#
Results are automatically added to a database and persist between invocations of
Python. For the example above, we may want to look at the last five results to
see how \(k_\text{eff}\) varies with the radius. The
Database
class provides a list-like object that contains all
previously generated Results
objects:
>>> database = watts.Database()
>>> database
[<ResultsMCNP: 2022-06-01 13:21:44.713942>,
<ResultsMCNP: 2022-06-01 13:23:12.410774>,
<ResultsMCNP: 2022-06-02 07:46:05.463723>,
<ResultsMCNP: 2022-06-02 07:46:10.996932>,
<ResultsMCNP: 2022-06-02 07:46:17.487411>,
<ResultsMCNP: 2022-06-02 07:46:24.964455>,
<ResultsMCNP: 2022-06-02 07:46:33.426781>]
This enables us to easily look at the \(k_\text{eff}\) value for the last five MCNP simulations:
>>> [result.keff for result in database[-5:]]
[0.3523+/-0.00021,
0.68017+/-0.00042,
0.97663+/-0.00063,
1.24086+/-0.00075,
1.47152+/-0.00081]