Statistiques
| Révision :

root / ase / md / nptberendsen.py @ 1

Historique | Voir | Annoter | Télécharger (3,79 ko)

1 1 tkerber
"""Berendsen NPT dynamics class."""
2 1 tkerber
3 1 tkerber
import numpy as np
4 1 tkerber
5 1 tkerber
#from ase.md import MolecularDynamics
6 1 tkerber
from ase.md.nvtberendsen import NVTBerendsen
7 1 tkerber
import ase.units as units
8 1 tkerber
#import math
9 1 tkerber
10 1 tkerber
11 1 tkerber
class NPTBerendsen(NVTBerendsen):
12 1 tkerber
    """Berendsen (constant N, P, T) molecular dynamics.
13 1 tkerber

14 1 tkerber
    Usage: NPTBerendsen(atoms, timestep, temperature, taut, pressure, taup)
15 1 tkerber

16 1 tkerber
    atoms
17 1 tkerber
        The list of atoms.
18 1 tkerber

19 1 tkerber
    timestep
20 1 tkerber
        The time step.
21 1 tkerber

22 1 tkerber
    temperature
23 1 tkerber
        The desired temperature, in Kelvin.
24 1 tkerber

25 1 tkerber
    taut
26 1 tkerber
        Time constant for Berendsen temperature coupling.
27 1 tkerber

28 1 tkerber
    fixcm
29 1 tkerber
        If True, the position and momentum of the center of mass is
30 1 tkerber
        kept unperturbed.  Default: True.
31 1 tkerber

32 1 tkerber
    pressure
33 1 tkerber
        The desired pressure, in bar (1 bar = 1e5 Pa).
34 1 tkerber

35 1 tkerber
    taup
36 1 tkerber
        Time constant for Berendsen pressure coupling.
37 1 tkerber

38 1 tkerber
    compressibility
39 1 tkerber
        The compressibility of the material, water 4.57E-5 bar-1, in bar-1
40 1 tkerber

41 1 tkerber
    """
42 1 tkerber
43 1 tkerber
    def __init__(self, atoms, timestep, temperature, taut=0.5e3*units.fs,
44 1 tkerber
                 pressure = 1.01325, taup=1e3*units.fs,
45 1 tkerber
                 compressibility=4.57e-5, fixcm=True,
46 1 tkerber
                 trajectory=None, logfile=None, loginterval=1):
47 1 tkerber
48 1 tkerber
        NVTBerendsen.__init__(self, atoms, timestep, temperature, taut, fixcm,
49 1 tkerber
                              trajectory,
50 1 tkerber
                              logfile, loginterval)
51 1 tkerber
        self.taup = taup
52 1 tkerber
        self.pressure = pressure
53 1 tkerber
        self.compressibility = compressibility
54 1 tkerber
55 1 tkerber
    def set_taup(self, taut):
56 1 tkerber
        self.taut = taut
57 1 tkerber
58 1 tkerber
    def get_taup(self):
59 1 tkerber
        return self.taut
60 1 tkerber
61 1 tkerber
    def set_pressure(self, pressure):
62 1 tkerber
        self.pressure = pressure
63 1 tkerber
64 1 tkerber
    def get_pressure(self):
65 1 tkerber
        return self.pressure
66 1 tkerber
67 1 tkerber
    def set_compressibility(self, compressibility):
68 1 tkerber
        self.compressibility = compressibility
69 1 tkerber
70 1 tkerber
    def get_compressibility(self):
71 1 tkerber
        return self.compressibility
72 1 tkerber
73 1 tkerber
    def set_timestep(self, timestep):
74 1 tkerber
        self.dt = timestep
75 1 tkerber
76 1 tkerber
    def get_timestep(self):
77 1 tkerber
        return self.dt
78 1 tkerber
79 1 tkerber
80 1 tkerber
81 1 tkerber
    def scale_positions_and_cell(self):
82 1 tkerber
        """ Do the Berendsen pressure coupling,
83 1 tkerber
        scale the atom positon and the simulation cell."""
84 1 tkerber
85 1 tkerber
        taupscl = self.dt / self.taup
86 1 tkerber
        stress = self.atoms.get_stress()
87 1 tkerber
        old_pressure = self.atoms.get_isotropic_pressure(stress)
88 1 tkerber
        scl_pressure = 1.0 - taupscl * self.compressibility / 3.0 * \
89 1 tkerber
                       (self.pressure - old_pressure)
90 1 tkerber
91 1 tkerber
        #print "old_pressure", old_pressure
92 1 tkerber
        #print "volume scaling by:", scl_pressure
93 1 tkerber
94 1 tkerber
        cell = self.atoms.get_cell()
95 1 tkerber
        positions = self.atoms.get_positions()
96 1 tkerber
97 1 tkerber
        cell = scl_pressure * cell
98 1 tkerber
        positions = scl_pressure * positions
99 1 tkerber
100 1 tkerber
        self.atoms.set_cell(cell, scale_atoms=False)
101 1 tkerber
        self.atoms.set_positions(positions)
102 1 tkerber
103 1 tkerber
        return
104 1 tkerber
105 1 tkerber
106 1 tkerber
    def step(self, f):
107 1 tkerber
        """ move one timestep forward using Berenden NPT molecular dynamics."""
108 1 tkerber
109 1 tkerber
        NVTBerendsen.scale_velocities(self)
110 1 tkerber
        self.scale_positions_and_cell()
111 1 tkerber
112 1 tkerber
        #one step velocity verlet
113 1 tkerber
        atoms = self.atoms
114 1 tkerber
        p = self.atoms.get_momenta()
115 1 tkerber
        p += 0.5 * self.dt * f
116 1 tkerber
117 1 tkerber
        if self.fixcm:
118 1 tkerber
            # calculate the center of mass
119 1 tkerber
            # momentum and subtract it
120 1 tkerber
            psum = p.sum(axis=0) / float(len(p))
121 1 tkerber
            p = p - psum
122 1 tkerber
123 1 tkerber
        self.atoms.set_positions(self.atoms.get_positions() +
124 1 tkerber
             self.dt * p / self.atoms.get_masses()[:,np.newaxis])
125 1 tkerber
126 1 tkerber
        # We need to store the momenta on the atoms before calculating
127 1 tkerber
        # the forces, as in a parallel Asap calculation atoms may
128 1 tkerber
        # migrate during force calculations, and the momenta need to
129 1 tkerber
        # migrate along with the atoms.  For the same reason, we
130 1 tkerber
        # cannot use self.masses in the line above.
131 1 tkerber
132 1 tkerber
        self.atoms.set_momenta(p)
133 1 tkerber
        f = self.atoms.get_forces()
134 1 tkerber
        atoms.set_momenta(self.atoms.get_momenta() + 0.5 * self.dt * f)
135 1 tkerber
136 1 tkerber
137 1 tkerber
        return f