Statistiques
| Révision :

root / ase / calculators / morse.py @ 2

Historique | Voir | Annoter | Télécharger (1,42 ko)

1
from math import exp, sqrt
2
import numpy as np
3

    
4
class MorsePotential:
5
    """Morse potential.
6

7
    Default values chosen to be similar as Lennard-Jones.
8
    """
9
    def __init__(self, rho0=6.0, epsilon=1.0, r0=1.0):
10
        self.epsilon = epsilon
11
        self.rho0 = rho0
12
        self.r0 = r0
13
        self.positions = None
14

    
15
    def update(self, atoms):
16
        assert not atoms.get_pbc().any()
17
        if (self.positions is None or
18
            (self.positions != atoms.get_positions()).any()):
19
            self.calculate(atoms)
20

    
21
    def get_potential_energy(self, atoms):
22
        self.update(atoms)
23
        return self.energy
24

    
25
    def get_forces(self, atoms):
26
        self.update(atoms)
27
        return self._forces
28

    
29
    def get_stress(self, atoms):
30
        return np.zeros((3, 3))
31
    
32
    def calculate(self, atoms):
33
        positions = atoms.get_positions()
34
        self.energy = 0.0
35
        self._forces = np.zeros((len(atoms), 3))
36
        preF = 2 * self.epsilon * self.rho0 / self.r0
37
        for i1, p1 in enumerate(positions):
38
            for i2, p2 in enumerate(positions[:i1]):
39
                diff = p2 - p1
40
                r = sqrt(np.dot(diff, diff))
41
                expf = exp(self.rho0 * (1.0 - r / self.r0))
42
                self.energy += self.epsilon * expf * (expf - 2)
43
                F = preF * expf * (expf - 1) * diff / r
44
                self._forces[i1] -= F
45
                self._forces[i2] += F
46
        self.positions = positions.copy()