Run an OpenFOAM simulation

from pathlib import Path
from remote_run import (
    Executor,
    SlurmSchedulingEngine,
    GuixEnvironment,
    remote,
    SshMachine,
)
from pyopenfoam.tutorials import generate_pitz_daily_case
from pyopenfoam.cli.scripts import of_run
import pyvista as pv

Set up a guix environment. We use pyopenfoam to call OpenFOAM from python this means adding this channel to the guix channels. This can also be read from a file directly.

guix_environment = GuixEnvironment(
    channels="""(list
      (channel
       (name 'guix)
       (url "https://git.savannah.gnu.org/git/guix.git")
       (branch "master")
       (commit
        "ee8be372972bc1e84b5870df738c6e0bbdd975ff")
       (introduction
        (make-channel-introduction
         "9edb3f66fd807b096b48283debdcddccfea34bad"
         (openpgp-fingerprint
          "BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA"))))
      (channel
       (name 'python-pyopenfoam)
       (url "https://gitlab.ost.ch/sce-floss/pyopenfoam.git")
       (branch "main")
       (commit
        "ab8b4130bd8e3c199e72b47c6ca1809011be3b5e"))
      (channel
       (name 'guix-ost)
       (url "https://gitlab.ost.ch/scl/guix-ost.git")
       (branch "main")
       (commit
        "2a64fa887f4a2069ea9426e423f55838bc8987e9")))""",
    manifest="""
(specifications->manifest
        (list "python"
              "python-pyvista"
              "python-pint"
              "python-pyopenfoam"
              "openfoam-org"
              "openmpi"))
""",
)

define execution variables

num_cpus = 10

Define an execution context with a scheduling engine. You can pass SLURM parameters directly here.

executor = Executor(
    machine=SshMachine(
        host="shpc0003.ost.ch",
        working_directory=Path("/cluster/raid/home/reza.housseini"),
    ),
    environment=[guix_environment],
    scheduling_engine=SlurmSchedulingEngine(
        job_name="openfoam_sim",
        mail_type="ALL",
        mail_user="reza.housseini@ost.ch",
    ),
)

define simulation variables

duration = 0.1  # seconds

create an OpenFOAM case locally

pitz_daily_case = generate_pitz_daily_case(duration=duration, num_cpus=num_cpus)
case_path = Path("pitz_daily_case")
pitz_daily_case.write(folder=case_path)

decorate your functions you want to (potentially) run on another machine the case path will be patched automatically when you run it on another machine

@remote
def run_sim(case_path):
    of_run(case_path)
    # return simulation data
    foam_file = case_path / (case_path.name + ".foam")
    foam_file.touch()
    reader = pv.POpenFOAMReader(foam_file)
    return reader.read()

this call will run on the remote machine specified in executor but due to the asynchronous nature of scheduling engines this will not return the result, instead you get a future to retrieve the result later. Inject the executor object here to run this on the specified machine.

job = run_sim(case_path, executor=executor)

now we wait for the remote execution to finish before retrieving the result.

result = job.result(timeout=10)

Gallery generated by Sphinx-Gallery