Statistiques
| Révision :

root / ase / md / langevin.py @ 16

Historique | Voir | Annoter | Télécharger (4,21 ko)

1 1 tkerber
"""Langevin dynamics class."""
2 1 tkerber
3 1 tkerber
4 1 tkerber
import sys
5 1 tkerber
import numpy as np
6 1 tkerber
from numpy.random import standard_normal
7 1 tkerber
from ase.md.md import MolecularDynamics
8 1 tkerber
9 1 tkerber
# For parallel GPAW simulations, the random forces should be distributed.
10 1 tkerber
if '_gpaw' in sys.modules:
11 1 tkerber
    # http://wiki.fysik.dtu.dk/gpaw
12 1 tkerber
    from gpaw.mpi import world as gpaw_world
13 1 tkerber
else:
14 1 tkerber
    gpaw_world = None
15 1 tkerber
16 1 tkerber
class Langevin(MolecularDynamics):
17 1 tkerber
    """Langevin (constant N, V, T) molecular dynamics.
18 1 tkerber

19 1 tkerber
    Usage: Langevin(atoms, dt, temperature, friction)
20 1 tkerber

21 1 tkerber
    atoms
22 1 tkerber
        The list of atoms.
23 1 tkerber

24 1 tkerber
    dt
25 1 tkerber
        The time step.
26 1 tkerber

27 1 tkerber
    temperature
28 1 tkerber
        The desired temperature, in energy units.
29 1 tkerber

30 1 tkerber
    friction
31 1 tkerber
        A friction coefficient, typically 1e-4 to 1e-2.
32 1 tkerber

33 1 tkerber
    fixcm
34 1 tkerber
        If True, the position and momentum of the center of mass is
35 1 tkerber
        kept unperturbed.  Default: True.
36 1 tkerber

37 1 tkerber
    The temperature and friction are normally scalars, but in principle one
38 1 tkerber
    quantity per atom could be specified by giving an array.
39 1 tkerber

40 1 tkerber
    This dynamics accesses the atoms using Cartesian coordinates."""
41 1 tkerber
42 1 tkerber
    def __init__(self, atoms, timestep, temperature, friction, fixcm=True,
43 1 tkerber
                 trajectory=None, logfile=None, loginterval=1,
44 1 tkerber
                 communicator=gpaw_world):
45 1 tkerber
        MolecularDynamics.__init__(self, atoms, timestep, trajectory,
46 1 tkerber
                                   logfile, loginterval)
47 1 tkerber
        self.temp = temperature
48 1 tkerber
        self.frict = friction
49 1 tkerber
        self.fixcm = fixcm  # will the center of mass be held fixed?
50 1 tkerber
        self.communicator = communicator
51 1 tkerber
        self.updatevars()
52 1 tkerber
53 1 tkerber
    def set_temperature(self, temperature):
54 1 tkerber
        self.temp = temperature
55 1 tkerber
        self.updatevars()
56 1 tkerber
57 1 tkerber
    def set_friction(self, friction):
58 1 tkerber
        self.frict = friction
59 1 tkerber
        self.updatevars()
60 1 tkerber
61 1 tkerber
    def set_timestep(self, timestep):
62 1 tkerber
        self.dt = timestep
63 1 tkerber
        self.updatevars()
64 1 tkerber
65 1 tkerber
    def updatevars(self):
66 1 tkerber
        dt = self.dt
67 1 tkerber
        # If the friction is an array some other constants must be arrays too.
68 1 tkerber
        self._localfrict = hasattr(self.frict, 'shape')
69 1 tkerber
        lt = self.frict * dt
70 1 tkerber
        masses = self.masses
71 1 tkerber
        sdpos = dt * np.sqrt(self.temp / masses * (2.0/3.0 - 0.5 * lt) * lt)
72 1 tkerber
        sdpos.shape = (-1, 1)
73 1 tkerber
        sdmom = np.sqrt(self.temp * masses * 2.0 * (1.0 - lt) * lt)
74 1 tkerber
        sdmom.shape = (-1, 1)
75 1 tkerber
        pmcor = np.sqrt(3.0)/2.0 * (1.0 - 0.125 * lt)
76 1 tkerber
        cnst = np.sqrt((1.0 - pmcor) * (1.0 + pmcor))
77 1 tkerber
78 1 tkerber
        act0 = 1.0 - lt + 0.5 * lt * lt
79 1 tkerber
        act1 = (1.0 - 0.5 * lt + (1.0/6.0) * lt * lt)
80 1 tkerber
        act2 = 0.5 - (1.0/6.0) * lt + (1.0/24.0) * lt * lt
81 1 tkerber
        c1 = act1 * dt / masses
82 1 tkerber
        c1.shape = (-1, 1)
83 1 tkerber
        c2 = act2 * dt * dt / masses
84 1 tkerber
        c2.shape = (-1, 1)
85 1 tkerber
        c3 = (act1 - act2) * dt
86 1 tkerber
        c4 = act2 * dt
87 1 tkerber
        del act1, act2
88 1 tkerber
        if self._localfrict:
89 1 tkerber
            # If the friction is an array, so are these
90 1 tkerber
            act0.shape = (-1, 1)
91 1 tkerber
            c3.shape = (-1, 1)
92 1 tkerber
            c4.shape = (-1, 1)
93 1 tkerber
            pmcor.shape = (-1, 1)
94 1 tkerber
            cnst.shape = (-1, 1)
95 1 tkerber
        self.sdpos = sdpos
96 1 tkerber
        self.sdmom = sdmom
97 1 tkerber
        self.c1 = c1
98 1 tkerber
        self.c2 = c2
99 1 tkerber
        self.act0 = act0
100 1 tkerber
        self.c3 = c3
101 1 tkerber
        self.c4 = c4
102 1 tkerber
        self.pmcor = pmcor
103 1 tkerber
        self.cnst = cnst
104 1 tkerber
105 1 tkerber
    def step(self, f):
106 1 tkerber
        atoms = self.atoms
107 1 tkerber
        p = self.atoms.get_momenta()
108 1 tkerber
109 1 tkerber
        random1 = standard_normal(size=(len(atoms), 3))
110 1 tkerber
        random2 = standard_normal(size=(len(atoms), 3))
111 1 tkerber
112 1 tkerber
        if self.communicator is not None:
113 1 tkerber
            self.communicator.broadcast(random1, 0)
114 1 tkerber
            self.communicator.broadcast(random2, 0)
115 1 tkerber
116 1 tkerber
        rrnd = self.sdpos * random1
117 1 tkerber
        prnd = (self.sdmom * self.pmcor * random1 +
118 1 tkerber
                self.sdmom * self.cnst * random2)
119 1 tkerber
120 1 tkerber
        if self.fixcm:
121 1 tkerber
            rrnd = rrnd - np.sum(rrnd, 0) / len(atoms)
122 1 tkerber
            prnd = prnd - np.sum(prnd, 0) / len(atoms)
123 1 tkerber
            n = len(atoms)
124 1 tkerber
            rrnd *= np.sqrt(n / (n - 1.0))
125 1 tkerber
            prnd *= np.sqrt(n / (n - 1.0))
126 1 tkerber
127 1 tkerber
        atoms.set_positions(atoms.get_positions() +
128 1 tkerber
                            self.c1 * p +
129 1 tkerber
                            self.c2 * f + rrnd)
130 1 tkerber
        p *= self.act0
131 1 tkerber
        p += self.c3 * f + prnd
132 1 tkerber
        atoms.set_momenta(p)
133 1 tkerber
134 1 tkerber
        f = atoms.get_forces()
135 1 tkerber
        atoms.set_momenta(p + self.c4 * f)
136 1 tkerber
        return f