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