g-xTB With FRUST
FRUST exposes g-xTB v2 through Stepper.gxtb(...). This is a dedicated path
separate from Stepper.xtb(...): FRUST calls Tooltoad's gxtb_calculate(...),
and Tooltoad runs the special g-xTB xtb binary with --gxtb added
automatically.
Setup
Put GXTB_EXE in ~/.env and point it to the g-xTB v2 xtb executable. Do
not point it at the normal XTB_EXE unless that binary advertises --gxtb.
Use the g-xTB v2.0.0 release from Grimme lab:
https://github.com/grimme-lab/g-xtb/releases/tag/v2.0.0
FRUST uses the newer g-xTB v2 xtb binary, not older g-xTB workflows. For
direct Stepper.gxtb(...), Tooltoad calls this binary with --gxtb. For
ORCA-driven g-xTB, the MolinDiscovery OET fork provides oet_gxtb; ORCA calls
that OET wrapper, and the wrapper calls GXTB_EXE so g-xTB 2.0 can provide
external energies and gradients back to ORCA.
GXTB_ROOT=/path/to/g-xtb
GXTB_EXE=/path/to/g-xtb/bin/xtb
See External tool setup for the
shared .env setup used by FRUST and Tooltoad.
Quick check:
"$GXTB_EXE" --help | grep -- --gxtb
"$GXTB_EXE" --help | grep -- --grad
Basic API
Use Stepper.gxtb(...) on a normal FRUST dataframe with atoms and a coordinate
column such as coords_embedded or a prior *-oc column.
from frust.stepper import Stepper
step = Stepper(
step_type="MOLS",
n_cores=8,
save_output_dir=False,
)
df_gxtb = step.gxtb(
df,
options={"grad": None},
n_cores=8,
)
This runs the equivalent of:
xtb mol.xyz --gxtb --grad
Stepper.gxtb(...) takes the shared xTB-style arguments:
step.gxtb(
df,
name="gxtb",
options=None,
detailed_inp_str="",
constraint=False,
save_step=False,
lowest=None,
n_cores=None,
)
Common Calculations
Single point:
df_sp = step.gxtb(df)
Gradient:
df_grad = step.gxtb(
df,
options={"grad": None},
)
Geometry optimization:
df_opt = step.gxtb(
df,
options={"opt": None},
)
Numerical Hessian on the input geometry:
df_hess = step.gxtb(
df,
options={"hess": None},
)
Optimize, then Hessian:
df_ohess = step.gxtb(
df,
options={"ohess": None},
)
Transition-state optimization is not handled by direct Stepper.gxtb(...).
Use ORCA-driven g-xTB instead, so ORCA owns the OptTS search and g-xTB only
provides energies and gradients. For difficult TS searches, first compute a
g-xTB Hessian directly and pass it into ORCA with use_last_hess=True:
df = step.gxtb(
df,
name="gxtb-hess",
options={"hess": None},
save_step=True,
)
df_ts = step.orca(
df,
name="gxtb-OptTS",
options={"OptTS": None},
gxtb=True,
use_last_hess=True,
save_step=True,
)
For a simpler first attempt, you can run ORCA OptTS without a supplied
Hessian and let ORCA build its own initial guess:
df_ts = step.orca(
df,
name="gxtb-OptTS",
options={"OptTS": None},
gxtb=True,
)
Use NumFreq, not Freq, when you want frequencies with ORCA-driven g-xTB.
Freq uses ORCA's analytic frequency machinery, which is not compatible with
the external g-xTB method. NumFreq uses finite differences of the external
gradients.
Mode-specific TS setup should also go through ORCA input blocks:
df_ts = step.orca(
df,
name="gxtb-OptTS",
options={"OptTS": None, "NumFreq": None},
gxtb=True,
xtra_inp_str="""
%geom
TS_Mode {B 0 1} end
end
""",
)
Charge and spin are handled by Tooltoad's normal xTB contract. If the input row
or calling layer passes charge/multiplicity through the backend, Tooltoad maps
them to xTB's --chrg and --uhf arguments.
Output Columns
FRUST maps Tooltoad result keys into stage-prefixed dataframe columns.
Default single-point prefix:
gxtb-EE
gxtb-NT
Optimization prefix:
gxtb-opt-EE
gxtb-opt-NT
gxtb-opt-oc
Custom names override the prefix:
df_named = step.gxtb(
df,
name="gxtb_preopt",
options={"opt": None},
)
Typical columns:
gxtb_preopt-EE
gxtb_preopt-NT
gxtb_preopt-oc
Useful suffixes:
-EE: electronic energy.-NT: normal termination boolean.-oc: optimized coordinates.-GE: Gibbs energy when thermochemistry is available.-vibs: vibrations when Hessian output is parsed.-error: row-level exception text if the backend fails.
Chaining
Use g-xTB exactly like the other FRUST stepper stages. FRUST will pick the most recent coordinate column when moving to the next stage.
step = Stepper(step_type="MOLS", n_cores=8, save_output_dir=False)
df = step.gxtb(
df,
name="gxtb_preopt",
options={"opt": None},
)
df = step.orca(
df,
name="hf_sp",
options={"HF": None, "STO-3G": None, "SP": None},
)
To keep only the lowest-energy conformers per structure group:
df_low = step.gxtb(
df,
options={"opt": None},
lowest=5,
)
lowest= uses the same shared FRUST behavior as Stepper.xtb(...) and
Stepper.orca(...).
ORCA-Driven TS Optimization
For transition states, use ORCA's external optimization interface:
step = Stepper(step_type="TS1", n_cores=8, save_output_dir=False)
df_ts = step.orca(
df,
name="gxtb-OptTS",
options={"OptTS": None},
gxtb=True,
)
FRUST automatically inserts ExtOpt and an OET %method block pointing to
oet_gxtb. OET then calls the GXTB_EXE binary as xtb --gxtb --grad for
each ORCA gradient request. This is the correct route for OptTS, NEB-TS,
and other ORCA optimizer workflows.
For TS searches that need a better starting Hessian, use a two-step workflow:
df = step.gxtb(
df,
name="gxtb-hess",
options={"hess": None},
save_step=True,
)
df_ts = step.orca(
df,
name="gxtb-OptTS",
options={"OptTS": None},
gxtb=True,
use_last_hess=True,
save_step=True,
)
Stepper.gxtb(..., options={"hess": None}) asks the g-xTB binary for a
numerical Cartesian Hessian. Tooltoad converts that xTB-style hessian file to
an ORCA text .hess file and stores it in the dataframe, usually as
gxtb-hess-input.hess. use_last_hess=True tells FRUST to write the latest
*.hess dataframe column to ORCA as private_input.hess and add:
%geom
inhess Read
InHessName "private_input.hess"
end
Use NumFreq when you want ORCA to verify the optimized geometry with
finite-difference frequencies:
df_ts = step.orca(
df,
name="gxtb-OptTS",
options={"OptTS": None, "NumFreq": None},
gxtb=True,
)
Do not add %geom Calc_Hess true for this external g-xTB route. With ORCA 6.1,
that makes ORCA enter an internal Hessian/property-integral path that is not
compatible with the external g-xTB method. Use the use_last_hess=True route
above when you want an initial g-xTB Hessian.
Constraints
FRUST's built-in constrained xTB setup is also available for g-xTB. This is
mainly useful for the existing FRUST step types such as TS1, TS2, TS3,
TS4, and INT3.
step = Stepper(step_type="TS1", n_cores=8)
df_ts1 = step.gxtb(
df,
options={"opt": "ts"},
constraint=True,
)
The dataframe must contain the constraint metadata expected by the step type,
typically constraint_atoms.
For custom xTB control input, pass detailed_inp_str:
df_custom = step.gxtb(
df,
options={"grad": None},
detailed_inp_str="""
$constrain
force constant=50
distance: 1, 2, 1.50
$end
""",
)
FRUST appends its generated constraint block after the custom input when both
detailed_inp_str and constraint=True are used.
Saving Calculation Files
Use save_step=True when you want to keep calculation directories.
step = Stepper(
step_type="MOLS",
n_cores=8,
save_output_dir="FRUST_results",
)
df_saved = step.gxtb(
df,
options={"opt": None},
save_step=True,
)
The saved directory can include files such as:
mol.xyz
xtbopt.xyz
xtbopt.log
charges
wbo
xtbtopo.mol
The exact file set depends on the options used and what the g-xTB binary writes.
Direct Tooltoad Use
FRUST uses Tooltoad internally, but the calculator can also be called directly:
from tooltoad.gxtb import gxtb_calculate
result = gxtb_calculate(
atoms=["H", "H"],
coords=[[0.0, 0.0, 0.0], [0.0, 0.0, 0.74]],
options={"grad": None},
n_cores=1,
)
print(result["normal_termination"])
print(result["electronic_energy"])
print(result["grad"].shape)
Notes And Limitations
GXTB_EXEis required only whengxtb_calculate(...)is called.- FRUST does not automatically reuse
XTB_EXE; the normal local xTB binary may not support--gxtb. - Tooltoad always adds
--gxtb, so do not include"gxtb": Noneyourself. - Direct
Stepper.gxtb(...)is not the TS optimization route. UseStepper.orca(..., options={"OptTS": None}, gxtb=True)for ORCA-driven TS searches. - ORCA
Freqis not compatible withgxtb=Truebecause g-xTB is supplied as an external method throughExtOpt. UseNumFreqfor finite-difference frequencies. - ORCA
%geom Calc_Hess trueis not compatible withgxtb=True. UseStepper.gxtb(..., options={"hess": None})followed byStepper.orca(..., gxtb=True, use_last_hess=True)when you want an initial g-xTB Hessian. - The installed upstream README notes that not all xTB features are supported by g-xTB yet.
- The macOS g-xTB README warns about parallel numerical Hessians. Prefer
n_cores=1for cautious local Hessian checks on macOS.
Troubleshooting
Check that Tooltoad sees the executable:
python - <<'PY'
from tooltoad.gxtb import _resolve_gxtb_cmd
print(_resolve_gxtb_cmd())
PY
Check that the executable is actually g-xTB-capable:
"$GXTB_EXE" --help | grep -- --gxtb
If FRUST returns gxtb-NT=False, inspect the gxtb-error column first. If the
backend ran but xTB itself failed, rerun with save_step=True and inspect the
saved xTB output files.