DFT with ORCA

Build a Job Template to automate your DFT calculations with ORCA in DECTRIS CLOUD

Job Template & Execution

To run ORCA calculations at scale and automate DFT jobs in DECTRIS CLOUD, you need to define a Job Template. This template acts as a blueprint that combines your ORCA environment, execution logic, and adjustable parameters.

You can use the provided examples to help you build your fully custom template. The Job Template here consists of a Bash execution script that handles the ORCA/OpenMPI environment and given input variables that can be configured manually in the UI, or with a json input.

1. Initialize the Template

  • Name & Description: Start by creating a new job template. Give it a scannable name (e.g., ORCA_DFT_Optimization) and a description that notes the ORCA and OpenMPI versions used.
  • Select Environment: Select the ORCA Docker environment as the base for this job. This ensures all math libraries and MPI runtimes are available. (If you do not have an ORCA environment, see instructions on how to build it HERE)

2. Define Input Variables

Set up variables to allow for easy iteration without modifying the underlying script.

Example Variables Configuration (JSON):

In order to configure variables, you can either declare them using the Job Template creation UI, or using json format. An example of variable declaration is shown below:

{
  "input_variables": {
    "DC_ORCA_INPUT": {
      "default_value": "",
      "type": "path",
      "unit": ""
    },
    "DC_NUM_THREADS": {
      "default_value": -1,
      "type": "number",
      "unit": ""
    },
    "DC_NP": {
      "default_value": 0,
      "type": "number",
      "unit": ""
    },
    "DC_PARAMS": {
      "default_value": "--mca btl",
      "type": "string",
      "unit": ""
    }
  }
}

The table below shows examples of variables you may want to declare if you need to tweak them when you run the DFT calculation job. (The table below was built in accordance with the bash instruction provided in section 3. Your variables and synthax may differ depending on your instructions file.)

Variable

Type

Default

Description

DC_ORCA_INPUT

Path

(empty)

The path to your ORCA .inp file.

DC_NUM_THREADS

Number

-1

OpenMP threads (use -1 for all available cores).

DC_NP

Number

0

Number of MPI ranks (set to 0 for serial runs).

DC_PARAMS

String

--mca btl

Additional flags for the mpirun command.

3. Build the Instructions File

The Instructions File is the Bash script that orchestrates the calculation. You can configure your custom bash script as suits you best. Below you find and example, that you may copy and paste into the template's instruction block. This script is designed to handle ORCA path discovery and output collection automatically.

#!/usr/bin/env bash
set -euo pipefail


# -------------------------------
# Required environment variables
# -------------------------------
: "${DC_ORCA_INPUT:?DC_ORCA_INPUT is not set}"
: "${JOB_OUTPUT_DIR:?JOB_OUTPUT_DIR is not set}"


# -------------------------------
# Optional environment variables
# -------------------------------
DC_NUM_THREADS="${DC_NUM_THREADS:--1}"   # -1 => use all cores
DC_NP="${DC_NP:-0}"                      # 0  => no MPI
DC_PARAMS="${DC_PARAMS:-}"               # extra mpirun params (string)
DC_ORCA_OUTPUT="${DC_ORCA_OUTPUT:-}"     # optional override; if empty -> derived from input


# -------------------------------
# Resolve input/output
# -------------------------------
INP="${DC_ORCA_INPUT}"
BASENAME="$(basename "${INP}")"
JOBNAME="${BASENAME%.inp}"


# Output log naming (optional override)
if [[ -n "${DC_ORCA_OUTPUT}" ]]; then
  OUT="${DC_ORCA_OUTPUT}"
else
  if [[ "${BASENAME}" == *.inp ]]; then
    OUT="${JOBNAME}.log"
  else
    OUT="${BASENAME}.log"
    JOBNAME="${BASENAME}"   # so we match outputs like "foo.log", "foo.gbw", etc.
  fi
fi


# -------------------------------
# Resolve thread count
# -------------------------------
if [[ "${DC_NUM_THREADS}" == "-1" ]]; then
  NUM_THREADS="$(nproc)"
else
  NUM_THREADS="${DC_NUM_THREADS}"
fi
export OMP_NUM_THREADS="${NUM_THREADS}"


# -------------------------------
# ORCA + MPI locations (from container)
# -------------------------------
ORCA_HOME="${ORCA_HOME:-/opt/orca}"
OMPI_HOME="${OMPI_HOME:-/opt/openmpi}"


# Find ORCA executable robustly (handles /opt/orca/orca_6_1_0/orca, etc.)
EXEC="${ORCA_HOME}/orca"
if [[ ! -x "${EXEC}" ]]; then
  # Common layout in your image: /opt/orca/orca_6_1_0/orca
  if [[ -x "${ORCA_HOME}/orca_6_1_0/orca" ]]; then
    EXEC="${ORCA_HOME}/orca_6_1_0/orca"
  else
    # Generic fallback: search a few levels deep
    EXEC="$(find "${ORCA_HOME}" -maxdepth 4 -type f -name orca -perm -111 2>/dev/null | head -n 1 || true)"
  fi
fi


# -------------------------------
# Validation (ORCA + input)
# -------------------------------
if [[ -z "${EXEC}" || ! -x "${EXEC}" ]]; then
  echo "ERROR: ORCA not found or not executable under ORCA_HOME=${ORCA_HOME}" >&2
  ls -lah "${ORCA_HOME}" >&2 || true
  exit 1
fi


if [[ ! -f "${INP}" ]]; then
  echo "ERROR: Input file not found: ${INP}" >&2
  exit 1
fi


mkdir -p "${JOB_OUTPUT_DIR}"


# Set PATH/LD_LIBRARY_PATH based on where ORCA was found
ORCA_BIN_DIR="$(dirname "${EXEC}")"
ORCA_LIB_DIR="${ORCA_BIN_DIR}/lib"


export PATH="${ORCA_BIN_DIR}:${OMPI_HOME}/bin:${PATH}"
export LD_LIBRARY_PATH="${ORCA_LIB_DIR}:${OMPI_HOME}/lib:${LD_LIBRARY_PATH:-}"


# -------------------------------
# PARAMS handling (string -> array)
# -------------------------------
NP="${DC_NP}"
PARAMS="${DC_PARAMS}"
PARAM_ARR=()
if [[ -n "${PARAMS}" ]]; then
  read -r -a PARAM_ARR <<< "${PARAMS}"
fi


# -------------------------------
# Execution
# -------------------------------
echo "======================================"
echo "Running ORCA"
echo "  ORCA executable : ${EXEC}"
echo "  Input           : ${INP}"
echo "  Output (stdout) : ${OUT}"
echo "  Job name prefix : ${JOBNAME}"
echo "  Threads         : ${OMP_NUM_THREADS}"
echo "  MPI ranks (NP)  : ${NP}"
echo "  MPI params      : ${PARAMS}"
echo "  Job output dir  : ${JOB_OUTPUT_DIR}"
echo "======================================"


if [[ "${NP}" -gt 0 ]]; then
  mpirun -np "${NP}" "${PARAM_ARR[@]}" "${EXEC}" "${INP}" > "${OUT}"
else
  "${EXEC}" "${INP}" > "${OUT}"
fi


echo "ORCA finished. Collecting outputs..."


# -------------------------------
# Collect outputs: copy all files that start with JOBNAME*
# (covers .gbw, .engrad, .xyz, .hess, etc.)
# -------------------------------
shopt -s nullglob
moved_any=0
for f in "${JOBNAME}"*; do
  if [[ -e "${f}" ]]; then
    cp -a "${f}" "${JOB_OUTPUT_DIR}/"
    moved_any=1
  fi
done
shopt -u nullglob


# Always ensure the main log is present in the output dir
cp -a "${OUT}" "${JOB_OUTPUT_DIR}/" || true


if [[ "${moved_any}" -eq 0 ]]; then
  echo "WARNING: No files matched '${JOBNAME}*' in the working directory." >&2
  echo "Contents of current directory:" >&2
  ls -lah >&2 || true
fi


echo "Done."
echo "Outputs copied to: ${JOB_OUTPUT_DIR}"
echo "  - ${JOB_OUTPUT_DIR}/$(basename "${OUT}")"

4. Upload Supporting Files

If your calculation requires external files, such as specific Basis Set files, XYZ coordinates not included in the .inp, or Hessian files for restarts, upload them to your Project/Experiment directory or as the job's supporting files. Ensure the paths specified in your .inp file match the location of these uploaded files.


Important Notes

  • Parallelization Matching: Ensure the %pal nprocs X end block in your ORCA input file matches the DC_NP variable in your job template.
  • Memory Management: ORCA memory (%maxcore) is requested per MPI rank. Ensure your total memory usage (MaxCore × NP) does not exceed the hardware limits of the allocated node.
  • Log Files: The main log file is automatically saved as {your_input_name}.log in the output directory for easy review.


ORCA REFERENCE

Neese, F., Wennmohs, F., Becker, U., & Riplinger, C. (2020). The ORCA quantum chemistry program package. The Journal of Chemical Physics, 152(22), 224108. https://doi.org/10.1063/5.0004608


Important: The ORCA installer is not provided by DECTRIS due to licensing restrictions. ORCA is distributed under a specific agreement that you must comply, and its redistribution is not permitted in DECTRIS CLOUD.



Was this article helpful?