Tutorial 01: Geometry#

Prerequisites#

  1. Computational Practices - Build System

  2. Software Carpentry: GNU Make - https://swcarpentry.github.io/make-novice/ [1, 9, 30]

  3. Software Carpentry: Python - https://swcarpentry.github.io/python-novice-inflammation/ [1, 8]

References#

Below is a list of references for more information about topics that are not explicitly covered in this tutorial.

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.

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#

  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 0 && mv tutorial_00_SConstruct SConstruct
WAVES fetch
Destination directory: '/home/roppenheimer/waves-tutorials'
  1. Within the waves-tutorials directory, create a new directory called modsim_package/abaqus. For example, in a bash shell:

$ pwd
/home/roppenheimer/waves-tutorials
$ mkdir -p modsim_package/abaqus
  1. Create Python module initialization files to create a project specific local Python package.

waves-tutorials/modsim_package/__init__.py and waves-tutorials/modsim_package/abaqus/__init__.py

$ pwd
/home/roppenheimer/waves-tutorials
$ waves fetch tutorials/modsim_package/__init__.py tutorials/modsim_package/abaqus/__init__.py --destination modsim_package
$ find . -name "__init__.py"
./modsim_package/__init__.py
./modsim_package/abaqus/__init__.py

SConscript File#

An SConscript file defines sources, actions, and targets. Sources are files that exist in the source repository, such as Abaqus journal files. Actions define how to process source files, for example executing the Abaqus command. Targets are the output artifacts created by the action, such as an Abaqus model file. It is also worth noting that the SConscript file naming convention is case sensitive. In this tutorial, we will build the geometry for a rectangle part using the waves.scons_extensions.abaqus_journal_builder_factory() builder from the waves.scons_extensions.WAVESEnvironment construction environment (click the builder’s name to link to the WAVES SCons Extensions API).

  1. Create an SConscript file with the non-default name tutorial_01_geometry using the contents below.

waves-tutorials/tutorial_01_geometry

 1#! /usr/bin/env python
 2"""Rectangle compression workflow
 3
 4Requires the following ``SConscript(..., exports={})``
 5
 6* ``env`` - The SCons construction environment with the following required keys
 7
 8  * ``unconditional_build`` - Boolean flag to force building of conditionally ignored targets
 9  * ``abaqus`` - String path for the Abaqus executable
10"""
11
12import pathlib
13
14# Inherit the parent construction environment
15Import("env")
16
17# Simulation variables
18build_directory = pathlib.Path(Dir(".").abspath)
19workflow_name = build_directory.name

The SConscript file begins with imports of standard Python libraries. The first highlighted line imports the env variable (Import('env')), which is a variable set in waves-tutorials/SConstruct file. The env variable defines project settings, and is imported so settings variables are not hard-coded more than once.

  1. Continue editing the file tutorial_01_geometry using the contents below.

waves-tutorials/tutorial_01_geometry

22# Collect the target nodes to build a concise alias for all targets
23workflow = []
24
25# Geometry
26workflow.extend(
27    env.AbaqusJournal(
28        target=["rectangle_geometry.cae", "rectangle_geometry.jnl"],
29        source=["#/modsim_package/abaqus/rectangle_geometry.py"],
30        subcommand_options="",
31    )
32)

First, the workflow variable is assigned to an empty list. Eventually, workflow will become a list of targets to build. Every time we instruct SCons to build a target or targets, we will extend this list and finally create an alias that matches the parent directory name. The alias thus represents the list of targets specified in the SConscript file.

The final block of code instructs SCons on how to build the targets, an Abaqus CAE file and an Abaqus journal file. The source file is specified as an absolute path using the SCons feature # which refers to the project root directory. Using an absolute path allows us to run the journal file without copying it to the build directory. The SCons # feature allows us to construct an absolute path that is correct with respect to the current SConstruct file location even if the project is moved or copied somewhere else on the filing system. subcommand_options allows for parameters to be passed as command-line arguments to the journal file. Using the journal file’s command-line interface with the subcommand_options string will be discussed in Tutorial 05: Parameter Substitution.

Next, the workflow list is extended to include the action to use the waves.scons_extensions.abaqus_journal_builder_factory() builder, as discussed in Tutorial 00: SConstruct. For more information about the behavior of the waves.scons_extensions.abaqus_journal_builder_factory() builder, click the builder’s link or see the WAVES SCons Extensions API. The target list specifies the files created by the waves.scons_extensions.abaqus_journal_builder_factory() task’s action, which is defined in the SCons Extensions API.

  1. Continue editing the file tutorial_01_geometry using the contents below.

waves-tutorials/tutorial_01_geometry

36# Collector alias based on parent directory name
37env.Alias(workflow_name, workflow)
38
39if not env["unconditional_build"] and not env["ABAQUS_PROGRAM"]:
40    print(f"Program 'abaqus' was not found in construction environment. Ignoring '{workflow_name}' target(s)")
41    Ignore([".", workflow_name], workflow)

First, we create an alias for the workflow that was extended previously to match the name of the current file, which will double as the build directory name: tutorial_01_geometry.

The final lines of code in this SConscript file allow SCons to skip building a target sequence if the Abaqus executable is not found.

Abaqus Journal File#

Now that you have an overview of the SConscript file and how SCons uses an Abaqus journal file, let’s create the geometry part build file for the rectangle model.

The following sections of this tutorial will introduce four software-engineering practices that match the build system philosophy. These concepts will be presented sequentially, starting with familiar Abaqus Python code, and adding in the following:

  • Protecting your code within a main() function

  • Writing docstrings for your Python code

  • Adding a command-line interface to your Python code

  • Protecting main() function execution and returning exit codes

  1. In the modsim_package/abaqus directory, create a file called rectangle_geometry.py using the contents below which contains the main() function.

waves-tutorials/modsim_package/abaqus/rectangle_geometry.py

 1import os
 2import sys
 3import inspect
 4import argparse
 5
 6import abaqus
 7import abaqusConstants
 8
 9
10def main(output_file, model_name, part_name, width, height):
11    """Create a simple rectangle geometry.
12
13    This script creates a simple Abaqus model with a single rectangle part.
14
15    :param str output_file: The output file for the Abaqus model. Will be stripped of the extension and ``.cae`` will be
16        used.
17    :param str model_name: The name of the Abaqus model
18    :param str part_name: The name of the Abaqus part
19    :param float width: The rectangle width
20    :param float height: The rectangle height
21
22    :returns: writes ``output_file``.cae and ``output_file``.jnl
23    """
24    output_file = os.path.splitext(output_file)[0] + ".cae"
25
26    abaqus.mdb.Model(name=model_name, modelType=abaqusConstants.STANDARD_EXPLICIT)
27
28    sketch = abaqus.mdb.models[model_name].ConstrainedSketch(name=part_name, sheetSize=1.0)
29    sketch.setPrimaryObject(option=abaqusConstants.STANDALONE)
30    sketch.rectangle(point1=(0.0, 0.0), point2=(width, height))
31    sketch.unsetPrimaryObject()
32
33    part = abaqus.mdb.models[model_name].Part(
34        name=part_name,
35        dimensionality=abaqusConstants.TWO_D_PLANAR,
36        type=abaqusConstants.DEFORMABLE_BODY,
37    )
38    part.BaseShell(sketch=sketch)
39
40    abaqus.mdb.saveAs(pathName=output_file)

It is important to note that rectangle_geometry.py is, indeed, an Abaqus journal file - even though it does not look like a journal file produced by an Abaqus CAE GUI session.

main Functions#

The top of the file imports standard library modules used by the script’s functions along with Abaqus modules. The main() function takes in several arguments, like model_name, part_name, and some geometric parameters for the rectangle part. Most notable of the inputs to the main() function is the first input argument - output_file. One can simplify the general concept of a build system into a series of inputs (known as sources) and outputs (known as targets). In this case, the output_file is the target which is created from the source - the rectangle_geometry.py file.

Python Docstrings#

The highlighted lines of code at the beginning of the main() function are called a docstring. Docstrings are specially formatted comment blocks that help automate documentation builds. In this case, the docstrings are formatted so the Sphinx automodule directive can interpret the comments as ReStructured Text. Docstrings discuss the function behavior and its interface. See the PEP-257 conventions for docstring formatting along with PEP-287 for syntax specific to reStructured Text. Using the Sphinx automodule directive, the docstring can be used to autobuild documentation for your functions. An example of this is in the WAVES-TUTORIAL API for rectangle_geometry.py.

Abaqus Python Code#

The latter portion of the main() function is the code that generates the rectangle geometry. Here, an Abaqus model is opened using the model_name variable as the model’s name, a rectangle is drawn with dimensions width and height, and the Abaqus CAE model is saved with the name output_file. One notable difference between the Abaqus Scripting documentation [37] of Abaqus journal files is the use of the PEP-8 style guide for package imports. Here, we order the imports according to the PEP-8 style and avoid bulk imports to the file’s namespace from Abaqus Python packages. It is also worth noting that Abaqus journal files use the Abaqus Python environment not the SCons Python environment. See the Abaqus Python Environment documentation [37] for more information on the Abaqus Python environment, noting that prior to Abaqus 2024, Abaqus shipped with Python 2.7 instead of Python 3. The tutorials in this project supply journal files compatible with both Python 2.7 and Python 3.

Command-Line Interfaces#

  1. In the modsim_package/abaqus directory, continue editing the file called rectangle_geometry.py using the contents below containing the get_parser() function. Note that missing line numbers may be ignored.

waves-tutorial/modsim_package/abaqus/rectangle_geometry.py

 44def get_parser():
 45    """Return parser for CLI options
 46
 47    All options should use the double-hyphen ``--option VALUE`` syntax to avoid clashes with the Abaqus option syntax,
 48    including flag style arguments ``--flag``. Single hyphen ``-f`` flag syntax often clashes with the Abaqus command
 49    line options and should be avoided.
 50
 51    :returns: parser
 52    :rtype: argparse.ArgumentParser
 53    """
 54    # The global '__file__' variable doesn't appear to be set when executing from Abaqus CAE
 55    filename = inspect.getfile(lambda: None)
 56    basename = os.path.basename(filename)
 57    basename_without_extension, extension = os.path.splitext(basename)
 58    # Construct a part name from the filename less the workflow step suffix
 59    default_part_name = basename_without_extension
 60    suffix = "_geometry"
 61    if default_part_name.endswith(suffix):
 62        default_part_name = default_part_name[: -len(suffix)]
 63    # Set default parameter values
 64    default_output_file = "{}".format(basename_without_extension)
 65    default_width = 1.0
 66    default_height = 1.0
 67
 68    prog = "abaqus cae -noGui {} --".format(basename)
 69    cli_description = "Create a simple rectangle geometry and write an ``output_file``.cae Abaqus model file."
 70    parser = argparse.ArgumentParser(description=cli_description, prog=prog)
 71    parser.add_argument(
 72        "--output-file",
 73        type=str,
 74        default=default_output_file,
 75        # fmt: off
 76        help="The output file for the Abaqus model. "
 77             "Will be stripped of the extension and ``.cae`` will be used, e.g. ``output_file``.cae",
 78        # fmt: on
 79    )
 80    parser.add_argument(
 81        "--model-name",
 82        type=str,
 83        default=default_part_name,
 84        help="The name of the Abaqus model",
 85    )
 86    parser.add_argument(
 87        "--part-name",
 88        type=str,
 89        default=default_part_name,
 90        help="The name of the Abaqus part",
 91    )
 92    parser.add_argument(
 93        "--width",
 94        type=float,
 95        default=default_width,
 96        help="The rectangle width. Positive float.",
 97    )
 98    parser.add_argument(
 99        "--height",
100        type=float,
101        default=default_height,
102        help="The rectangle height. Positive float.",
103    )
104    return parser

This portion of rectangle_geometry.py defines the argument parsing function, get_parser(), which is the next step in turning our simple Python script into a small software utility. Command-line interfaces allow for scripts to be executed with optional command-line arguments. This allows us to change the values of input arguments to the main() function without any source code modification. argparse also helps automate command-line interface (CLI) documentation. An example of this is the WAVES-TUTORIAL CLI for rectangle_geometry.py. See the Argparse tutorial for an introduction to the argparse module.

The first highlighted portion of the get_parser() function defines variables based on the name of the script. While this method of determining the file name is non-standard for Python 3, the Abaqus Python 2.7 environment necessitates this syntax. This code will become common boilerplate code included in every Abaqus journal file created in the tutorials. It is valuable to the behavior of these example journal files, but may not be required for all journal files depending on their designed behavior.

The code that follows uses the name of the script to define some variables. This code assumes that the part_name variable will be equal to the name of the script and will remove the _geometry suffix if it exists in the file name.

The default values and naming conventions in this journal file are modsim project design decisions made for the WAVES tutorials and ModSim Templates. In practice, it may be beneficial to choose different default behavior depending on the design of the modsim project.

The second highlighted portion defines default values for some of the command-line arguments. Default values are assigned if no command-line argument is detected for any of the expected command-line arguments. This provides sensible defaults even when no command-line arguments are specified. It should be noted, however, that some model developers may prefer to require all command-line arguments every time the file is used to build a target. output_file is the name of the file that is created at the end of the main() function, which assumes output_file does not include a file extension. default_width and default_height define the size of the rectangle part.

The final highlighted portion of the code is where the argparse package is used to define the argument parser rules. First, an argument parser is defined using the ArgumentParser class. This receives a brief description cli_description and direction prog on how to execute the program. Each subsequent call of the add_argument method adds a command-line argument to the parser’s rules. Command-line arguments defined using argparse have options, like -o or --output-file, and arguments. Arguments can also have default values. argparse also allows for command line argument definitions to include a help message that is used to auto-generate the command’s help message. See the Python argparse documentation for more information.

In this case, we are using argparse in an Abaqus Python script, which will use Python 2.7. See the Python 2.7 argparse documentation for more information about how argparse will behave in an Abaqus journal file.

  1. In the modsim_package/abaqus directory, continue editing the file called rectangle_geometry.py using the contents below to create the if statement within which we will call the main() function. Note that missing line numbers may be ignored.

waves-tutorials/modsim_package/abaqus/rectangle_geometry.py

110if __name__ == "__main__":
111    parser = get_parser()
112    # Abaqus does not strip the CAE options, so we have to skip the unknown options related to the CAE CLI.
113    try:
114        args, unknown = parser.parse_known_args()
115    except SystemExit as err:
116        sys.exit(err.code)
117    # Check for typos in expected arguments. Assumes all arguments use ``--option`` syntax, which is unused by Abaqus.
118    possible_typos = [argument for argument in unknown if argument.startswith("--")]
119    if len(possible_typos) > 0:
120        raise RuntimeError("Found possible typos in CLI option(s) {}".format(possible_typos))
121
122    sys.exit(
123        main(
124            output_file=args.output_file,
125            model_name=args.model_name,
126            part_name=args.part_name,
127            width=args.width,
128            height=args.height,
129        )
130    )

Top-Level Code Environment#

When the script is executed, an internal variable __name__ is set to the value __main__. When this condition is true (i.e. the script is being executed rather than being imported), the code inside of main() is executed. __main__ is referred to as the top-level code environment. Top-level code is also referred to as the entry point of the program. See the Python Top-Level Code Environment documentation for more information.

The first lines within the if __name__ == "__main__" context call the get_parser() method and use argparse to separate known and unknown command-line arguments. This is required for Abaqus journal files, because Abaqus will not strip the CAE options from the abaqus cae -nogui command, which are irrelevant to and unused by the journal file interface.

Retrieving Exit Codes#

The main() function is called from within the sys.exit() method. This provides the operating system with a non-zero exit code if the script throws an error. By convention, non-zero exit codes indicate an error in the executing program. See the Bash Exit Status documentation for more information about specific exit codes. This is used by build systems to understand when a target has not been produced correctly and to exit the downstream sequence of target actions which can no longer succeed.

Entire Abaqus Journal File#

Shown below is rectangle_geometry.py in its entirety. The highlighted lines show the non-boilerplate code that will change between journal files in the tutorials. As discussed in preceding sections, some portions of the boilerplate code are required for modsim project best practice when using a build system such as SCons and other sections are boilerplate code that matches naming conventions used by the tutorials, but that may change in production modsim projects.

waves-tutorials/modsim_package/abaqus/rectangle_geometry.py

  1import os
  2import sys
  3import inspect
  4import argparse
  5
  6import abaqus
  7import abaqusConstants
  8
  9
 10def main(output_file, model_name, part_name, width, height):
 11    """Create a simple rectangle geometry.
 12
 13    This script creates a simple Abaqus model with a single rectangle part.
 14
 15    :param str output_file: The output file for the Abaqus model. Will be stripped of the extension and ``.cae`` will be
 16        used.
 17    :param str model_name: The name of the Abaqus model
 18    :param str part_name: The name of the Abaqus part
 19    :param float width: The rectangle width
 20    :param float height: The rectangle height
 21
 22    :returns: writes ``output_file``.cae and ``output_file``.jnl
 23    """
 24    output_file = os.path.splitext(output_file)[0] + ".cae"
 25
 26    abaqus.mdb.Model(name=model_name, modelType=abaqusConstants.STANDARD_EXPLICIT)
 27
 28    sketch = abaqus.mdb.models[model_name].ConstrainedSketch(name=part_name, sheetSize=1.0)
 29    sketch.setPrimaryObject(option=abaqusConstants.STANDALONE)
 30    sketch.rectangle(point1=(0.0, 0.0), point2=(width, height))
 31    sketch.unsetPrimaryObject()
 32
 33    part = abaqus.mdb.models[model_name].Part(
 34        name=part_name,
 35        dimensionality=abaqusConstants.TWO_D_PLANAR,
 36        type=abaqusConstants.DEFORMABLE_BODY,
 37    )
 38    part.BaseShell(sketch=sketch)
 39
 40    abaqus.mdb.saveAs(pathName=output_file)
 41
 42
 43# Comment used in tutorial code snippets: marker-1
 44
 45
 46def get_parser():
 47    """Return parser for CLI options
 48
 49    All options should use the double-hyphen ``--option VALUE`` syntax to avoid clashes with the Abaqus option syntax,
 50    including flag style arguments ``--flag``. Single hyphen ``-f`` flag syntax often clashes with the Abaqus command
 51    line options and should be avoided.
 52
 53    :returns: parser
 54    :rtype: argparse.ArgumentParser
 55    """
 56    # The global '__file__' variable doesn't appear to be set when executing from Abaqus CAE
 57    filename = inspect.getfile(lambda: None)
 58    basename = os.path.basename(filename)
 59    basename_without_extension, extension = os.path.splitext(basename)
 60    # Construct a part name from the filename less the workflow step suffix
 61    default_part_name = basename_without_extension
 62    suffix = "_geometry"
 63    if default_part_name.endswith(suffix):
 64        default_part_name = default_part_name[: -len(suffix)]
 65    # Set default parameter values
 66    default_output_file = "{}".format(basename_without_extension)
 67    default_width = 1.0
 68    default_height = 1.0
 69
 70    prog = "abaqus cae -noGui {} --".format(basename)
 71    cli_description = "Create a simple rectangle geometry and write an ``output_file``.cae Abaqus model file."
 72    parser = argparse.ArgumentParser(description=cli_description, prog=prog)
 73    parser.add_argument(
 74        "--output-file",
 75        type=str,
 76        default=default_output_file,
 77        # fmt: off
 78        help="The output file for the Abaqus model. "
 79             "Will be stripped of the extension and ``.cae`` will be used, e.g. ``output_file``.cae",
 80        # fmt: on
 81    )
 82    parser.add_argument(
 83        "--model-name",
 84        type=str,
 85        default=default_part_name,
 86        help="The name of the Abaqus model",
 87    )
 88    parser.add_argument(
 89        "--part-name",
 90        type=str,
 91        default=default_part_name,
 92        help="The name of the Abaqus part",
 93    )
 94    parser.add_argument(
 95        "--width",
 96        type=float,
 97        default=default_width,
 98        help="The rectangle width. Positive float.",
 99    )
100    parser.add_argument(
101        "--height",
102        type=float,
103        default=default_height,
104        help="The rectangle height. Positive float.",
105    )
106    return parser
107
108
109# Comment used in tutorial code snippets: marker-2
110
111
112if __name__ == "__main__":
113    parser = get_parser()
114    # Abaqus does not strip the CAE options, so we have to skip the unknown options related to the CAE CLI.
115    try:
116        args, unknown = parser.parse_known_args()
117    except SystemExit as err:
118        sys.exit(err.code)
119    # Check for typos in expected arguments. Assumes all arguments use ``--option`` syntax, which is unused by Abaqus.
120    possible_typos = [argument for argument in unknown if argument.startswith("--")]
121    if len(possible_typos) > 0:
122        raise RuntimeError("Found possible typos in CLI option(s) {}".format(possible_typos))
123
124    sys.exit(
125        main(
126            output_file=args.output_file,
127            model_name=args.model_name,
128            part_name=args.part_name,
129            width=args.width,
130            height=args.height,
131        )
132    )

SConstruct File#

In Tutorial 00: SConstruct, we created the SConstruct file. For convenience, we will add a collector alias matching the tutorial directory name in the SContruct file. This collector alias will point to the list of targets to build specified in the waves-tutorials/tutorial_01_geometry file.

  1. Modify the waves-tutorials/SConstruct file by adding the tutorial_01_geometry collector alias to the workflow_configurations list. The diff output below shows the difference between the SConstruct file created in Tutorial 00: SConstruct and what the new SConstruct file will be.

    waves-tutorials/SConstruct diff

    --- /home/runner/work/waves/waves/build/docs/tutorials_tutorial_00_SConstruct
    +++ /home/runner/work/waves/waves/build/docs/tutorials_tutorial_01_geometry_SConstruct
    @@ -92,7 +92,9 @@
     # Comments used in tutorial code snippets: marker-6
     
     # Add simulation targets
    -workflow_configurations = []
    +workflow_configurations = [
    +    "tutorial_01_geometry",
    +]
     for workflow in workflow_configurations:
         build_dir = env["variant_dir_base"] / workflow
         SConscript(workflow, variant_dir=build_dir, exports={"env": env}, duplicate=False)
    

Building Targets#

Now that you’ve created the geometry task in tutorial_01_geometry, this section will walk through building the tutorial_01_geometry targets using Scons.

  1. To build the targets only for the tutorial_01_geometry workflow, execute the following command:

    $ pwd
    /home/roppenheimer/waves-tutorials
    $ scons tutorial_01_geometry
    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_01_geometry && /apps/abaqus/Commands/abq2024 cae -noGui
    /home/roppenheimer/waves-tutorials/modsim_package/abaqus/rectangle_geometry.py -- > rectangle_geometry.cae.stdout 2>&1
    scons: done building targets.
    

The default build directory name is build and located in the same parent directory as the SConstruct file as described in Tutorial 00: SConstruct.

Output Files#

Explore the contents of the build directory using the tree command against the build directory, as shown below. Note that the directory structure of the build directory exactly matches the directory structure of the location where the project-level SConstruct and SConscript files exist. This behavior will allow us to define multiple simulations in our modsim repository with build result separation if more than one simulation is built at the same time. Tutorial 02: Partition and Mesh will demonstrate the importance of this behavior more clearly.

$ pwd
/home/roppenheimer/waves-tutorials
$ tree build/tutorial_01_geometry/
build/tutorial_01_geometry/
|-- abaqus.rpy
|-- rectangle_geometry.cae
|-- rectangle_geometry.cae.stdout
`-- rectangle_geometry.jnl

0 directories, 4 files

At this point, the only directory in the build directory is that pertaining to the specific target that was specified to be built. In this case, that is tutorial_01_geometry.

The build/tutorial_01_geometry/ directory should contain the following files:

  • abaqus.rpy, the replay file from the abaqus cae -nogui command

  • rectangle_geometry.cae, an Abaqus CAE file that contains a model named model_name within which is a part named part_name.

  • rectangle_geometry.jnl and rectangle_geometry.cae.stdout, the journal file that records all of the commands executed by Abaqaus and the log file that will contain any errors recorded by Abaqus.

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.

$ pwd
/home/roppenheimer/waves-tutorials
$ waves visualize tutorial_01_geometry --output-file tutorial_01_geometry.png --width=16 --height=3
$ ls tutorial_01_geometry.png
tutorial_01_geometry.png

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

_images/tutorial_01_geometry.png

In this case, the single source file rectangle_geometry.py is producing several output files which are required by the workflow. Notice that only two of these files were specified in our geometry task: rectangle_geometry.cae and rectangle_geometry.jnl. The rectangle_geometry.cae.stdout files is generated as part of the AbaqusJournal builder and appended automatically during task generation. This workflow visualization will become crowded quickly in these tutorials, so future visualization commands will show you how to ignore specific file extensions to reduce visual clutter.

This workflow graph would be relatively easy to manage manually for this simple introductory tutorial. However, as the core tutorials grow in file count, and especially when we start adding parameter studies, it will become more obvious why a build system is desirable to manage modsim workflows.