|
| 1 | +"""An ASE calculator interface. |
| 2 | +
|
| 3 | +Example: |
| 4 | +```python |
| 5 | +from ase import Atoms |
| 6 | +from deepmd.calculator import DP |
| 7 | +
|
| 8 | +water = Atoms('H2O', |
| 9 | + positions=[(0.7601, 1.9270, 1), |
| 10 | + (1.9575, 1, 1), |
| 11 | + (1., 1., 1.)], |
| 12 | + cell=[100, 100, 100], |
| 13 | + calculator=DP(model="frozen_model.pb", type_map=['O', 'H'])) |
| 14 | +print(water.get_potential_energy()) |
| 15 | +print(water.get_forces()) |
| 16 | +``` |
| 17 | +
|
| 18 | +Optimization is also available: |
| 19 | +```python |
| 20 | +from ase.optimize import BFGS |
| 21 | +dyn = BFGS(water) |
| 22 | +dyn.run(fmax=1e-6) |
| 23 | +print(water.get_positions()) |
| 24 | +``` |
| 25 | +""" |
| 26 | + |
| 27 | +from ase.calculators.calculator import Calculator, all_changes |
| 28 | +import deepmd.DeepPot as DPinference |
| 29 | + |
| 30 | + |
| 31 | +class DP(Calculator): |
| 32 | + name = "DP" |
| 33 | + implemented_properties = ["energy", "forces", "stress"] |
| 34 | + |
| 35 | + def __init__(self, model, type_map, label="DP", **kwargs): |
| 36 | + Calculator.__init__(self, label=label, **kwargs) |
| 37 | + self.dp = DPinference(model) |
| 38 | + self.type_map = type_map |
| 39 | + |
| 40 | + def calculate(self, atoms=None, properties=["energy", "forces", "stress"], system_changes=all_changes): |
| 41 | + coord = atoms.get_positions().reshape([1, -1]) |
| 42 | + cell = atoms.get_cell().reshape([1, -1]) |
| 43 | + symbols = atoms.get_chemical_symbols() |
| 44 | + type_dict = dict(zip(self.type_map, range(len(self.type_map)))) |
| 45 | + atype = [type_dict[k] for k in symbols] |
| 46 | + e, f, v = self.dp.eval(coord, cell, atype) |
| 47 | + self.results['energy'] = e[0] |
| 48 | + self.results['forces'] = f[0] |
| 49 | + self.results['stress'] = v[0] |
| 50 | + |
0 commit comments