User Script Entry Points ("Hooks")

This section shows how to configure the execution of custom modules at certain points of the Python Driver workflow.

This page discusses:

Definitions and Overview

User Script Entry Points, called "hooks," are optional steps in the tosca_driver workflow where a user-defined call to an external module can be established. The terms "hooks" and "User Script Entry Points" are used interchangeably in this guide.

There are two types of hooks supported by the Python Driver:

  1. Module hooks—executed before/after a specific Tosca Module. For a list of the Tosca Modules, refer to Redefinition of the Tosca Modules.
  2. Check point hooks—executed before/after save rules at a given "check point" of the optimization process; for example, at the beginning or end of a design cycle, at the beginning/end of the entire optimization, etc.

In general, both types execute the user script the same way. The only differences are the hook setup and the state of the optimization process. Hooks can be accumulated; that is, multiple user scripts can be attached to the same module/check point, and they are executed in the order in which they were registered.

The Python Driver spawns a new process for each individual hook, and it is executed synchronously. Optionally, the driver can pass the current design cycle and the perturbation number as command-line arguments to the process. This feature is ON by default. For all postprocessing modules (report, smooth, onf2sim), as well as for all preprocessing modules (step2lc, fem_include, fem_to_onf, fem_modif, and tosca_prep), the current design cycle and perturbation number are always 0. The user can provide additional command-line arguments to be passed to the hook-modules executed. These additional arguments to the hook are evaluated once by the Python Driver before the start of the optimization and remain constant throughout the run. For a detailed description of the possibilities to customize any command-line arguments to the hook-calls, refer to the section on command-line options below.

All hook start files (user scripts or executables), if not specified by the full path, are expected to be located in the directory of the job input-files. The files themselves are not moved, no matter how they are specified, but the working directory for the hook-modules is always the Tosca working directory.

Setting-up Module Hooks

A module hook can be attached to any module that the driver executes. If the specific module is not called during the optimization process, any attached hooks are not called. Optionally, the Python Driver can pass the command-line of the module the hook is attached to. This feature is OFF by default.

Registering a module hook can be done in two ways:

General Hook Registration

The most generic way to attach a hook is using the method registerModuleHook().

In the following example, a script is executed before the call to the Tosca module tosca_opt.

    DRIVER
      driver.registerModuleHook( ToscaModules.tosca_opt, HookTypes.PRE, EventTimes.EVER, 'script.bat --arg1 a1' )
    END_
  
After evaluation of the hook-definition by the Python Driver, the following call to the user script is performed,
    script.bat --arg1 a1 --cycle <i> --perturbation <p>
  
where <i> and <p> are the current design cycle and perturbation, respectively.

The arguments of a call to registerModuleHook() are as follows:

    driver.registerModuleHook( module, type, time, command, addIterPert = True, addArgs = False )
  

  • The argument module specifies to which Tosca module the hook should be attached. Specify one of the following:

    • ToscaModules.abq_lc_step
    • ToscaModules.fem_include
    • ToscaModules.fem_to_onf
    • ToscaModules.fem_modif
    • ToscaModules.tosca_prep
    • ToscaModules.tosca_opt
    • ToscaModules.res_to_vtm (non-Abaqus)
    • ToscaModules.odb_to_vtm (Abaqus)
    • ToscaModules.life_to_vtm
    • PostTypes.report
    • PostTypes.smooth
    • PostTypes.db_to_sim
    • FeSolvers.ABAQUS
    • FeSolvers.MSCNASTRAN
    • LifeSolvers.ONF
    • LifeSolvers.FESAFE
    • LifeSolvers.FEMFAT

  • Argument type specifies when the user script should be executed. The possible values are:

    • HookTypes.PRE: before the Tosca module execution
    • HookTypes.POST: after the Tosca module execution
    • HookTypes.PRE_POST: both before and after the Tosca module execution

  • The argument time defines how often the hook-script should be executed. It can be one of the following:

    • EventTimes.EVER: every time
    • EventTimes.NEVER: never
    • EventTimes.FIRST: only the first time
    • EventTimes.LAST: only the last time (Only selectable for PostTypes)
    • EventTimes.FIRST_LAST: only the first and the last time (Only selectable for PostTypes)
    • EventTimes.NTH: only once, the Nth-time
    • EventTimes.FREQ: every Nth-time

  • The argument command is a string-value Python expression that should be used to evaluate a system call to be executed for the hook. Typically this is a string that can contain format-specifiers plus variables/expressions to fill these format-specifiers with values. For examples and further details, refer to the section on command-line options below.

  • addIterPert is an optional flag-argument (default value: True) that triggers the addition of design cycle and perturbation to the hook-script command-line. The user script would get the following arguments added to its command-line: --cycle <i> --perturbation <p>, where <i> and <p> are the current design cycle and perturbation, respectively.

  • The optional argument addArgs (default value: False) instructs the Python Driver whether to add the command-line arguments of the Tosca module to the command-line of the user-script.

Hook Registration through the Pre/Post Shortcuts

A simpler syntax is provided to register hooks using the Pre and Post properties of the existing modules as shortcuts:

    <module>.Pre = <command>
  
or
    <module>.Post = <command>
  
Behind the scenes the general method registerModuleHook() is used, whereas the default values are used except for the command-line and the module name.

Example—assigning a hook to be executed after the solver is finished:

    DRIVER
      driver.Solver.Post = 'post_solver.py --arg1 a1 --arg2 a2'
    END_
  
This assignment is equivalent to the following call, assuming the current solver is Abaqus:
    DRIVER
      driver.registerModuleHook( FeSolvers.ABAQUS, HookTypes.POST, EventTimes.EVER, 'post_solver.py --arg1 a1 --arg2 a2', addIterPert = True, addArgs = False )
    END_
  

Setting-up Check-Point Hooks

A check-point hook can be attached to events in the course of an optimization job; for example, at the beginning or end of a design cycle, at the beginning/end of the entire optimization, etc.

The arguments of a call to registerCheckPointHook() are as follows:

    driver.registerCheckPointHook( checkPoint, type, time, command, addIterPert = True )
  

  • The argument checkPoint specifies the event to which the hook should be attached. Provide one of the following:

    • CheckPoints.CYCLE_COMPLETE: after a design cycle is completed
    • CheckPoints.OPT_COMPLETE: after the whole optimization is completed
    • CheckPoints.MX_COMPLETE: after a matrix cycle is completed
    • CheckPoints.OPT_BEGIN: the optimization is about to begin

  • Argument type specifies when the user script should be executed. The possible values are:

    • HookTypes.PRE: before the execution of the save-rules for this check-point
    • HookTypes.POST: after the execution of the save-rules for this check-point
    • HookTypes.PRE_POST: both before and after the execution of the save-rules for this check-point

  • The argument time defines how often the hook-script should be executed. It can be one of the following:

    • EventTimes.EVER: every time
    • EventTimes.NEVER: never
    • EventTimes.FIRST: only the first time
    • EventTimes.LAST: only the last time
    • EventTimes.FIRST_LAST: only the first and the last time
    • EventTimes.NTH: only once, the Nth-time
    • EventTimes.FREQ: every Nth-time

  • The argument command is a string-value Python expression that should be used to evaluate a system call to be executed for the hook. Typically this is a string that can contain format-specifiers plus variables/expressions to fill these format-specifiers with values. For examples and further details, refer to the section on command-line options below.

  • addIterPert is an optional flag-argument (default value: True) that triggers the addition of design cycle and perturbation to the hook-script command-line. The user script would get the following arguments added to its command-line: --cycle <i> --perturbation <p>, where <i> and <p> are the current design cycle and perturbation, respectively.

Command-Line for the Hook-Modules

The command-line of the hook-module can be given as a string or as a list of strings. The Python Driver can natively execute Python files (.py), as well as shell scripts for the corresponding platform: .bat, .cmd, .sh, etc. For example, passing the type of the optimization:

    'script.bat --optype "%s"' % str( driver.OptimizationType )
  
evaluates to
    script.bat --optype "Topo Sensitivity"
  
Example—passing the title of the result file:
    'script.bat --resfile %s' % OptimizationTypes.toOnf( driver.OptimizationType )
  
evaluates to
    script.bat --resfile TP