Command manual

Command list

Python scripting

Python scriptning extends the functionality of *FUNCTION and *PARAMETER with a more powerful way of defining custom workflow. This document describes the basics of how it can used.

IMPETUS Afea Solver uses Python 3 and it is embedded in the Windows version. Linux users must install python3 from the package manager. For use of external modules installed from pip, Python 3 must also be installed externally on Windows systems.

Writing the Python script

If you are not familiar with Python, please, check out the tutorial and documentation below:

The basics steps are: 1 read the input data (parameters), 2 do the necessary calculations and 3 return the desired value. It's important that the function actually returns a value, else the return value will be set to zero. It's also important to know that function names are case sensitive.

The example below shows a module named py_module with the function func(). The function contains one parameter called time. This parameter is passed on from the input deck in the *FUNCTION command.

Python script: py_module.py
def func(time):
    if time < 1.0:
        return 0.5
    else:
        return 1.0

Including a Python script (module) into the simulation

In order to use a function defined in Python, the file needs to be added with the *SCRIPT_PYTHON command. The name of the file must end with a .py extension. Script files loaded into Python are treated as modules with the file name as module name. Be aware that the name of the module is case sensitive.

# Adding the python file *SCRIPT_PYTHON
py_module.py

The code above loads py_module.py as a module with the name py_module. It will later be used in the *FUNCTION command.

Calling Python function from *FUNCTION

Calling a Python function works just like calling one of the built-in functions. It must, however, be preceded by the module name seperated with a period. Example:
module_name.function_name(...)

*FUNCTION
1000
epsp * py_module.funcA(fxc(1), pres) *FUNCTION
2000
py_module.funcB(epsp)

One can also call two different functions from two different modules. In this example, we load python_file_A.py and python_file_B.py. Both of these modules will work independently from each other.

Any parameters that can be used in *FUNCTION, can also be sent into the python function.

*SCRIPT_PYTHON
python_file_A.py python_file_B.py *FUNCTION
1000
python_file_A.func(epsp) * python_file_B.func(t)

Calling Python function from *PARAMETER

Calling a Python function from *PARAMETER is essentially the same as calling from *FUNCTION. The difference is that the returned value is assigned to variable, and the function is only executed once during the initialization.

Python functions called from *PARAMETER can also return a Python list (array) of variables. If a list is returned from Python, then the varaible in the input deck will be defined as a vector.

For usage with *PARAMETER, the python file must be included before it is called from *PARAMETER.

*SCRIPT_PYTHON
python_file.py *PARAMETER
value = python_file.func(1, 2)

Conclusion & example

Summarize:

  • A script file (module) must be loaded with the *SCRIPT_PYTHON command.
  • Both module names and functions are case sensitive.
  • Functions must return a value, else it returns the value zero.
  • Print statements are good for debug purposes but should otherwise be avoided.
  • Python functions are called by both the module and function name, seperated by a period sign.

The example below shows the usage of the output interval for imp-output. We send in the variables: t (time) and fxc (contact force) into the function fuser(). This function evaluates the time and the contact force. If the contact force is less than 1.0, a larger output interval is returned. In every other case, a smaller output interval will returned. One exception is when the time passes 3.0e-4, then it will return a larger output interval.

*TIME 0.001 *OUTPUT fcn(1000) *SCRIPT_PYTHON output.py *FUNCTION "output interval" 1000 output.fuser(t, fxc(1))
Python script: output.py
def fuser(t, fxc):
    if fxc < 1.0 or t > 3.0e-4:
        return 1.0e-4 
    else:
        return 1.0e-5