Note
Go to the end to download the full example code.
Run chemkin Java GUI in Python#
GUI workflow for running Chemkin applications from Python.
This GUI wraps the high-level workflow used to launch Chemkin applications from the command line, which consists of the following steps: 1) generate a platform-specific run script, 2) execute the script with subprocess.
Import PyChemkin packages and start the logger#
from pathlib import Path
import platform
import subprocess
from ansys.chemkin.core import Color
from ansys.chemkin.core.chemistry import chemkin_bin_dir
from ansys.chemkin.core.logger import logger
Establish the chemkin runtime environment#
The batch script to establish the chemkin runtime environment is platform dependent. The first task is to find out the platform and the shell environment. Then you will run the environment setup script accordingly.
# Get local Ansys Chemkin installation bin folder
ckbin = Path(chemkin_bin_dir())
# Configure platform-dependent executable/env names.
under_win = platform.system() == "Windows"
if under_win:
# Windows platform
env_file = "run_chemkin_env_setup.bat"
run_env_path = ckbin / env_file
java_file = "run_chemkin.bat"
run_java_path = ckbin / java_file
elif platform.system() == "Linux":
# Linux platform
env_file = "chemkin_setup.ksh"
run_env_path = ckbin / env_file
java_file = "run_chemkin.ksh"
run_java_path = ckbin / java_file
else:
raise RuntimeError(f"Unsupported platform: {platform.system()}")
# check files exist
if not run_env_path.is_file():
raise FileNotFoundError(f"Chemkin setup script not found: {run_env_path}")
if not run_java_path.is_file():
raise FileNotFoundError(f"Chemkin GUI launcher not found: {run_java_path}")
# Create run script.
if under_win:
# Windows platform
script_path = Path.cwd() / "RUN_CKjob_gui.bat"
with script_path.open("w", encoding="utf-8") as script:
script.write("@REM Generated by run_chemkin_java_gui.py\n")
script.write(f'@CALL "{run_env_path}"\n')
script.write("@SET MKL_NUM_THREADS=1\n")
script.write("@SET OMP_NUM_THREADS=1\n")
script.write("@SET XERCES_DISABLE_DTD=1\n")
script.write(f'@CALL "{run_java_path}"\n')
script.write(r"@IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%")
script.write("\n")
else:
# Linux platform
script_path = Path.cwd() / "RUN_CKjob_gui.sh"
with script_path.open("w", encoding="utf-8") as script:
script.write("#!/bin/bash\n")
script.write("set -e\n")
script.write(f'. "{run_env_path}"\n')
script.write("export MKL_NUM_THREADS=1\n")
script.write("export OMP_NUM_THREADS=1\n")
script.write("export XERCES_DISABLE_DTD=1\n")
script.write(f'. "{run_java_path}"\n')
logger.info(f"Created run script: {script_path}")
# Execute run script with subprocess.
try:
if under_win:
run_cmd = ["cmd", "/d", "/c", str(script_path)]
else:
run_cmd = ["bash", str(script_path)]
result = subprocess.run(
run_cmd,
capture_output=True,
text=True,
check=True,
shell=False,
)
# Log stderr if it exists.
if result.stderr:
msg = [
Color.PURPLE,
"--- stderr ---\n",
Color.SPACEx6,
result.stderr.rstrip(),
Color.END,
]
this_msg = Color.SPACE.join(msg)
logger.error(this_msg)
except subprocess.CalledProcessError as e:
if not e.returncode == 1: # return code 1 is expected when user closes the GUI
logger.error(f"Chemkin Java GUI failed with return code {e.returncode}")
result = e # capture the error output for logging
if result.stderr:
msg = [
Color.PURPLE,
"process error\n",
Color.SPACEx6,
result.stderr.rstrip(),
Color.END,
]
this_msg = Color.SPACE.join(msg)
logger.error(this_msg)
# clean up run script
try:
script_path.unlink()
logger.info(f"Deleted run script: {script_path}")
except Exception as e:
logger.warning(f"Failed to delete run script: {script_path}. Error: {e}")