Automatically Extending a Parameter Study

Automatically Extending a Parameter Study#

Warning

The waves build feature is considered experimental. The feature should be treated like an alpha feature whose design, behavior, and interface may change without notice. This feature is documented to solicit user feedback on preferred behavior and usefulness.

Warning

This tutorial is in a draft outline state. It is provided as reference and will be fleshed out in future releases. Be sure to check back in on this tutorial or watch the Changelog for updates!

References#

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

    $ 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
    
  2. Activate the environment

    $ 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.

Directory Structure#

  1. Create and change to a new project root directory to house the tutorial files if you have not already done so. For example

$ mkdir -p ~/waves-tutorials
$ cd ~/waves-tutorials
$ pwd
/home/roppenheimer/waves-tutorials

Note

If you skipped any of the previous tutorials, run the following commands to create a copy of the necessary tutorial files.

$ pwd
/home/roppenheimer/waves-tutorials
$ waves fetch --overwrite --tutorial 7
WAVES fetch
Destination directory: '/home/roppenheimer/waves-tutorials'
$ waves fetch --overwrite 'tutorials/tutorial_07_sobol_sequence_SConstruct' 'tutorials/modsim_package/python/rectangle_compression_sobol_sequence.py' && mv tutorial_07_sobol_sequence_SConstruct SConstruct
WAVES fetch
Destination directory: '/home/roppenheimer/waves-tutorials'
  1. Download and copy the tutorial_07_sobol_sequence file to a new file named tutorial_extend_study with the WAVES Command-Line Utility fetch subcommand.

$ pwd
/home/roppenheimer/waves-tutorials
$ waves fetch --overwrite tutorials/tutorial_07_sobol_sequence && cp tutorial_07_sobol_sequence tutorial_extend_study
WAVES fetch
Destination directory: '/home/roppenheimer/waves-tutorials'

SConscript#

A diff against the tutorial_07_sobol_sequence file from Tutorial 07: Sobol Sequence is included below to help identify the differences between the two parameter generators.

waves-tutorials/tutorial_extend_study

--- /home/runner/work/waves/waves/build/docs/tutorials_tutorial_07_sobol_sequence
+++ /home/runner/work/waves/waves/build/docs/tutorials_tutorial_extend_study
@@ -9,6 +9,7 @@
   * ``abaqus`` - String path for the Abaqus executable
 """
 
+import copy
 import pathlib
 
 import waves
@@ -43,7 +44,6 @@
     previous_parameter_study=parameter_study_file,
     **kwargs,
 )
-parameter_generator.write()
 
 # Comment used in tutorial code snippets: marker-3
 
@@ -157,6 +157,39 @@
 
 # Comment used in tutorial code snippets: marker-6
 
+
+def write_parameter_study(target, source, env):
+    """`SCons Python build function`_ wrapper for the parameter generator's write() function.
+
+    Reference: https://scons.org/doc/production/HTML/scons-user/ch17s04.html
+    """
+    set_count = len(source)
+    if set_count < 8:
+        new_schema = copy.deepcopy(parameter_schema())
+        new_schema["num_simulations"] = set_count + 2
+        new_generator = waves.parameter_generators.SobolSequence(
+            new_schema,
+            output_file=parameter_study_file,
+            **kwargs,
+        )
+        new_generator.write()
+    else:
+        parameter_generator.write()
+    return None
+
+
+workflow.extend(
+    env.Command(
+        target=[parameter_study_file.name],
+        source=[
+            pathlib.Path(set_name) / "rectangle_compression.odb"
+            for set_name in parameter_generator.parameter_study_to_dict().keys()
+        ],
+        action=[write_parameter_study],
+        parameter_generator=parameter_generator,
+    )
+)
+
 # Collector alias based on parent directory name
 env.Alias(workflow_name, workflow)
 env.Alias(f"{workflow_name}_datacheck", datacheck)

SConstruct#

A diff against the SConstruct file from Tutorial 07: Sobol Sequence is included below to help identify the changes made in this tutorial.

waves-tutorials/SConstruct

--- /home/runner/work/waves/waves/build/docs/tutorials_tutorial_07_sobol_sequence_SConstruct
+++ /home/runner/work/waves/waves/build/docs/tutorials_tutorial_extend_study_SConstruct
@@ -106,6 +106,7 @@
     "tutorial_06_include_files",
     "tutorial_07_cartesian_product",
     "tutorial_07_sobol_sequence",
+    "tutorial_extend_study",
 ]
 for workflow in workflow_configurations:
     build_dir = env["variant_dir_base"] / workflow

Build Targets#

  1. Build the new targets

$ pwd
/home/roppenheimer/waves-tutorials
$ waves build --max-iterations=4 tutorial_extend_study --jobs=4

Output Files#

$ pwd
/home/roppenheimer/waves-tutorials
$ tree build/tutorial_extend_study -d
build/tutorial_extend_study
|-- parameter_set0
|-- parameter_set1
|-- parameter_set2
|-- parameter_set3
|-- parameter_set4
|-- parameter_set5
|-- parameter_set6
`-- parameter_set7

8 directories