ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/ExtendedSystem.cpp
Revision: 453
Committed: Thu Apr 3 23:49:20 2003 UTC (21 years, 3 months ago) by gezelter
File size: 4908 byte(s)
Log Message:
renamed nvt to extendedsystem

File Contents

# User Rev Content
1 gezelter 453 #include <math.h>
2    
3     ExtendedSystem::ExtendedSystem( SimInfo &info ) {
4    
5     // get what information we need from the SimInfo object
6    
7     entry_plug = &info;
8     nAtoms = info.n_atoms;
9     atoms = info.atoms;
10     nMols = info.n_mol;
11     molecules = info.molecules;
12    
13     }
14    
15     ExtendedSystem::~ExtendedSystem() {
16     }
17    
18    
19     void ExtendedSystem::nose_hoover_nvt( double ke, double dt, double temp ){
20    
21     // Basic thermostating via Hoover, Phys.Rev.A, 1985, Vol. 31 (5) 1695-1697
22    
23     int i, j, degrees_freedom;
24     double ke, dt, temp, kB;
25     double keconverter, NkBT, zetaScale, ke_temp;
26     double vxi, vyi, vzi, jxi, jyi, jzi;
27    
28     degrees_freedom = 6*nmol; // number of degrees of freedom for the system
29     kB = 8.31451e-7; // boltzmann constant in amu*Ang^2*fs^-2/K
30     keconverter = 4.184e-4; // to convert ke from kcal/mol to amu*Ang^2*fs^-2 / K
31    
32     ke_temp = ke * keconverter;
33     NkBT = degrees_freedom*kB*temp;
34    
35     // advance the zeta term to zeta(t + dt) - zeta is 0.0d0 on config. readin &
36     // qmass is set in the parameter file
37     zeta = zeta + dt*((ke_temp*2 - NkBT)/qmass);
38     zetaScale = zeta * dt;
39    
40     // perform thermostat scaling on linear velocities and angular momentum
41     for(i = 0, i < nmol; i++ ) {
42     vxi = vx(i)*zetaScale;
43     vyi = vy(i)*zetaScale;
44     vzi = vz(i)*zetaScale;
45     jxi = jx(i)*zetaScale;
46     jyi = jy(i)*zetaScale;
47     jzi = jz(i)*zetaScale;
48    
49     vx(i) = vx(i) - vxi;
50     vy(i) = vy(i) - vyi;
51     vz(i) = vz(i) - vzi;
52     jx(i) = jx(i) - jxi;
53     jy(i) = jy(i) - jyi;
54     jz(i) = jz(i) - jzi;
55     }
56     }
57    
58    
59     void ExtendedSystem::nose_hoover_anderson_npt(double pressure, double ke, double dt,
60     double temp ) {
61    
62     // Basic barostating via Hoover, Phys.Rev.A, 1985, Vol. 31 (5) 1695-1697
63     // Hoover, Phys.Rev.A, 1986, Vol.34 (3) 2499-2500
64    
65     int i, j, degrees_freedom;
66     double pressure, dt, temp, pressure_units, epsilonScale;
67     double ke, kB, vxi, vyi, vzi, pressure_ext;
68     double boxx_old, boxy_old, boxz_old;
69     double keconverter, NkBT, zetaScale, ke_temp;
70     double jxi, jyi, jzi, scale;
71    
72     kB = 8.31451e-7; // boltzmann constant in amu*Ang^2*fs^-2/K
73     pressure_units = 6.10192996e-9; // converts atm to amu*fs^-2*Ang^-1
74     degrees_freedom = 6*nmol; // number of degrees of freedom for the system
75     keconverter = 4.184e-4; // to convert ke from kcal/mol to amu*Ang^2*fs^-2/K
76    
77     pressure_ext = pressure * pressure_units;
78     volume = boxx*boxy*boxz;
79     ke_temp = ke * keconverter;
80     NkBT = degrees_freedom*kB*temp;
81    
82     // propogate the strain rate
83    
84     epsilon_dot += dt * ( (p_mol - pressure_ext)*volume
85     / (tau_relax*tau_relax * kB * temp) );
86    
87     // determine the change in cell volume
88     scale = pow( (1.0 + dt * 3.0 * epsilon_dot), (1.0 / 3.0));
89    
90     volume = volume * pow(scale, 3.0);
91    
92     // perform affine transform to update positions with volume fluctuations
93     affine_transform( scale );
94    
95     // save old lengths and update box size
96     boxx_old = boxx;
97     boxy_old = boxy;
98     boxz_old = boxz;
99    
100     boxx = boxx_old*scale;
101     boxy = boxy_old*scale;
102     boxz = boxz_old*scale;
103    
104     epsilonScale = epsilon_dot * dt;
105    
106     // advance the zeta term to zeta(t + dt) - zeta is 0.0d0 on config. readin
107     // qmass is set in the parameter file
108     zeta += dt * ( (ke_temp*2 - NkBT) / qmass );
109     zetaScale = zeta * dt;
110    
111     // apply barostating and thermostating to velocities and angular momenta
112    
113     for (i=0; i < nmol; i++) {
114    
115     vxi = vx(i)*epsilonScale;
116     vyi = vy(i)*epsilonScale;
117     vzi = vz(i)*epsilonScale;
118     vxi = vxi + vx(i)*zetaScale;
119     vyi = vyi + vy(i)*zetaScale;
120     vzi = vzi + vz(i)*zetaScale;
121     jxi = jx(i)*zetaScale;
122     jyi = jy(i)*zetaScale;
123     jzi = jz(i)*zetaScale;
124    
125     vx(i) = vx(i) - vxi;
126     vy(i) = vy(i) - vyi;
127     vz(i) = vz(i) - vzi;
128     jx(i) = jx(i) - jxi;
129     jy(i) = jy(i) - jyi;
130     jz(i) = jz(i) - jzi;
131     }
132    
133    
134    
135     }
136    
137     void ExtendedSystem::affine_transform( double scale ){
138    
139     int i;
140     double boxx_old, boxy_old, boxz_old, percentScale;
141     double boxx_num, boxy_num, boxz_num, rxi, ryi, rzi;
142     double[3] r;
143    
144     // first determine the scaling factor from the box size change
145     percentScale = (boxx - boxx_old)/boxx_old;
146    
147    
148     for (i=0; i < nMols; i++) {
149    
150     molecules[i]->getCOM(r);
151    
152     // find the minimum image coordinates of the molecular centers of mass:
153    
154    
155     boxx_num = boxx_old*copysign(1.0,r[0])*(double)(int)(fabs(r[0]/boxx_old)+0.5);
156    
157     boxx_num = boxx_old*dsign(1.0d0,rx(i))*int(abs(rx(i)/boxx_old)+0.5d0);
158     boxy_num = boxy_old*dsign(1.0d0,ry(i))*int(abs(ry(i)/boxy_old)+0.5d0);
159     boxz_num = boxz_old*dsign(1.0d0,rz(i))*int(abs(rz(i)/boxz_old)+0.5d0);
160    
161     rxi = rx(i) - boxx_num;
162     ryi = ry(i) - boxy_num;
163     rzi = rz(i) - boxz_num;
164    
165     // update the minimum image coordinates using the scaling factor
166     rxi = rxi + rxi*percentScale;
167     ryi = ryi + ryi*percentScale;
168     rzi = rzi + rzi*percentScale;
169    
170     rx(i) = rxi + boxx_num;
171     ry(i) = ryi + boxy_num;
172     rz(i) = rzi + boxz_num;
173     }
174     }