Simulation
The simulation component connects the Workbench to numerical solvers. Since the meshing component exports to multiple standard formats, the Workbench can interface with a range of commercial and open-source simulation packages. In the current version, SfePy (Simple Finite Elements in Python) is integrated as an open-source, Python-based multi-physics finite element framework. Meshes generated within the Workbench are passed directly to SfePy at runtime, without manual file management.
To demonstrate the workflow, the examples use a simple hydrothermal benchmark model that covers the complete procedure — from mesh import and parameter definition to solver execution and result visualisation.
Workflow
1. Prepare the SfePy input file
Workbench component:
SfePy Input
SfePy is configured through a Python script (.py) that defines the mesh, regions, materials, fields, variables, equations, solvers, and output settings. A full reference for the input file format is available in the SfePy documentation.
To run an SfePy model within the Workbench, two parts of the input file must be defined dynamically.
Mesh filename — must be read from an environment variable so the Workbench can pass the generated mesh at runtime:
The string "filename.mesh" is a fallback default used when running the script outside the Workbench. During execution through simulation_run(), the Workbench sets TEMP_MESH_FILE to the actual mesh file path.
Output directory — must also be read from an environment variable so that results are written to the project folder created by the Workbench:
This directory must then be referenced in the solver options section of the input file:
options = {
'nls': 'newton',
'ls': 'ls',
'ts': 'ts',
'save_times': 'all',
'output_dir': output_dir,
}
With these two dynamic components in place, the rest of the input file — material properties, boundary conditions, governing equations, and solver settings — can be defined in the standard SfePy format.
2. Run the simulation
Workbench component:
Simulating with Sfepy
Running SfePy within the Workbench requires three inputs:
- Input file path — path to the SfePy
.pyconfiguration script. - Mesh type —
"unstr"for unstructured,"str"for structured, or"imp"for implicit meshes. - Output directory (optional) — directory where simulation results will be stored. If not specified, results are written to a temporary directory created automatically by the Workbench.
In the codebase, the mesh object generated by the Workbench is passed as an additional argument internally. In the visual interface (visual DSL) this is handled automatically and does not need to be provided manually.
Example call in the codebase:
Sim_out = run_sfepy(
cwd + "/examples/synthetic_examples/model1/input_data/simulation_input_file/Hydro_thermal.py",
mesh_implicit,
mesh_type="imp",
output_dir="results",
)
3. Load results
Workbench component:
Load VTK results
Before visualising results, they must be loaded into the Workbench using load_vtk_results() or load_exodus_results(), depending on the output format. Two output formats are supported: VTK and Exodus.
If the simulation was run within the Workbench, no path needs to be specified — results are managed automatically. To visualise results from a simulation run outside the Workbench, provide the path to the output directory or file explicitly.
data_by_time = load_vtk_results(Sim_out) # from a simulation run within the Workbench
data_by_time = load_vtk_results("../../model_results/") # from an external output directory
load_exodus_results() works analogously for Exodus output.
Visualisation and Inspection
Workbench: Where available, these are exposed as inspector functions with limited functionality in the visual interface (visual DSL) — parameters are fixed; the codebase functions below expose the full set of options.
The following components allow quick exploration of simulation results without leaving the Workbench. All of them operate on a sim object containing the mesh and all time-dependent simulation data. In the visual interface (visual DSL), sim is passed automatically by the system; in the codebase it is the first argument to each function.
Plot a variable at a time step
Workbench component:
Plot Variable p at a time
Produces a 3D visualisation of a selected simulation variable at a specific time step using PyVista.
var_name: Variable to visualise, e.g."temperature","displacement","stress".time: Time step at which to plot.cmap(optional): Colormap, default"viridis".show_edges(optional): IfTrue, displays mesh element boundaries.scale(optional): Tuple(sx, sy, sz)to scale the geometry along each axis.
Example call in the codebase:
Here, data_by_time is the SimulationResults object (e.g. from load_vtk_results()). This plots the temperature field ("T") at time step 0, using the "coolwarm" colormap with mesh edges shown, scaled by a factor of 10 in all three spatial dimensions.
Plot a variable on a cross-section
Workbench component:
Plot Variable T along a cross_section
Produces a 3D visualisation of a planar cross-section through the model at a specific time step. Useful for inspecting internal distributions by cutting through the model with a plane.
var_name: Variable to visualise.time: Time step at which to evaluate.origin: A 3D point the slicing plane passes through.normal: A 3D vector defining the orientation of the slicing plane.cmap(optional): Colormap, default"viridis".show_edges(optional): IfTrue, displays mesh edges on the sliced surface.scale(optional): Tuple(sx, sy, sz)scaling factors applied to the sliced geometry.
Example call in the codebase:
plot_cross_section(data_by_time, "p", 0, origin=(540, 20, 100), normal=(1, 0, 0), cmap="coolwarm", show_edges=True, scale=(1, 1, 1))
Here, data_by_time is the SimulationResults object. This plots a cross-sectional slice of "p" at time step 0, through the point (540, 20, 100) with a plane oriented perpendicular to the x-axis (1, 0, 0).
Plot a variable along a line
Workbench component:
Plot Variable p along a line
Produces a 2D profile of a variable versus distance along a straight line between two points. Useful for quantitative comparison of results along a transect.
var_name: Variable to evaluate.time: Time step at which to sample.p0: 3D coordinates of the starting point.p1: 3D coordinates of the ending point.n_samples(optional): Number of sampling points along the line, default200.
The horizontal axis shows distance along the line; the vertical axis shows the variable value.
Example call in the codebase:
Here, data_by_time is the SimulationResults object. This plots the variation of "p" at time step 0 along the line from p0 to p1, sampled at 20 points.
Plot a time series at a point
Tracks the temporal evolution of a variable at a fixed spatial location and presents the result as a 2D time-history plot.
var_name: Variable to evaluate.point: 3D coordinate(x, y, z)of the monitoring location.decimals(optional): Decimal places for y-axis formatting, default3.
The horizontal axis shows time; the vertical axis shows the variable value.
Example call in the codebase:
Here, data_by_time is the SimulationResults object. This plots the time series of "p" at location (500, 20, 500).
Print a variable at a point
Evaluates and prints the value of a variable at a specific spatial point and time step. Intended for quick numerical inspection rather than graphical visualisation.
var_name: Variable to evaluate.time: Time step at which to access the variable.point: 3D coordinate of the sampling location.
The value is printed together with the point coordinates.
Example call in the codebase:
Here, data_by_time is the SimulationResults object. This prints the value of "p" at time step 0 and location (500, 20, 500).
Output
Workbench: The
resultsoutput port ofLoad VTK resultsorLoad Exodus filecarries the loaded results. It can be inspected in-place usingPlot Variable p at a time,Plot Variable T along a cross_section, andPlot Variable p along a line.
load_vtk_results() and load_exodus_results() both return a SimulationResults object — a time-dependent container for geometry, topology, and result fields, with every field keyed by simulation time:
nodes_by_time— nodal coordinates for each timestep, shaped(n_nodes, 3).cells_by_time— cell connectivity for each timestep.celltypes_by_time— VTK-style cell type identifiers for each element.node_data_by_time— node-based variables (e.g. temperature, pressure, displacement), as{variable_name: array}dictionaries per timestep.cell_data_by_time— element-based variables (e.g. stress, material IDs), in the same structure asnode_data_by_time.
SimulationResults is the sim object used throughout Visualisation and Inspection above.