Skip to content

Correspondence between dxtb and xtb-python of xtb-gfn1 #258

Description

@hannesvdc

Dear Grimme lab

We're evaluating dxtb as a GPU-accelerated drop-in for the CPU xtb-python calculator. We found correspondence is excellent overall on a range of molecules between 2 and 182 atoms. GFN1 energies agree to ~1e-6 Ha and forces to <= 2e-5 eV/Å in float64 on CPU.

But at a couple of peculiar cases, the forces disagree, and I wanted to ask whether you've seen this before.

Test case

At the equilibrium (ASE G2) geometries of methanol ( minimal code example below), dxtb and xtb-python GFN1 forces differ by approximately 0.22 eV/Å on the x-coordinate of the carbon atom. Energies still agree within a relative error of 1e-5 eV.

dxtb is correct because the negative central-finite-difference gradient of xtb-python's own energy matches dxtb to ~1e-6 eV/Å, and
disagrees with xtb-python's analytical force by the full 0.225 eV/Å. This totally makes sense because dxtb forces are computed through automatic differentiation. Apparently, xtb-python's reported force is not the gradient of its own energy there, while
dxtb's autograd force is.

The discrepancy is invariant to SCF accuracy (1.0→1e-4), electronic temperature, and finite-difference step size. The issue does not appear to be a convergence artifact. It's also geometry-localized: a non-equilibrium methanol conformer agrees perfectly.

Numbers (methanol equilibrium, worst atom = C), eV/Å

  xtb-python analytical : [-0.0652 -0.3899  0.    ]
  dxtb autograd         : [-0.2904 -0.3899  0.    ]
  -FD(xtb-python energy): [-0.2904 -0.3899  0.    ]   (neutral truth)

  max |xtb-python analytical - (-FD(xtb energy))| = 2.25e-01 eV/A
  max |dxtb autograd        - (-FD(xtb energy))| = 1.6e-06 eV/A

Is this a known incompatibility between dxtb and the xtb/tblite analytical gradients at (near-)symmetric geometries? Have you encountered it in other situations or molecules, and is there a known cause (e.g. a gradient term that xtb/tblite treats differently, or a documented edge case)? We'd like to know how broadly it can occur before relying on either code's forces near symmetric
stationary points.

Have you also seen this issue with xtb-gfn2?

Minimal-reproducing script:

import numpy as np, torch
from ase import Atoms
from xtb.ase.calculator import XTB
from dxtb_potential import DxtbPotential   # thin dxtb wrapper, GFN1, f64

SYMBOLS = ["C","O","H","H","H","H"]; Z = np.array([6,8,1,1,1,1])
XYZ = np.array([[-0.047131, 0.664389, 0.0],[-0.047131,-0.758551,0.0],
                [-1.092995, 0.969785, 0.0],[ 0.878534,-1.048458,0.0],
                [ 0.437145, 1.080376, 0.891772],[0.437145,1.080376,-0.891772]])

def E(x):
    a=Atoms(symbols=SYMBOLS,positions=x)
    a.calc=XTB(method="GFN1-xTB",electronic_temperature=300.0); return a.get_potential_energy()

a=Atoms(symbols=SYMBOLS,positions=XYZ); a.calc=XTB(method="GFN1-xTB",electronic_temperature=300.0)
F_xtb = a.get_forces()
_, F_dxtb = DxtbPotential(Z=Z, method="GFN1-xTB", dtype=torch.double).energy_forces(XYZ)

h=2e-4; g=np.zeros_like(XYZ)
for i in range(6):
    for j in range(3):
        xp=XYZ.copy(); xp[i,j]+=h; xm=XYZ.copy(); xm[i,j]-=h
        g[i,j]=(E(xp)-E(xm))/(2*h)
F_fd = -g
print("xtb analytical  - FD:", np.abs(F_xtb  - F_fd).max())   # ~0.225
print("dxtb autograd   - FD:", np.abs(F_dxtb - F_fd).max())   # ~1e-6

The full code for this example is in our repo https://github.com/hannesvdc/ChemDM/blob/main/examples/xtb_gpu/reference_gradient_bug.py

Thank you,

Hannes Vandecasteele

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions