root / ase / calculators / lj.py @ 20
Historique | Voir | Annoter | Télécharger (1,25 ko)
1 |
import numpy as np |
---|---|
2 |
|
3 |
|
4 |
class LennardJones: |
5 |
def __init__(self, epsilon=1.0, sigma=1.0): |
6 |
self.epsilon = epsilon
|
7 |
self.sigma = sigma
|
8 |
self.positions = None |
9 |
|
10 |
def update(self, atoms): |
11 |
assert not atoms.get_pbc().any() |
12 |
if (self.positions is None or |
13 |
(self.positions != atoms.get_positions()).any()):
|
14 |
self.calculate(atoms)
|
15 |
|
16 |
def get_potential_energy(self, atoms): |
17 |
self.update(atoms)
|
18 |
return self.energy |
19 |
|
20 |
def get_forces(self, atoms): |
21 |
self.update(atoms)
|
22 |
return self._forces |
23 |
|
24 |
def get_stress(self, atoms): |
25 |
return np.zeros((3, 3)) |
26 |
|
27 |
def calculate(self, atoms): |
28 |
positions = atoms.get_positions() |
29 |
self.energy = 0.0 |
30 |
self._forces = np.zeros((len(atoms), 3)) |
31 |
for i1, p1 in enumerate(positions): |
32 |
for i2, p2 in enumerate(positions[:i1]): |
33 |
diff = p2 - p1 |
34 |
d2 = np.dot(diff, diff) |
35 |
c6 = (self.sigma**2 / d2)**3 |
36 |
c12 = c6**2
|
37 |
self.energy += 4 * self.epsilon * (c12 - c6) |
38 |
F = 24 * self.epsilon * (2 * c12 - c6) / d2 * diff |
39 |
self._forces[i1] -= F
|
40 |
self._forces[i2] += F
|
41 |
self.positions = positions.copy()
|