Tutorial 03: SolverPrep#
References#
Bash concepts used in this tutorial: Bash Variables, Bash Arrays, Bash Parameter Expansion [38]
Abaqus *INCLUDE keyword documentation [37]
SCons Pseudo-Builder and SCons Copy [32]
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.
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
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.
Warning
STOP! Before continuing, check that the documentation version matches your installed package version.
You can find the documentation version in the upper-left corner of the webpage.
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#
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 2 && mv tutorial_02_partition_mesh_SConstruct SConstruct
WAVES fetch
Destination directory: '/home/roppenheimer/waves-tutorials'
Fetch the
tutorial_02_partition_mesh
file and create a new file namedtutorial_03_solverprep
with the WAVES Command-Line Utility fetch subcommand.
$ pwd
/home/roppenheimer/waves-tutorials
$ waves fetch --overwrite tutorials/tutorial_02_partition_mesh && cp tutorial_02_partition_mesh tutorial_03_solverprep
WAVES fetch
Destination directory: '/home/roppenheimer/waves-tutorials'
Solver Input Files#
Fetch the WAVES tutorials abaqus source files into your existing
modsim_package/abaqus
sub-directory with the WAVES Command-Line Utility fetch subcommand.
$ pwd
/home/roppenheimer/waves-tutorials
$ waves fetch 'tutorials/modsim_package/abaqus/*.inp' --destination modsim_package/abaqus
WAVES fetch
Destination directory: 'modsim_package/abaqus'
This action will fetch the source files we included in the
tutorial_03_solverprep
file into the waves-tutorials/modsim_package/abaqus/
directory. Check the contents of this directory using the ls
command.
$ pwd
/home/roppenheimer/waves-tutorials
$ ls modsim_package/abaqus
abaqus_utilities.py history_output.inp rectangle_compression.inp
assembly.inp __init__.py rectangle_geometry.py
boundary.inp materials.inp rectangle_mesh.py
field_output.inp parts.inp rectangle_partition.py
SConscript#
Note
There is a large section of lines in the SConscript
file that are not included
before the next section of code shown here, as they are identical to those from
Tutorial 02: Partition and Mesh. The diff
of the SConscript
file at the
end of the SConscript section will demonstrate this
more clearly.
Modify your
tutorial_03_solverprep
file by adding the contents shown below immediately after the code pertaining to# Mesh
from the previous tutorial, and above the# Collector alias
code.
waves-tutorials/tutorial_03_solverprep
56# SolverPrep
57copy_source_list = [
58 "#/modsim_package/abaqus/rectangle_compression.inp",
59 "#/modsim_package/abaqus/assembly.inp",
60 "#/modsim_package/abaqus/boundary.inp",
61 "#/modsim_package/abaqus/field_output.inp",
62 "#/modsim_package/abaqus/materials.inp",
63 "#/modsim_package/abaqus/parts.inp",
64 "#/modsim_package/abaqus/history_output.inp",
65]
66workflow.extend(
67 env.CopySubstfile(
68 copy_source_list,
69 )
70)
The abaqus_source_list
contains the names of all the files that are used to build the Abaqus model. The
{model}_compression.inp
file is the primary input file, and the other files in the abaqus_source_list
are
included within it. See the Abaqus *INCLUDE keyword documentaiton [37] for more information about how
this is implemented.
Each file in the abaqus_source_list
is specified with its absolute path with the SCons #
project root feature
which is replaced by the parent directory of the SConstruct
file. After constructing the abaqus_source_list
, we
must first convert each string (which represent the absolute paths of each file in the list) to a Python pathlib
object. While not strictly neccessary for the waves.scons_extensions.copy_substfile()
pseudo-builder, the Python
pathlib objects are used elsewhere in the SConscript
file.
Just as in the previous tutorials, we now need to extend the workflow
list. Recall that we have already extended the
workflow three times - once each for the Geometry, Partition, and Mesh processes.
Unlike the AbaqusJournal
builder, the waves.scons_extensions.copy_substfile()
is not a builder, but an SCons
Pseudo-Builder which only requires the source file name(s). This is possible because the target file can be inferred
from the copy operation and build directory. With this pseudo-builder interface, it’s also possible to pass a list of
source files instead of defining a unique task for each item in the abaqus_source_list
. The
waves.scons_extensions.copy_substfile()
pseudo-builder will construct the per-file tasks automatically and return
the complete list of targets.
In summary of the changes you just made to the tutorial_03_solverprep
file, a diff
against the SConscript
file from Tutorial 02: Partition and Mesh is included below to help identify the changes made in this tutorial.
waves-tutorials/tutorial_03_solverprep
--- /home/runner/work/waves/waves/build/docs/tutorials_tutorial_02_partition_mesh
+++ /home/runner/work/waves/waves/build/docs/tutorials_tutorial_03_solverprep
@@ -54,6 +54,24 @@
# Comment used in tutorial code snippets: marker-3
+# SolverPrep
+copy_source_list = [
+ "#/modsim_package/abaqus/rectangle_compression.inp",
+ "#/modsim_package/abaqus/assembly.inp",
+ "#/modsim_package/abaqus/boundary.inp",
+ "#/modsim_package/abaqus/field_output.inp",
+ "#/modsim_package/abaqus/materials.inp",
+ "#/modsim_package/abaqus/parts.inp",
+ "#/modsim_package/abaqus/history_output.inp",
+]
+workflow.extend(
+ env.CopySubstfile(
+ copy_source_list,
+ )
+)
+
+# Comment used in tutorial code snippets: marker-4
+
# Collector alias based on parent directory name
env.Alias(workflow_name, workflow)
SConstruct#
Add
tutorial_03_solverprep
to theworkflow_configurations
list in theSConstruct
file.
A diff
against the SConstruct
file from Tutorial 02: Partition and Mesh is included below to help identify the
changes made in this tutorial.
waves-tutorials/SConstruct
--- /home/runner/work/waves/waves/build/docs/tutorials_tutorial_02_partition_mesh_SConstruct
+++ /home/runner/work/waves/waves/build/docs/tutorials_tutorial_03_solverprep_SConstruct
@@ -98,6 +98,7 @@
workflow_configurations = [
"tutorial_01_geometry",
"tutorial_02_partition_mesh",
+ "tutorial_03_solverprep",
]
for workflow in workflow_configurations:
build_dir = env["variant_dir_base"] / workflow
Build Targets#
Build the new targets
$ pwd
/home/roppenheimer/waves-tutorials
$ scons tutorial_03_solverprep
scons: Reading SConscript files ...
Checking whether /apps/abaqus/Commands/abq2024 program exists.../apps/abaqus/Commands/abq2024
Checking whether abq2024 program exists.../apps/abaqus/Commands/abq2024
scons: done reading SConscript files.
scons: Building targets ...
cd /home/roppenheimer/waves-tutorials/build/tutorial_03_solverprep && /apps/abaqus/Commands/abq2024 cae -noGui /home/roppenheimer/waves-tutorials/modsim_package/abaqus/rectangle_geometry.py -- > rectangle_geometry.cae.stdout 2>&1
cd /home/roppenheimer/waves-tutorials/build/tutorial_03_solverprep && /apps/abaqus/Commands/abq2024 cae -noGui /home/roppenheimer/waves-tutorials/modsim_package/abaqus/rectangle_partition.py -- > rectangle_partition.cae.stdout 2>&1
cd /home/roppenheimer/waves-tutorials/build/tutorial_03_solverprep && /apps/abaqus/Commands/abq2024 cae -noGui /home/roppenheimer/waves-tutorials/modsim_package/abaqus/rectangle_mesh.py -- > rectangle_mesh.inp.stdout 2>&1
Copy("build/tutorial_03_solverprep/rectangle_compression.inp", "modsim_package/abaqus/rectangle_compression.inp")
Copy("build/tutorial_03_solverprep/assembly.inp", "modsim_package/abaqus/assembly.inp")
Copy("build/tutorial_03_solverprep/boundary.inp", "modsim_package/abaqus/boundary.inp")
Copy("build/tutorial_03_solverprep/field_output.inp", "modsim_package/abaqus/field_output.inp")
Copy("build/tutorial_03_solverprep/materials.inp", "modsim_package/abaqus/materials.inp")
Copy("build/tutorial_03_solverprep/parts.inp", "modsim_package/abaqus/parts.inp")
Copy("build/tutorial_03_solverprep/history_output.inp", "modsim_package/abaqus/history_output.inp")
scons: done building targets.
Output Files#
Explore the contents of the build
directory using the tree
command against the
build
directory, as shown below.
$ pwd
/home/roppenheimer/waves-tutorials
$ tree build/tutorial_01_geometry/ build/tutorial_02_partition_mesh/ build/tutorial_03_solverprep/
build/tutorial_01_geometry/
|-- abaqus.rpy
|-- rectangle_geometry.cae
|-- rectangle_geometry.cae.stdout
`-- rectangle_geometry.jnl
build/tutorial_02_partition_mesh/
|-- abaqus.rpy
|-- abaqus.rpy.1
|-- abaqus.rpy.2
|-- rectangle_geometry.cae
|-- rectangle_geometry.cae.stdout
|-- rectangle_geometry.jnl
|-- rectangle_mesh.cae
|-- rectangle_mesh.inp
|-- rectangle_mesh.inp.stdout
|-- rectangle_mesh.jnl
|-- rectangle_partition.cae
|-- rectangle_partition.cae.stdout
`-- rectangle_partition.jnl
build/tutorial_03_solverprep/
|-- abaqus.rpy
|-- abaqus.rpy.1
|-- abaqus.rpy.2
|-- assembly.inp
|-- boundary.inp
|-- field_output.inp
|-- history_output.inp
|-- materials.inp
|-- parts.inp
|-- rectangle_compression.inp
|-- rectangle_geometry.cae
|-- rectangle_geometry.cae.stdout
|-- rectangle_geometry.jnl
|-- rectangle_mesh.cae
|-- rectangle_mesh.inp
|-- rectangle_mesh.inp.stdout
|-- rectangle_mesh.jnl
|-- rectangle_partition.cae
|-- rectangle_partition.cae.stdout
`-- rectangle_partition.jnl
0 directories, 36 files
Inside the build directory are three sub-directories. tutorial_01_geometry
and
tutorial_02_partition_mesh
remain from the previous two tutorials. The third
directory, tutorial_03_solverprep
, pertains to the targets we just built.
It is worth noting that the tutorial_03_solverprep
build directory contains all the
files from the previous two tutorials. The additional files are the files from the
abaqus_source_list
that were acted on with the waves.scons_extensions.copy_substfile()
pseudo-builder. In this case, the files were simply copied into the build directory with no
modification to the source code. Tutorial 05: Parameter Substitution will discuss
how parameters can be inserted into these solver input files.
Workflow Visualization#
View the workflow directed graph by running the following command and opening the image in your preferred image viewer.
$ pwd
/home/roppenheimer/waves-tutorials
$ waves visualize tutorial_03_solverprep --output-file tutorial_03_solverprep.png --width=28 --height=5 --exclude-list /usr/bin .stdout .jnl
The output should look similar to the figure below.

Compared to Tutorial 02: Partition and Mesh, the workflow has grown significantly. Of course, if you were managing
this workflow manually, the source *.inp
files would probably be managed as a single file. Here, the files are split
in anticipation of larger modsim projects where a simulation may be recombined with many variations of materials, parts,
boundary conditions, or loading steps. The piecewise nature of the input file minimizes data duplication over simulation
combinations.
For the tutorials, the piecewise input files also fill in as a surrogate to demonstrate the large number of files found in modsim projects of moderate to large complexity and in modsim projects with large parameter studies. In practice, the modsim owner should balance priorities of code duplication and repository file count for the needs of the projects and organization. While it’s tempting to reduce duplication to a minimum, there may be good reasons to provide clean separation between simulation input definitions. There is also an on-boarding cost found with many separate, re-usable files and the associated high file count. Regardless, the modsim repository directory structure and design choices should be documented in a developer manual with regular updates to match the existing implementation.