ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/ExtendedSystem.cpp
Revision: 454
Committed: Fri Apr 4 01:57:11 2003 UTC (21 years, 3 months ago) by gezelter
File size: 5438 byte(s)
Log Message:
changes for extended system code

File Contents

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