-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate.py
More file actions
95 lines (70 loc) · 2.36 KB
/
generate.py
File metadata and controls
95 lines (70 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""
Python script to generate a 2D LJ dataset
"""
import numpy as np
import torch
from ase import Atoms, io
# Settings
M = 10 # initial coordinate grid spacing
N = M**2 # Num atoms
L = 20.0 # Box length
dt = 0.01 # timestep
kT = 1.0 # KbT
gamma = 1.0 # Friction
sigma = 1.0 # LJ sigma
epsilon = 2.0 # LJ epsilon
Nsteps = 100000 # Number of timesteps
Nout = 100 # Frequency of output
def energy(positions):
"Compute the energy of a Lennard-Jones system."
# get [i,j] pairs
a, b = torch.triu_indices(N, N, 1)
# compute the displacement vectors
d = positions[a] - positions[b]
# PBCs
d = d - torch.round(d/L)*L
# compute distance^2
r2 = torch.sum(d**2, dim=1)
c6 = (sigma**2 / r2)**3
c12 = c6**2
return torch.sum(4 * epsilon * (c12 - c6))
# Simulation setup
line = torch.linspace(0,L-2.0,M)
x = torch.cartesian_prod(line,line)
v = torch.zeros(N,2)
# Main simulation loop
frames=[]
equilibrium_frames=[]
for t in range(Nsteps):
x = x.clone().detach().requires_grad_(True)
# compute energy
energies = energy(x)
# compute forces
energies.backward()
forces = -x.grad
# leap-frog Verlet langevin
alpha = np.exp(-gamma*dt)
v = v*alpha + forces*(1.0-alpha)/gamma + np.sqrt(kT*(1-alpha**2))*torch.randn(v.shape)
x = x.detach() + v*dt
# PBCs
x = x - torch.floor(x/L)*L
# print some logs to screen
if t%10000==0:
print(t,"/",Nsteps, "Energy =", energies.item() )
# output to trajectory
if t%Nout==0:
xyz = torch.hstack((x, torch.zeros(N,1)))
frame = Atoms(''.join(['C']*N), positions = xyz.numpy(), cell=(L,L,L), pbc=True, info={"energy": float(energies.detach().numpy())})
frames.append(frame)
# save these to equilibrium frames
equilibrium_frames.append(frame)
## add some noise to the data to get higher energy structures
x_temp = x.clone()
x_temp += torch.randn(x_temp.shape)*0.05
e_temp = energy(x_temp)
xyz = torch.hstack((x_temp, torch.zeros(N,1)))
frame = Atoms(''.join(['C']*N), positions = xyz.numpy(), cell=(L,L,L), pbc=True, info={"energy": float(e_temp.detach().numpy())})
frames.append(frame)
# write trajectorys using ASE
io.write("generated_traj_2d.extxyz", frames)
io.write("equilibrium_traj_2d.xyz", equilibrium_frames)