Run a simulation#

OGSTools is a Python library designed to simplify the process of running simulations with the OpenGeoSys (OGS) framework. The Project class is a core component of OGSTools, providing a convenient interface for creating and altering OGS6 input files up and executing OGS simulations. This allows you to automate OGS-workflows in Python via Jupyter or just plain Python scripts. The development of this functionality was first started in [ogs6py](joergbuchwald/ogs6py) and is continued in OGSTools. Here you’ll find the detailed API: ogstools.ogs6py.project.Project.

Features: - alternate existing files (e.g., for parameter sweeps) - create new input files from scratch - execute project files - tailored alteration of input files e.g. for mesh replacements or restarts - display and export parameter settings

In this guide, we will walk you through the process of using the Project class and then run a simple simulation from an existing model setup. Assuming you have prepared a model with your mesh and a project file you can use the following setup, to run it from python.

Choosing the OGS binary

Execution details (which OGS binary to use, MPI settings, logging, …) are controlled via ogstools.core.execution.Execution. Pre-built OGS binaries and container images for each release are available at https://www.opengeosys.org/6.5.7/releases/.

To apply site-wide defaults on a shared system (e.g. HPC cluster), set the OGS_EXECUTION_DEFAULTS environment variable to a YAML file that overrides only the keys you need:

export OGS_EXECUTION_DEFAULTS=/path/to/my_defaults.yaml

See ogstools.core.execution.Execution for the full list of options.

from pathlib import Path
from tempfile import mkdtemp

import ogstools as ot
from ogstools.definitions import EXAMPLES_DIR

results_dir = Path(mkdtemp())
prj_path_in = EXAMPLES_DIR / "prj" / "simple_mechanics.prj"
prj_path_out = results_dir / "simple_mechanics_modified.prj"
prj = ot.Project(
    input_file=prj_path_in, output_file=prj_path_out, output_dir=results_dir
)

model = ot.Model(prj, meshes=EXAMPLES_DIR / "prj")
sim = model.run()
# Optionally save the simulation data
sim.save()
print(sim)
Last 10 line of the log:
Simulation id: 20260323_113730_601492
   Simulation(saved to: file:///tmp/ogstools_root/Simulation/20260323_113730_601492)
  Model: saved to file:///tmp/ogstools_root/Model/20260323_113730_417804
  Result: saved to file:///tmp/ogstools_root/Result/20260323_113730_512144
  Log file: file:///tmp/ogstools_root/Result/20260323_113730_512144/log.txt
  MeshSeries: file:///tmp/ogstools_root/Result/20260323_113730_512144/out_E=3.pvd
  Status: terminated with error
OGS execution was not successful.info: Parsing the OGS commandline passed
info: This is OpenGeoSys-6 version 6.5.7. Log version: 2, Log level: info.
info: OGS starts on 2026-03-23 11:37:30+0000 in serial mode / Python embedded mode.
warning: OMP_NUM_THREADS is not set, falling back to: 16
info: Eigen use 16 threads
info: Reading project file ../../../../../../../tmp/tmpibef6sk5/simple_mechanics_modified.prj.
error: File /tmp/tmpibef6sk5/simple_mechanics_modified.prj does not exist.
critical: /project/BaseLib/PrjProcessing.cpp:307 readAndPatchPrj()
error: Could not open project file '/tmp/tmpibef6sk5/simple_mechanics_modified.prj' for reading.
Could not construct OGSSimulation object

Manipulating the Project#

By using a prj-file as a template and modifying it in python we have an easy way to parametrize simulations. Below are some methods, which change different parts of the model definition. For more detailed information have a look into the API. The subsequent code would work but for clarity we recommend saving 2 different states of the prj object into 2 different files.

# Either tell that you are going to change prj object (prj.copy) OR do prj.save() after you have changed but before you run the simulation.
prj2 = prj.copy()
prj2.replace_parameter_value(name="E", value=1e9)
# You can achieve the same via the `replace_text` method:
prj2.replace_text(1e9, xpath="./parameters/parameter[name='E']/value")
# Let's also replace the output prefix of the result
prj2.replace_text("E=1e9", xpath="./time_loop/output/prefix")
# The density of a phase can also be changed
prj2.replace_phase_property_value(
    mediumid=0, phase="Solid", name="density", value="42"
)

After modifying the Project you can execute the model in the same way as before. You have to prj.save(new_name) here, or beforehand by prj2.copy.

model2 = ot.Model(prj2, meshes=model.meshes)
sim = model2.run()
print(sim)
Simulation id: 20260323_113730_795089
   (not saved (planned: file:///tmp/ogstools_root/Simulation/20260323_113730_795089))
  Model: saved to file:///tmp/ogstools_root/Model/20260323_113730_604386
  Result: saved to file:///tmp/ogstools_root/Result/20260323_113730_696125
  Log file: file:///tmp/ogstools_root/Result/20260323_113730_696125/log.txt
  MeshSeries: file:///tmp/ogstools_root/Result/20260323_113730_696125/E=1e9.pvd
  Status: completed successfully (results available)

Alternatively, for more control

simc = model2.controller()  # this call is not blocking
simc.terminate()  # do something while the simulation is running
simc.run()  # this call is blocking, it waits for the simulation to finish
Simulation(model=Model.from_folder('/tmp/ogstools_root/Model/20260323_113730_604386'), result=Result('/tmp/ogstools_root/Result/20260323_113730_796181'))
log_file='/tmp/ogstools_root/Result/20260323_113730_796181/log.txt'
meshseries_file='/tmp/ogstools_root/Result/20260323_113730_796181/E=1e9.pvd'
status=Status: completed successfully (results pending)
StorageBase(id='20260323_113730_797916', is_saved=False, _active_target=None, next_target=PosixPath('/tmp/ogstools_root/Simulation/20260323_113730_797916'))

Creating a Project from scratch#

You can also create a Project without a prj-file. Have a look at this example to see how: How to Create Simple Mechanics Problem

Total running time of the script: (0 minutes 0.382 seconds)