Skip to main content

AVxcelerate Simulation Framework 2024 R2 SP02

Simfwk as a solver (Architect 2.0)

Last update: 16.07.2025

Based on the architect 2.0 solver interface, a derived simfwk-solver can be created to take the job scheduled by TSA. Mandatory information for simfwk_cli includes input scenarios and output directory, which must be provided by the TSA job. For other optional arguments and scheduling configurations, simfwk_cli will use default input files stored in the solver image unless specified by the TSA job.

Create base image

Dependencies

The simfwk package, which contains binaries and all runtime dependencies, needs to be installed in the image. Additionally, the following build-time dependencies should be included in the Dockerfile:

RUN apt-get --quiet update && apt-get --quiet install -y --no-install-recommends \
python3.8 python3.8-dev virtualenv \
python3-pip python3.8-venv \
zip \
software-properties-common \
manpages-dev \
unzip \
gzip \
tar \
p7zip-full \
proj-bin\
libgl1-mesa-dev \
libxrandr-dev \
libxinerama-dev \
fontconfig \
build-essential \
curl \
libsqlite3-dev \
&& rm -rf /var/lib/apt/lists/*
RUN add-apt-repository -y ppa:ubuntu-toolchain-r/test && apt-get --quiet install -y --no-install-recommends \
gcc-11 \
g++-11
RUN ln -s /usr/bin/python3 /usr/bin/python

License client binaries

The license client binaries are also contained inside the simfwk installation package. Depending on the version, the client must be copied to the expected directory /ansys_inc/<version>.

In this release, the license client version v231 is applied and should be copied to the expected path in the image:

ENV ANSYS_INC_FOLDER=/ansys_inc/v231
...
COPY <path-to-license_client>/anslic_client/licensingclient $ANSYS_INC_FOLDER/licensingclient

Default data

Currently, TSA cannot hand over all input or static data files required by simfwk, i.e., scheduling config based on different setups should be copied inside the image as default data. Based on how the solver binding is implemented and how the TSA job is configured, the user can select if any default input files should be applied.

In the simfwk-solver image, all default data (Catalogs, Maps, scheduling configs, user settings, and driver input) are copied in the image as follows:

ENV SIMFWK_SOLVER_DEFAULT_DATA=/deployment_binaries/default_data
...
# Define default input names
ENV NAME_INPUT_OPEN_SCENARIO="open_scenario.xosc"
ENV NAME_INPUT_DRIVER_INPUT="driver_input.json"
ENV NAME_INPUT_USER_SETTINGS="UserSettings.ini"
ENV NAME_INPUT_SCHEDULING_CONFIG="sim_config.json"
ENV NAME_INPUT_SCHEDULING_CONFIG_WITH_MCAP="sim_config_mcap.json"
COPY <path-to-default-data>/alks/Catalogs $SIMFWK_SOLVER_DEFAULT_DATA/Catalogs
COPY <path-to-default-data>/alks/Maps $SIMFWK_SOLVER_DEFAULT_DATA/Maps
COPY <path-to-default-data>/driver_input_default.json $SIMFWK_SOLVER_DEFAULT_DATA/$NAME_INPUT_DRIVER_INPUT
COPY <path-to-default-data>/config/sim_config.json $SIMFWK_SOLVER_DEFAULT_DATA/$NAME_INPUT_SCHEDULING_CONFIG
COPY <path-to-default-data>/config/sim_config_mcap.json $SIMFWK_SOLVER_DEFAULT_DATA/$NAME_INPUT_SCHEDULING_CONFIG_WITH_MCAP
COPY <path-to-default-data>/UserSettings.ini $SIMFWK_SOLVER_DEFAULT_DATA/$NAME_INPUT_USER_SETTINGS

Manage I/O files

It is important to have the input and output directories from the TSA job and manage them correctly in solver binding. Make sure simfwk_cli takes the correct input files from the input data directory if the default data shall not be used. The output files (kpi, simulation log, and trace) will be dumped in the given output directory if it is provided by the argument -o <output-directory>.

The names of generated output files are fixed and cannot be customized. In the current solver binding, they are defined as global parameters:

NAME_KPI_FILE = "kpi_results.json"
NAME_LOG_FILE = "simulation_report.txt"
NAME_TRACE_FILE = "simout_trace"

If any need to rename those file after simulation is done, i.e. after simfwk_cli returns 0, it can be done manually though.

Running simfwk_cli as subprocess

According to the new solver architecture, the simfwk solver shall be running as a subprocess inside the python binding script and fill the arguments parameter with expected value:

env: dict[str, str] = {}
env.update(os.environ)
simfwk_process = subprocess.run(
[
os.path.join(<path_to_solver_binary>, "simfwk_cli"),
"-s",
<path_to_input_scenario>,
"-o",
<path_to_solver_output_path>,
"-z",
<path_to_solver_output_path>,
"-d",
<path_to_scheduling_config>,
"-u",
<path_to_user_settings>,
"-x",
<path_to_driver_input>,
],
env=env,
check=False,
capture_output=True,
text=True,
)

Simulation log

With different return codes, the console output of the simfwk process shall be appended to the simulation log so that it can be captured eventually by TSA and forwarded to the frontend for the user.

output_log_file = os.path.join(solver_output_path, NAME_LOG_FILE)
if simfwk_process.returncode == 0:
with open(output_log_file, 'a') as f:
f.write(simfwk_process.stdout + '\n\n')
else:
with open(output_log_file, 'a') as f:
f.write(simfwk_process.stderr + '\n\n')
raise RuntimeError(f"SimulationFramework solver failed with error code {simfwk_process.returncode}: \n{simfwk_process.stderr}")

Handling MCAP files

If the MCAP trace file is enabled, a file simout_trace.mcap is created after the simulation is correctly finished. The size of this binary is quite large without any post-processing, but it can be shrunk significantly after compression using 7z. TSA also requires a compressed file with the extension simout_trace.7z, which it collects and forwards to the frontend for the users.

This step can be done with the following commands in the python solver binding:

"""Archive the mcap trace into 7z format and remove original mcap trace."""
trace_mcap = os.path.join(solver_output_path, NAME_TRACE_FILE + ".mcap")
if not Path(trace_mcap).exists():
raise RuntimeError(f"Simulation finished but the trace file {trace_mcap} is not created.")
trace_7z_archive = os.path.join(solver_output_path, NAME_TRACE_FILE + ".7z")
trace_compression_command = ['7z', 'a', '-mmt=off', '-ma=0', trace_7z_archive, trace_mcap]
try:
trace_compression = subprocess.run(trace_compression_command, check=True)
print(f"File {trace_mcap} has been archived to {trace_7z_archive}")
if trace_compression.returncode == 0:
os.remove(trace_mcap)
print(f"Original mcap file {trace_mcap} has been removed.")
except subprocess.CalledProcessError as e:
print(f"An error occurred during compression: {e}")
except FileNotFoundError:
print("7z command not found. Make sure 7-Zip is installed and the command is available in your PATH.")
except Exception as e:
print(f"An unexpected error occurred: {e}")

Note that the subprocess command defined in trace_compression_command requires the installation of package p7zip-full in docker image, this shall be addressed in the base image dependency

How to add standalone activities to your simulation

If any standalone activities are defined in the scheduling configuration, you must execute them in the background as another subprocess BEFORE the simfwk_cli process. To address this, you can use the subprocess.Popen command in the solver binding, for instance:

# Start the standalone activity process
standalone_activity_process = subprocess.Popen("./<your_standalone_activity_exec>")

This ensures that the dependent standalone activity process is running in the background so that the simfwk_cli can be executed correctly.

Connect with Ansys