Skip to main content
`Ctrl`+`K`

# Quickstart: Abaqus

This tutorial is also available with a fully open-source, conda-forge based compute environment using the Gmsh mesher and CalculiX FEA solver in Quickstart: Gmsh+CalculiX.

This quickstart will create a minimal, two file project configuration combining elements of the tutorials listed below.

- Tutorial 00: SConstruct

- Tutorial 01: Geometry

- Tutorial 02: Partition and Mesh

- Tutorial 03: SolverPrep

- Tutorial 04: Simulation

- Tutorial 05: Parameter Substitution

- Tutorial 07: Cartesian Product

- Tutorial 08: Data Extraction

- Tutorial 09: Post-Processing

These tutorials and this quickstart describe the computational engineering workflow through simulation execution and post-processing. This tutorial will use a different working directory and directory structure than the rest of the tutorials to avoid filename clashes. The quickstart also uses a flat directory structure to simplify the project configuration. Larger projects, like the ModSim Templates, may require a hierarchical directory structure to separate files with identical basenames.

## Environment

SCons and WAVES can be installed in a Conda environment with the Conda package manager. See the Conda installation and Conda environment management documentation for more details about using Conda.

Note

The SALib and numpy versions may not need to be this strict for most tutorials. However, Tutorial: Sensitivity Study uncovered some undocumented SALib version sensitivity to numpy surrounding the numpy v2 rollout.

1. Create the tutorials environment if it doesn’t exist

   Linux/MacOS

       $ conda create --name waves-tutorial-env --channel conda-forge waves 'scons>=4.6' matplotlib pandas pyyaml xarray seaborn 'numpy>=2' 'salib>=1.5.1' pytest

   Windows

       PS > conda create --name waves-tutorial-env --channel conda-forge waves scons matplotlib pandas pyyaml xarray seaborn numpy salib pytest

2. Activate the environment

   Linux/MacOS

       $ conda activate waves-tutorial-env

   Windows

       PS > conda activate waves-tutorial-env

Some tutorials require additional third-party software that is not available for the Conda package manager. This software must be installed separately and either made available to SConstruct by modifying your system’s `PATH` or by modifying the SConstruct search paths provided to the `waves.scons_extensions.add_program()` method.

Warning

STOP! Before continuing, check that the documentation version matches your installed package version.

1. You can find the documentation version in the upper-left corner of the webpage.

2. You can find the installed WAVES version with `waves --version`.

If they don’t match, you can launch identically matched documentation with the WAVES Command-Line Utility docs subcommand as `waves docs`.

## Directory Structure

3. Create the project directory structure and copy the WAVES quickstart source files into the `~/waves-tutorials/waves_quickstart` sub-directory with the WAVES Command-Line Utility fetch subcommand.

Linux/MacOS

    $ waves fetch tutorials/waves_quickstart --destination ~/waves-tutorials/waves_quickstart
    WAVES fetch
    Destination directory: '/home/roppenheimer/waves-tutorials/waves_quickstart'
    $ cd ~/waves-tutorials/waves_quickstart
    $ pwd
    /home/roppenheimer/waves-tutorials/waves_quickstart

Windows

    PS > waves fetch tutorials\waves_quickstart --destination $HOME\waves-tutorials\waves_quickstart
    WAVES fetch
    Destination directory: 'C:\Users\roppenheimer\waves-tutorials\waves_quickstart'
    PS > Set-Location $HOME\waves-tutorials\waves_quickstart
    PS > Get-Location

    Path
    ----
    C:\Users\roppenheimer\waves-tutorials\waves_quickstart

## SConscript

Managing digital data and workflows in modern computational science and engineering is a difficult and error-prone task. The large number of steps in the workflow and complex web of interactions between data files results in non-intuitive dependencies that are difficult to manage by hand. This complexity grows substantially when the workflow includes parameter studies. WAVES enables the use of traditional software build systems in computational science and engineering workflows with support for common engineering software and parameter study management.

Build systems construct a directed acyclic graph (DAG) from small, individual task definitions. Each task is defined by the developer and subsequently linked by the build system. Tasks are composed of targets, sources, and actions. A target is the output of the task. Sources are the required direct-dependency files used by the task and may be files tracked by the version control system for the project or files produced by other tasks. Actions are the executable commands that produce the target files. In pseudocode, this might look like a dictionary:

    task1:
        target: output1
        source: source1
        action: action1 --input source1 --output output1

    task2:
        target: output2
        source: output1
        action: action2 --input output1 --output output2

As the number of discrete tasks increases, and as cross-dependencies grow, an automated tool to construct the build order becomes more important. Besides simplifying the process of constructing the workflow DAG, most build systems also incorporate a state machine. The build system tracks the execution state of the DAG and will only re-build out-of-date portions of the DAG. This is especially valuable when trouble-shooting or expanding a workflow. For instance, when adding or modifying the post-processing step, the build system will not re-run simulation tasks that are computationally expensive and require significant wall time to solve.

The `SConscript` file below contains the workflow task definitions. Review the source and target files defining the workflow tasks. As discussed briefly above and in detail in Build System, a task definition also requires an action. For convenience, WAVES provides builders for common engineering software with pre-defined task actions. See the `waves.scons_extensions.abaqus_journal_builder_factory()` and `waves.scons_extensions.abaqus_solver_builder_factory()` for more complete descriptions of the builder actions.

waves_quickstart/SConscript

     1Import("env", "alias", "parameters")
     2
     3# Geometry
     4env.AbaqusJournal(
     5    target=["rectangle_geometry.cae", "rectangle_geometry.jnl"],
     6    source=["rectangle_geometry.py"],
     7    subcommand_options="--width ${width} --height ${height}",
     8    **parameters,
     9)
    10
    11# Partition
    12env.AbaqusJournal(
    13    target=["rectangle_partition.cae", "rectangle_partition.jnl"],
    14    source=["rectangle_partition.py", "rectangle_geometry.cae"],
    15    subcommand_options="--width ${width} --height ${height}",
    16    **parameters,
    17)
    18
    19# Mesh
    20env.AbaqusJournal(
    21    target=["rectangle_mesh.inp", "rectangle_mesh.cae", "rectangle_mesh.jnl"],
    22    source=["rectangle_mesh.py", "rectangle_partition.cae", "abaqus_utilities.py"],
    23    subcommand_options="--global-seed ${global_seed}",
    24    **parameters,
    25)
    26
    27# SolverPrep
    28env.CopySubstfile(
    29    ["#/rectangle_compression.inp.in"],
    30    substitution_dictionary=env.SubstitutionSyntax(parameters),
    31)
    32
    33# Abaqus Solve
    34env.AbaqusStandard(
    35    target=["rectangle_compression.odb"],
    36    source=["rectangle_compression.inp"],
    37    job="rectangle_compression",
    38    program_options="-double both",
    39    **parameters,
    40)
    41
    42# Abaqus Extract
    43env.AbaqusExtract(
    44    target=["rectangle_compression.h5", "rectangle_compression_datasets.h5"],
    45    source=["rectangle_compression.odb"],
    46)
    47
    48# Post-processing
    49target = env.PythonScript(
    50    target=["stress_strain.pdf", "stress_strain.csv"],
    51    source=["post_processing.py", "rectangle_compression_datasets.h5"],
    52    subcommand_options="--input-file ${SOURCES[1:].abspath} --output-file ${TARGET.file} --x-units mm/mm --y-units MPa",
    53)
    54
    55# Collector alias named after the model simulation
    56env.Alias(alias, target)
    57
    58if not env["unconditional_build"] and not env["ABAQUS_PROGRAM"]:
    59    print(f"Program 'abaqus' was not found in construction environment. Ignoring 'rectangle' target(s)")
    60    Ignore([".", alias], target)

## SConstruct

For this quickstart, we will not discuss the main SCons configuration file, named `SConstruct`, in detail. Tutorial 00: SConstruct has a more complete discussion about the contents of the `SConstruct` file.

One of the primary benefits to WAVES is the ability to robustly integrate the conditional re-building behavior of a build system with computational parameter studies. Because most build systems consist of exactly two steps: configuration and execution, the full DAG must be fixed at configuration time. To avoid hardcoding the parameter study tasks, it is desirable to re-use the existing workflow or task definitions. This could be accomplished with a simple for-loop and naming convention; however, it is common to run a small, scoping parameter study prior to exploring the full parameter space which would require careful set re-numbering to preserve previous work.

To avoid out-of-sync errors in parameter set definitions when updating a previously executed parameter study, WAVES provides a parameter study generator utility that uniquely identifies parameter sets by contents, assigns a unique index to each parameter set, and guarantees that previously executed sets are matched to their unique identifier. When expanding or re-executing a parameter study, WAVES enforces set name/content consistency which in turn ensures that the build system can correctly identify previous work and only re-build the new or changed sets.

In the configuration snippet below, the workflow parameterization is performed in the root configuration file, `SConstruct`. This allows us to re-use the entire workflow file, `SConscript`, with more than one parameter study. First, we define a nominal workflow. Nominal workflows can be defined as a simple dictionary. This can be useful for trouble-shooting the workflow, simulation definition, and simulation convergence prior to running a larger parameter study. Second, we define a small mesh convergence study where the only parameter that changes is the mesh global seed.

waves_quickstart/SConstruct

    78# Define parameter studies
    79nominal_parameters = {
    80    "width": 1.0,
    81    "height": 1.0,
    82    "global_seed": 1.0,
    83    "displacement": -0.01,
    84}
    85mesh_convergence_parameter_study_file = env["parameter_study_directory"] / "mesh_convergence.h5"
    86mesh_convergence_parameter_generator = waves.parameter_generators.CartesianProduct(
    87    {
    88        "width": [1.0],
    89        "height": [1.0],
    90        "global_seed": [1.0, 0.5, 0.25, 0.125],
    91        "displacement": [-0.01],
    92    },
    93    output_file=mesh_convergence_parameter_study_file,
    94    previous_parameter_study=mesh_convergence_parameter_study_file,
    95)
    96mesh_convergence_parameter_generator.write()

Finally, we call the workflow `SConscript` file in a loop where the study names and definitions are unpacked into the workflow call. The `ParameterStudySConscript` method handles the differences between a nominal parameter set dictionary and the mesh convergence parameter study object. The `SConscript` file has been written to accept the `parameters` variable that will be unpacked by this function.

waves_quickstart/SConstruct

     98# Add workflow(s)
     99workflow_configurations = [
    100    ("nominal", nominal_parameters),
    101    ("mesh_convergence", mesh_convergence_parameter_generator),
    102]
    103for study_name, study_definition in workflow_configurations:
    104    env.ParameterStudySConscript(
    105        "SConscript",
    106        variant_dir=env["build_dir"] / study_name,
    107        exports={"env": env, "alias": study_name},
    108        study=study_definition,
    109        subdirectories=True,
    110        duplicate=True,
    111    )

In this tutorial, the entire workflow is re-run from scratch for each parameter set. This simplifies the parameter study construction and enables the geometric parameterization hinted at in the `width` and `height` parameters. Not all workflows require the same level of granularity and re-use. There are resource trade-offs to workflow construction, task definition granularity, and computational resources. For instance, if the geometry and partition tasks required significant wall time, but are not part of the mesh convergence study, it might be desirable to parameterize within the `SConscript` file where the geometry and partition tasks could be excluded from the parameter study.

WAVES provides several solutions for parameterizing at the level of workflow files, task definitions, or in arbitrary locations and methods, depending on the needs of the project.

- workflow files: `waves.scons_extensions.parameter_study_sconscript()`

- task definitions: `waves.scons_extensions.parameter_study_task()`

- anywhere: `waves.parameter_generators.ParameterGenerator.parameter_study_to_dict()`

## Building targets

Note

You may need to pass the relative or absolute path to your Abaqus installation when running the workflow.

    scons --abaqus-command /path/to/executable/abaqus ...

You can also edit the SConstruct file contents below to include your Abaqus installation in the default search for an Abaqus executable.

waves_quickstart/SConstruct

    28default_abaqus_commands = [
    29    "/apps/abaqus/Commands/abq2024",
    30    "/usr/projects/ea/abaqus/Commands/abq2024",
    31    "abq2024",
    32    "abaqus",
    33]

The `waves.scons_extensions.WAVESEnvironment.AddProgram()` method performs an ordered preference search for executables by absolute and relative paths in the system `PATH`.

In `SConstruct`, the workflows were provided aliases matching the study names for more convenient execution. First, run the `nominal` workflow and observe the task command output as below. The default behavior of SCons is to report each task’s action as it is executed. WAVES builders capture the STDOUT and STDERR into per-task log files to aid in troubleshooting and to remove clutter from the terminal output. On first execution you may see a warning message as a previous parameter study is being requested which will only exist on subsequent executions.

Linux/MacOS

    $ pwd
    /home/roppenheimer/waves-tutorials/waves_quickstart
    $ scons nominal
    scons: Reading SConscript files ...
    Checking whether '/apps/abaqus/Commands/abq2024' program exists.../apps/abaqus/Commands/abq2024
    Checking whether '/usr/projects/ea/abaqus/Commands/abq2024' program exists...no
    Checking whether 'abq2024' program exists...no
    Checking whether 'abaqus' program exists...no
    scons: done reading SConscript files.
    scons: Building targets ...
    Copy("build/nominal/rectangle_compression.inp.in", "rectangle_compression.inp.in")
    Creating 'build/nominal/rectangle_compression.inp'
    cd /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal && /apps/abaqus/Commands/abq2024 cae -noGUI /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal/rectangle_geometry.py -- --width 1.0 --height 1.0 > /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal/rectangle_geometry.cae.stdout 2>&1
    cd /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal && /apps/abaqus/Commands/abq2024 cae -noGUI /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal/rectangle_partition.py -- --width 1.0 --height 1.0 > /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal/rectangle_partition.cae.stdout 2>&1
    cd /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal && /apps/abaqus/Commands/abq2024 cae -noGUI /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal/rectangle_mesh.py -- --global-seed 1.0 > /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal/rectangle_mesh.inp.stdout 2>&1
    cd /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal && /apps/abaqus/Commands/abq2024 -interactive -ask_delete no -job rectangle_compression -input rectangle_compression -double both > /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal/rectangle_compression.stdout 2>&1
    _build_odb_extract(["build/nominal/rectangle_compression.h5", "build/nominal/rectangle_compression_datasets.h5", "build/nominal/rectangle_compression.csv"], ["build/nominal/rectangle_compression.odb"])
    cd /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal && python /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal/post_processing.py --input-file /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal/rectangle_compression_datasets.h5 --output-file stress_strain.pdf --x-units mm/mm --y-units MPa > /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal/stress_strain.pdf.stdout 2>&1
    scons: done building targets.

Windows

    PS > Get-Location

    Path
    ----
    C:\Users\roppenheimer\waves-tutorials\waves_quickstart

    PS > scons nominal
    scons: Reading SConscript files ...
    Checking whether '/apps/abaqus/Commands/abq2024' program exists...no
    Checking whether '/usr/projects/ea/abaqus/Commands/abq2024' program exists...no
    Checking whether 'abq2024' program exists...C:\SIMULIA\Commands\abq2024.BAT
    Checking whether 'abaqus' program exists...C:\SIMULIA\Commands\abaqus.BAT
    scons: done reading SConscript files.
    scons: Building targets ...
    Copy("build\nominal\rectangle_compression.inp.in", "rectangle_compression.inp.in")
    Creating 'build\nominal\rectangle_compression.inp'
    cd C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal && C:\SIMULIA\Commands\abq2024.BAT cae -noGUI C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal\rectangle_geometry.py -- --width 1.0 --height 1.0 > C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal\rectangle_geometry.cae.stdout 2>&1
    cd C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal && C:\SIMULIA\Commands\abq2024.BAT cae -noGUI C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal\rectangle_partition.py -- --width 1.0 --height 1.0 > C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal\rectangle_partition.cae.stdout 2>&1
    cd C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal && C:\SIMULIA\Commands\abq2024.BAT cae -noGUI C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal\rectangle_mesh.py -- --global-seed 1.0 > C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal\rectangle_mesh.inp.stdout 2>&1
    cd C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal && C:\SIMULIA\Commands\abq2024.BAT -interactive -ask_delete no -job rectangle_compression -input rectangle_compression -double both > C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal\rectangle_compression.odb.stdout 2>&1
    _build_odb_extract(["build\nominal\rectangle_compression.h5", "build\nominal\rectangle_compression_datasets.h5", "build\nominal\rectangle_compression_datasets.h5", "build\nominal\rectangle_compression.csv"], ["build\nominal\rectangle_compression.odb"])
    cd C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal && python C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal\post_processing.py --input-file C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal\rectangle_compression_datasets.h5 --output-file stress_strain.pdf --x-units mm/mm --y-units MPa > C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal\stress_strain.pdf.stdout 2>&1
    scons: done building targets.

You will find the output files in the build directory. The final post-processing image of the uniaxial compression stress-strain curve is found in `stress_strain.pdf`.

Linux/MacOS

    $ pwd
    /home/roppenheimer/waves-tutorials/waves_quickstart
    $ ls build/nominal/stress_strain.pdf
    build/nominal/stress_strain.pdf

Windows

    PS > Get-Location

    Path
    ----
    C:\Users\roppenheimer\waves-tutorials\waves_quickstart

    PS > Get-ChildItem build\nominal\stress_strain.pdf

        Directory: C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal

    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    -a---             6/9/2023 4:32 PM          11311 stress_strain.pdf

Before running the parameter study, explore the conditional re-build behavior of the workflow by deleting the intermediate output file `rectangle_mesh.inp` and re-executing the workflow. You should observe that only the command which produces the orphan mesh `rectangle_mesh.inp` file is re-run. You can confirm by inspecting the time stamps of files in the build directory before and after file removal and workflow execution.

Linux/MacOS

    $ pwd
    /home/roppenheimer/waves-tutorials/waves_quickstart
    $ rm build/nominal/rectangle_mesh.inp
    $ scons nominal
    scons: Reading SConscript files ...
    Checking whether '/apps/abaqus/Commands/abq2024' program exists.../apps/abaqus/Commands/abq2024
    Checking whether '/usr/projects/ea/abaqus/Commands/abq2024' program exists...no
    Checking whether 'abq2024' program exists...no
    Checking whether 'abaqus' program exists...no
    scons: done reading SConscript files.
    scons: Building targets ...
    cd /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal && /apps/abaqus/Commands/abq2024 cae -noGUI /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal/rectangle_mesh.py -- --global-seed 1.0 > /home/roppenheimer/waves-tutorials/waves_quickstart/build/nominal/rectangle_mesh.inp.stdout 2>&1
    scons: `nominal' is up to date.
    scons: done building targets.

Windows

    PS > Get-Location

    Path
    ----
    C:\Users\roppenheimer\waves-tutorials\waves_quickstart

    PS > Remove-Item build\nominal\rectangle_mesh.inp
    PS > scons nominal
    scons: Reading SConscript files ...
    Checking whether '/apps/abaqus/Commands/abq2024' program exists...no
    Checking whether '/usr/projects/ea/abaqus/Commands/abq2024' program exists...no
    Checking whether 'abq2024' program exists...C:\SIMULIA\Commands\abq2024.BAT
    Checking whether 'abaqus' program exists...C:\SIMULIA\Commands\abaqus.BAT
    scons: done reading SConscript files.
    scons: Building targets ...
    cd C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal && C:\SIMULIA\Commands\abq2024.BAT cae -noGUI C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal\rectangle_mesh.py -- --global-seed 1.0 > C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\nominal\rectangle_mesh.inp.stdout 2>&1
    scons: `nominal' is up to date.
    scons: done building targets.

You should expect that the geometry and partition tasks do not need to re-execute because their output files still exist and they are upstream of the mesh task. But the tasks after the mesh task did not re-execute, either. This should be somewhat surprising. The simulation itself depends on the mesh file, so why didn’t the workflow re-execute all tasks from mesh to post-processing?

Many software build systems, such as GNU Make use file system modification time stamps to track DAG state [30]. By default the SCons state machine uses file signatures built from md5 hashes to identify task state. If the contents of the `rectangle_mesh.inp` file do not change, then the md5 signature on re-execution still matches the build state for the rest of the downstream tasks, which do not need to rebuild.

This default behavior of SCons makes it desirable for computational science and engineering workflows where downstream tasks may be computationally expensive. The added cost of computing md5 signatures during configuration is valuable if it prevents re-execution of a computationally expensive simulation. In actual practice, production engineering analysis workflows may include tasks and simulations with wall clock run times of hours to days. By comparison, the cost of using md5 signatures instead of time stamps is often negligible.

Now run the mesh convergence study as below. SCons uses the `--jobs` option to control the number of threads used in task execution and will run up to 4 tasks simultaneously.

Linux/MacOS

    $ scons mesh_convergence --jobs=4
    ...

Windows

    PS > scons mesh_convergence --jobs=4
    ...

The output is truncated, but should look very similar to the `nominal` output above, where the primary difference is that each parameter set is nested one directory lower using the parameter set number.

Linux/MacOS

    $ ls build/mesh_convergence/
    parameter_set0/  parameter_set1/  parameter_set2/  parameter_set3/

Windows

    PS > Get-ChildItem build\mesh_convergence\

        Directory: C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\mesh_convergence

    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    d----            6/9/2023  4:32 PM                parameter_set0
    d----            6/9/2023  4:32 PM                parameter_set1
    d----            6/9/2023  4:32 PM                parameter_set2
    d----            6/9/2023  4:32 PM                parameter_set3

These set names are managed by the WAVES parameter study object, which is written to a separate build directory for later re-execution. This parameter study file is used in the parameter study object construction to identify previously created parameter sets on re-execution.

Linux/MacOS

    $ ls build/parameter_studies/
    mesh_convergence.h5
    $ waves print_study build/parameter_studies/mesh_convergence.h5
                                            set_hash  width  height  global_seed  displacement
    set_name
    parameter_set0  cf0934b22f43400165bd3d34aa61013f    1.0     1.0        1.000         -0.01
    parameter_set1  ee7d06f97e3dab5010007d57b2a4ee45    1.0     1.0        0.500         -0.01
    parameter_set2  93de452cc9564a549338e87ad98e5288    1.0     1.0        0.250         -0.01
    parameter_set3  49e34595c98442a228efd9e9765f61dd    1.0     1.0        0.125         -0.01

Windows

    PS > Get-ChildItem build\parameter_studies\

        Directory: C:\Users\roppenheimer\waves-tutorials\waves_quickstart\build\parameter_studies

    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    -a---            6/9/2023  4:32 PM           9942 mesh_convergence.h5

    PS > waves print_study build\parameter_studies\mesh_convergence.h5
                                            set_hash  width  height  global_seed  displacement
    set_name
    parameter_set0  cf0934b22f43400165bd3d34aa61013f    1.0     1.0        1.000         -0.01
    parameter_set1  ee7d06f97e3dab5010007d57b2a4ee45    1.0     1.0        0.500         -0.01
    parameter_set2  93de452cc9564a549338e87ad98e5288    1.0     1.0        0.250         -0.01
    parameter_set3  49e34595c98442a228efd9e9765f61dd    1.0     1.0        0.125         -0.01

Try adding a new global mesh seed in the middle of the existing range. An example might look like the following, where the seed `0.4` is added between `0.5` and `0.25`.

SConstruct

    mesh_convergence_parameter_generator = waves.parameter_generators.CartesianProduct(
         {
            "width": [1.0],
            "height": [1.0],
            "global_seed": [1.0, 0.5, 0.4, 0.25, 0.125],
            "displacement": [-0.01],
        },
        output_file=mesh_convergence_parameter_study_file,
        previous_parameter_study=mesh_convergence_parameter_study_file
    )

Then re-run the parameter study. The new parameter set should build under the name `parameter_set4` and workflow should build only `parameter_set4` tasks. The parameter study file should also be updated in the build directory.

Linux/MacOS

    $ scons mesh_convergence --jobs=4
    $ ls build/mesh_convergence/
    parameter_set0/  parameter_set1/  parameter_set2/  parameter_set3/ parameter_set4/
    $ waves print_study build/parameter_studies/mesh_convergence.h5
                                            set_hash  width  height  global_seed  displacement
    set_name
    parameter_set0  cf0934b22f43400165bd3d34aa61013f    1.0     1.0        1.000         -0.01
    parameter_set1  ee7d06f97e3dab5010007d57b2a4ee45    1.0     1.0        0.500         -0.01
    parameter_set2  93de452cc9564a549338e87ad98e5288    1.0     1.0        0.250         -0.01
    parameter_set3  49e34595c98442a228efd9e9765f61dd    1.0     1.0        0.125         -0.01
    parameter_set4  4a49100665de0220143675c0d6626c50    1.0     1.0        0.400         -0.01

Windows

    PS > scons mesh_convergence --jobs=4
    PS > Get-ChildItem build\mesh_convergence\

        Directory: C:\Users\oppenheimer\waves-tutorials\waves_quickstart\build\mesh_convergence

    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    d----             6/9/2023 4:32 PM                parameter_set0
    d----             6/9/2023 4:32 PM                parameter_set1
    d----             6/9/2023 4:32 PM                parameter_set2
    d----             6/9/2023 4:32 PM                parameter_set3
    d----             6/9/2023 4:32 PM                parameter_set4

    PS > waves print_study build/parameter_studies/mesh_convergence.h5
                                            set_hash  width  height  global_seed  displacement
    set_name
    parameter_set0  cf0934b22f43400165bd3d34aa61013f    1.0     1.0        1.000         -0.01
    parameter_set1  ee7d06f97e3dab5010007d57b2a4ee45    1.0     1.0        0.500         -0.01
    parameter_set2  4a49100665de0220143675c0d6626c50    1.0     1.0        0.400         -0.01
    parameter_set3  93de452cc9564a549338e87ad98e5288    1.0     1.0        0.250         -0.01
    parameter_set4  49e34595c98442a228efd9e9765f61dd    1.0     1.0        0.125         -0.01

If the parameter study naming convention were managed by hand it would likely be necessary to add the new seed to the end of the parameter study to guarantee that the new set received a new set number. In practice, parameter studies are often defined programmatically as a `range()` or vary more than one parameter, which makes it difficult to predict how the set numbers may change. It would be tedious and error-prone to re-number the parameter sets such that the input/output relationships are consistent. In the best case, mistakes in set re-numbering would result in unnecessary re-execution of the previous parameter sets. In the worst case, mistakes could result in silent inconsistencies in the input/output relationships and lead to errors in result interpretations.

WAVES first looks for and opens the previous parameter study file saved in the build directory, reads the previous set definitions if the file exists, and then merges the previous study definition with the current definition along the unique set contents identifier coordinate. Under the hood, this unique identifier is an md5 hash of a string representation of the set contents, which is robust between systems with identical machine precision. To avoid long, unreadable hashes in build system paths, the unique md5 hashes are tied to the more human readable set numbers seen in the mesh convergence build directory.

## Output Files

An example of the full nominal workflow output files is found below using the `tree` command. If `tree` is not installed on your system, you can use the `find` command as `find build/nominal -type f`. If you run a similar command against the mesh convergence build directory you should see the same set of files repeated once per parameter set because the workflow definitions are identical for each parameter set.

Linux/MacOS

    $ pwd
    /home/roppenheimer/waves-tutorials/waves_quickstart
    $ tree build/nominal
    build/nominal
    |-- SConscript
    |-- abaqus.rpy
    |-- abaqus.rpy.1
    |-- abaqus.rpy.2
    |-- abaqus_utilities.py
    |-- post_processing.py
    |-- rectangle_compression.com
    |-- rectangle_compression.csv
    |-- rectangle_compression.dat
    |-- rectangle_compression.h5
    |-- rectangle_compression.inp
    |-- rectangle_compression.inp.in
    |-- rectangle_compression.msg
    |-- rectangle_compression.odb
    |-- rectangle_compression.prt
    |-- rectangle_compression.sta
    |-- rectangle_compression.stdout
    |-- rectangle_compression_datasets.h5
    |-- rectangle_geometry.cae
    |-- rectangle_geometry.cae.stdout
    |-- rectangle_geometry.jnl
    |-- rectangle_geometry.py
    |-- rectangle_mesh.cae
    |-- rectangle_mesh.inp
    |-- rectangle_mesh.inp.stdout
    |-- rectangle_mesh.jnl
    |-- rectangle_mesh.py
    |-- rectangle_partition.cae
    |-- rectangle_partition.cae.stdout
    |-- rectangle_partition.jnl
    |-- rectangle_partition.py
    |-- stress_strain.csv
    |-- stress_strain.pdf
    `-- stress_strain.pdf.stdout

    0 directories, 35 files

Windows

    PS > Get-Location

       Path
       ----
       C:\Users\roppenheimer\waves-tutorials\waves_quickstart

    PS > tree build\nominal /F
    C:\USERS\ROPPENHEIMER\WAVES-TUTORIALS\WAVES_QUICKSTART\BUILD\NOMINAL
        abaqus.rpy
        abaqus.rpy.1
        abaqus.rpy.2
        abaqus_utilities.py
        post_processing.py
        rectangle_compression.com
        rectangle_compression.csv
        rectangle_compression.dat
        rectangle_compression.h5
        rectangle_compression.inp
        rectangle_compression.inp.in
        rectangle_compression.msg
        rectangle_compression.odb
        rectangle_compression.odb.stdout
        rectangle_compression.prt
        rectangle_compression.sta
        rectangle_compression_datasets.h5
        rectangle_geometry.cae
        rectangle_geometry.cae.stdout
        rectangle_geometry.jnl
        rectangle_geometry.py
        rectangle_mesh.cae
        rectangle_mesh.inp
        rectangle_mesh.inp.stdout
        rectangle_mesh.jnl
        rectangle_mesh.py
        rectangle_partition.cae
        rectangle_partition.cae.stdout
        rectangle_partition.jnl
        rectangle_partition.py
        SConscript
        stress_strain.csv
        stress_strain.pdf
        stress_strain.pdf.stdout

    No subfolders exist

## Workflow Visualization

To visualize the workflow, you can use the WAVES visualize command. The `--output-file` allows you to save the visualization file non-interactively. Without this option, you’ll enter an interactive matplotlib window.

Linux/MacOS

    $ pwd
    /home/roppenheimer/waves-tutorials/waves_quickstart
    $ waves visualize nominal --output-file waves_quickstart.png --width=30 --height=6

Windows

    PS > Get-Location

    Path
    ----
    C:\Users\roppenheimer\waves-tutorials\waves_quickstart

    PS > waves visualize nominal --output-file waves_quickstart.png --width=30 --height=6

The workflow visualization should look similar to the image below, which is a representation of the directed graph constructed by SCons from the task definitions. The image starts with the final workflow target on the left, in this case the `nominal` simulation target alias. Moving left to right, the files required to complete the workflow are shown until we reach the original source file(s) on the far right of the image. The arrows represent actions and are drawn from a required source to the produced target. The Computational Practices introduction discusses the relationship of a Build System task and Directed graphs.