|
| 1 | +import numpy as np |
| 2 | + |
| 3 | +from dpdata.dftbplus.output import read_dftb_plus |
| 4 | +from dpdata.format import Format |
| 5 | +from dpdata.unit import EnergyConversion, ForceConversion |
| 6 | + |
| 7 | +energy_convert = EnergyConversion("hartree", "eV").value() |
| 8 | +force_convert = ForceConversion("hartree/bohr", "eV/angstrom").value() |
| 9 | + |
| 10 | + |
| 11 | +@Format.register("dftbplus") |
| 12 | +class DFTBplusFormat(Format): |
| 13 | + """The DFTBplusFormat class handles files in the DFTB+ format. |
| 14 | +
|
| 15 | + This class provides a method to read DFTB+ files from a labeled system and |
| 16 | + returns a dictionary containing various properties of the system.For more |
| 17 | + information, please refer to the official documentation at the following URL: |
| 18 | + https://dftbplus.org/documentation |
| 19 | +
|
| 20 | + Attributes |
| 21 | + ---------- |
| 22 | + None |
| 23 | +
|
| 24 | + Methods |
| 25 | + ------- |
| 26 | + from_labeled_system(file_paths, **kwargs): Reads system information from files. |
| 27 | +
|
| 28 | + """ |
| 29 | + |
| 30 | + def from_labeled_system(self, file_paths, **kwargs): |
| 31 | + """Reads system information from the given DFTB+ file paths. |
| 32 | +
|
| 33 | + Parameters |
| 34 | + ---------- |
| 35 | + file_paths : tuple |
| 36 | + A tuple containing the input and output file paths. |
| 37 | + - Input file (file_in): Contains information about symbols and coord. |
| 38 | + - Output file (file_out): Contains information about energy and force. |
| 39 | + **kwargs : dict |
| 40 | + other parameters |
| 41 | +
|
| 42 | + """ |
| 43 | + file_in, file_out = file_paths |
| 44 | + symbols, coord, energy, forces = read_dftb_plus(file_in, file_out) |
| 45 | + last_occurrence = {v: i for i, v in enumerate(symbols)} |
| 46 | + atom_names = np.array(sorted(np.unique(symbols), key=last_occurrence.get)) |
| 47 | + atom_types = np.array([np.where(atom_names == s)[0][0] for s in symbols]) |
| 48 | + atom_numbs = np.array([np.sum(atom_types == i) for i in range(len(atom_names))]) |
| 49 | + natoms = coord.shape[0] |
| 50 | + |
| 51 | + return { |
| 52 | + "atom_types": atom_types, |
| 53 | + "atom_names": list(atom_names), |
| 54 | + "atom_numbs": list(atom_numbs), |
| 55 | + "coords": coord.reshape((1, natoms, 3)), |
| 56 | + "energies": np.array([energy * energy_convert]), |
| 57 | + "forces": (forces * force_convert).reshape((1, natoms, 3)), |
| 58 | + "cells": np.zeros((1, 3, 3)), |
| 59 | + "orig": np.zeros(3), |
| 60 | + "nopbc": True, |
| 61 | + } |
0 commit comments