Skip to content

Commit

Permalink
add zbl test
Browse files Browse the repository at this point in the history
  • Loading branch information
chiang-yuan committed Jan 23, 2025
1 parent 0f5930e commit c701ecc
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 15 deletions.
5 changes: 2 additions & 3 deletions mlip_arena/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,15 @@

MLIPEnum = Enum("MLIPEnum", MLIPMap)

# https://github.com/pytorch/pytorch/blob/3cbc8c54fd37eb590e2a9206aecf3ab568b3e63c/torch/_dynamo/config.py#L534
# torch._dynamo.config.compiled_autograd = True

class MLIP(
nn.Module,
PyTorchModelHubMixin,
tags=["atomistic-simulation", "MLIP"],
):
def __init__(self, model: nn.Module) -> None:
super().__init__()
# https://github.com/pytorch/pytorch/blob/3cbc8c54fd37eb590e2a9206aecf3ab568b3e63c/torch/_dynamo/config.py#L534
# torch._dynamo.config.compiled_autograd = True
# self.model = torch.compile(model)
self.model = model

Expand Down
16 changes: 4 additions & 12 deletions mlip_arena/models/classicals/zbl.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,15 @@
class ZBL(nn.Module):
"""Ziegler-Biersack-Littmark (ZBL) screened nuclear repulsion"""

# name: str
# implemented_properties: list[str] = ["energy", "forces", "stress"]

def __init__(
self,
trianable: bool = False,
**kwargs,
) -> None:
nn.Module.__init__(self, **kwargs)
# Calculator.__init__(
# self, restart=restart, atoms=atoms, directory=directory, **calculator_kwargs
# )


torch.set_default_dtype(torch.double)

# self.cutoff = torch.tensor(cutoff, dtype=torch.get_default_dtype())

self.a = torch.nn.parameter.Parameter(
torch.tensor(
[0.18175, 0.50986, 0.28022, 0.02817], dtype=torch.get_default_dtype()
Expand Down Expand Up @@ -142,7 +134,7 @@ def envelope(self, r: torch.Tensor, rc: torch.Tensor, p: int = 6):
return y

def _get_derivatives(self, energy: torch.Tensor, data: Data):
egrad, fij = torch.autograd.grad(
egradi, egradij = torch.autograd.grad(
outputs=[energy], # TODO: generalized derivatives
inputs=[data.positions, data.vij], # TODO: generalized derivatives
grad_outputs=[torch.ones_like(energy)],
Expand All @@ -152,7 +144,7 @@ def _get_derivatives(self, energy: torch.Tensor, data: Data):
)

volume = torch.det(data.cell) # (batch,)
rfaxy = torch.einsum("ax,ay->axy", data.vij, fij)
rfaxy = torch.einsum("ax,ay->axy", data.vij, -egradij)

edge_batch = data.batch[data.edge_index[0]]

Expand All @@ -162,7 +154,7 @@ def _get_derivatives(self, energy: torch.Tensor, data: Data):
/ volume.view(-1, 1)
)

return -egrad, stress
return -egradi, stress

def forward(
self,
Expand Down
36 changes: 36 additions & 0 deletions tests/test_internal_calculators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import numpy as np
from mlip_arena.models import MLIPCalculator
from mlip_arena.models.classicals.zbl import ZBL

from ase.build import bulk


def test_zbl():
calc = MLIPCalculator(model=ZBL(), cutoff=6.0)

energies = []
forces = []
stresses = []

lattice_constants = [1, 3, 5, 7]

for a in lattice_constants:
atoms = bulk("Cu", "fcc", a=a) * (2, 2, 2)
atoms.calc = calc

energies.append(atoms.get_potential_energy())
forces.append(atoms.get_forces())
stresses.append(atoms.get_stress(voigt=False))

# test energy monotonicity
assert all(np.diff(energies) <= 0), "Energy is not monotonically decreasing with increasing lattice constant"

# test force vectors are all zeros due to symmetry
for f in forces:
assert np.allclose(f, 0), "Forces should be zero due to symmetry"

# test trace of stress is monotonically increasing (less negative) and zero beyond cutoff
traces = [np.trace(s) for s in stresses]

assert all(np.diff(traces) >= 0), "Trace of stress is not monotonically increasing with increasing lattice constant"
assert np.allclose(stresses[-1], 0), "Stress should be zero beyond cutoff"

0 comments on commit c701ecc

Please sign in to comment.