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