Skip to content

[BUG] DFTB+ reader silently drops periodic cell/PBC and stress #1063

Description

@Tresormap

Bug summary

With dpdata==1.1.0, reading a periodic DFTB+ input/output pair with fmt="dftbplus" produces a zero cell, sets nopbc=True, and omits virials even when the output contains a stress tensor.

This affects periodic GenFormat inputs in both S and F modes. In F mode, the lattice is used to convert fractional coordinates, but it is not preserved in the returned system.

dpdata Version

1.1.0 (official, unmodified)

Input Files, Running Commands, Error Log, etc.

A minimal reproducer using synthetic input:

from io import StringIO
import numpy as np
import dpdata

geometry = StringIO("""Geometry = GenFormat {
2 S
Si
1 1 0.0 0.0 0.0
2 1 1.0 1.0 1.0
0.0 0.0 0.0
5.0 0.0 0.0
0.0 5.0 0.0
0.0 0.0 5.0
}
""")

output = StringIO("""Total energy: -1.0 H -27.2114 eV
Total Forces
1 0.0 0.0 0.0
2 0.0 0.0 0.0

Total stress tensor
1.0e-6 0.0 0.0
0.0 1.0e-6 0.0
0.0 0.0 1.0e-6
""")

system = dpdata.LabeledSystem(
    (geometry, output), fmt="dftbplus"
)

print("cell volume:", np.linalg.det(system["cells"][0]))
print("nopbc:", system.data["nopbc"])
print("has virials:", "virials" in system.data)

The result with unmodified dpdata 1.1.0 is:

cell volume: 0.0
nopbc: True
has virials: False

The expected result is a periodic system with the supplied cell (volume 125 ų) and the stress converted to a per-frame virial in eV. Exporting the current result to deepmd/npy instead produces a nopbc marker, zero cell data, and no virial.npy.

Steps to Reproduce

  1. Use an unmodified installation of dpdata==1.1.0.
  2. Run the self-contained Python example above; it uses synthetic in-memory input, so no external files are needed.
  3. Inspect the cell volume, nopbc, and presence of virials. The periodic input is returned with a zero cell, nopbc=True, and no virial.

Further Information, Files, and Links

The relevant assignments in the 1.1.0 DFTB+ adapter are:

"cells": np.zeros((1, 3, 3)),
"orig": np.zeros(3),
"nopbc": True,

The underlying parser reads energy and forces but does not extract stress, and returns only:

return symbols, coord, energy, forces

We have implemented a local patch against official 1.1.0 that:

  • Preserves the existing atom-count parsing, fractional-coordinate conversion, and energy/force conversions.
  • Passes the cell, origin, and periodicity through to the standard LabeledSystem interface.
  • Reads Total stress tensor and converts it to virial using the frame volume:
virial_eV = stress_au * abs(np.linalg.det(cell_angstrom)) * (
    27.211386245988034 / 0.529177210903**3
)

The patch retains the low-level reader's default four-value return for compatibility; the adapter requests the additional fields through an optional keyword. When periodic stress is absent, it warns and leaves virials absent rather than creating zero labels.

Reference patch against official dpdata 1.1.0 (provided as an optional implementation):

dpdata-1.1.0-dftbplus-periodic.patch

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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions