# | Line 16 | Line 16 | using namespace std; | |
---|---|---|
16 | #include "mpiSimulation.hpp" | |
17 | #endif // is_mpi | |
18 | ||
19 | < | |
20 | < | #define BASE_SEED 123456789 |
21 | < | |
22 | < | Thermo::Thermo( SimInfo* the_entry_plug ) { |
23 | < | entry_plug = the_entry_plug; |
24 | < | int baseSeed = BASE_SEED; |
19 | > | Thermo::Thermo( SimInfo* the_info ) { |
20 | > | info = the_info; |
21 | > | int baseSeed = the_info->getSeed(); |
22 | ||
23 | gaussStream = new gaussianSPRNG( baseSeed ); | |
24 | } | |
# | Line 33 | Line 30 | double Thermo::getKinetic(){ | |
30 | double Thermo::getKinetic(){ | |
31 | ||
32 | const double e_convert = 4.184E-4; // convert kcal/mol -> (amu A^2)/fs^2 | |
33 | < | double vx2, vy2, vz2; |
34 | < | double kinetic, v_sqr; |
35 | < | int kl; |
36 | < | double jx2, jy2, jz2; // the square of the angular momentums |
33 | > | double kinetic; |
34 | > | double amass; |
35 | > | double aVel[3], aJ[3], I[3][3]; |
36 | > | int j, kl; |
37 | ||
38 | DirectionalAtom *dAtom; | |
39 | ||
# | Line 45 | Line 42 | double Thermo::getKinetic(){ | |
42 | Atom** atoms; | |
43 | ||
44 | ||
45 | < | n_atoms = entry_plug->n_atoms; |
46 | < | atoms = entry_plug->atoms; |
45 | > | n_atoms = info->n_atoms; |
46 | > | atoms = info->atoms; |
47 | ||
48 | kinetic = 0.0; | |
49 | kinetic_global = 0.0; | |
50 | for( kl=0; kl < n_atoms; kl++ ){ | |
51 | + | |
52 | + | atoms[kl]->getVel(aVel); |
53 | + | amass = atoms[kl]->getMass(); |
54 | + | |
55 | + | for (j=0; j < 3; j++) |
56 | + | kinetic += amass * aVel[j] * aVel[j]; |
57 | ||
55 | – | vx2 = atoms[kl]->get_vx() * atoms[kl]->get_vx(); |
56 | – | vy2 = atoms[kl]->get_vy() * atoms[kl]->get_vy(); |
57 | – | vz2 = atoms[kl]->get_vz() * atoms[kl]->get_vz(); |
58 | – | |
59 | – | v_sqr = vx2 + vy2 + vz2; |
60 | – | kinetic += atoms[kl]->getMass() * v_sqr; |
61 | – | |
58 | if( atoms[kl]->isDirectional() ){ | |
59 | ||
60 | dAtom = (DirectionalAtom *)atoms[kl]; | |
61 | + | |
62 | + | dAtom->getJ( aJ ); |
63 | + | dAtom->getI( I ); |
64 | ||
65 | < | jx2 = dAtom->getJx() * dAtom->getJx(); |
66 | < | jy2 = dAtom->getJy() * dAtom->getJy(); |
68 | < | jz2 = dAtom->getJz() * dAtom->getJz(); |
65 | > | for (j=0; j<3; j++) |
66 | > | kinetic += aJ[j]*aJ[j] / I[j][j]; |
67 | ||
70 | – | kinetic += (jx2 / dAtom->getIxx()) + (jy2 / dAtom->getIyy()) |
71 | – | + (jz2 / dAtom->getIzz()); |
68 | } | |
69 | } | |
70 | #ifdef IS_MPI | |
# | Line 89 | Line 85 | double Thermo::getPotential(){ | |
85 | int el, nSRI; | |
86 | Molecule* molecules; | |
87 | ||
88 | < | molecules = entry_plug->molecules; |
89 | < | nSRI = entry_plug->n_SRI; |
88 | > | molecules = info->molecules; |
89 | > | nSRI = info->n_SRI; |
90 | ||
91 | potential_local = 0.0; | |
92 | potential = 0.0; | |
93 | < | potential_local += entry_plug->lrPot; |
93 | > | potential_local += info->lrPot; |
94 | ||
95 | < | for( el=0; el<entry_plug->n_mol; el++ ){ |
95 | > | for( el=0; el<info->n_mol; el++ ){ |
96 | potential_local += molecules[el].getPotential(); | |
97 | } | |
98 | ||
# | Line 127 | Line 123 | double Thermo::getTemperature(){ | |
123 | ||
124 | double Thermo::getTemperature(){ | |
125 | ||
126 | < | const double kb = 1.9872179E-3; // boltzman's constant in kcal/(mol K) |
126 | > | const double kb = 1.9872156E-3; // boltzman's constant in kcal/(mol K) |
127 | double temperature; | |
128 | ||
129 | < | temperature = ( 2.0 * this->getKinetic() ) / ((double)entry_plug->ndf * kb ); |
129 | > | temperature = ( 2.0 * this->getKinetic() ) / ((double)info->ndf * kb ); |
130 | return temperature; | |
131 | } | |
132 | ||
# | Line 138 | Line 134 | double Thermo::getEnthalpy() { | |
134 | ||
135 | const double e_convert = 4.184E-4; // convert kcal/mol -> (amu A^2)/fs^2 | |
136 | double u, p, v; | |
137 | < | double press[9]; |
137 | > | double press[3][3]; |
138 | ||
139 | u = this->getTotalE(); | |
140 | ||
141 | this->getPressureTensor(press); | |
142 | < | p = (press[0] + press[4] + press[8]) / 3.0; |
142 | > | p = (press[0][0] + press[1][1] + press[2][2]) / 3.0; |
143 | ||
144 | v = this->getVolume(); | |
145 | ||
# | Line 152 | Line 148 | double Thermo::getVolume() { | |
148 | ||
149 | double Thermo::getVolume() { | |
150 | ||
151 | < | return entry_plug->boxVol; |
151 | > | return info->boxVol; |
152 | } | |
153 | ||
154 | double Thermo::getPressure() { | |
# | Line 160 | Line 156 | double Thermo::getPressure() { | |
156 | // Relies on the calculation of the full molecular pressure tensor | |
157 | ||
158 | const double p_convert = 1.63882576e8; | |
159 | < | double press[9]; |
159 | > | double press[3][3]; |
160 | double pressure; | |
161 | ||
162 | this->getPressureTensor(press); | |
163 | ||
164 | < | pressure = p_convert * (press[0] + press[4] + press[8]) / 3.0; |
164 | > | pressure = p_convert * (press[0][0] + press[1][1] + press[2][2]) / 3.0; |
165 | ||
166 | return pressure; | |
167 | } | |
168 | ||
169 | + | double Thermo::getPressureX() { |
170 | ||
171 | < | void Thermo::getPressureTensor(double press[9]){ |
171 | > | // Relies on the calculation of the full molecular pressure tensor |
172 | > | |
173 | > | const double p_convert = 1.63882576e8; |
174 | > | double press[3][3]; |
175 | > | double pressureX; |
176 | > | |
177 | > | this->getPressureTensor(press); |
178 | > | |
179 | > | pressureX = p_convert * press[0][0]; |
180 | > | |
181 | > | return pressureX; |
182 | > | } |
183 | > | |
184 | > | double Thermo::getPressureY() { |
185 | > | |
186 | > | // Relies on the calculation of the full molecular pressure tensor |
187 | > | |
188 | > | const double p_convert = 1.63882576e8; |
189 | > | double press[3][3]; |
190 | > | double pressureY; |
191 | > | |
192 | > | this->getPressureTensor(press); |
193 | > | |
194 | > | pressureY = p_convert * press[1][1]; |
195 | > | |
196 | > | return pressureY; |
197 | > | } |
198 | > | |
199 | > | double Thermo::getPressureZ() { |
200 | > | |
201 | > | // Relies on the calculation of the full molecular pressure tensor |
202 | > | |
203 | > | const double p_convert = 1.63882576e8; |
204 | > | double press[3][3]; |
205 | > | double pressureZ; |
206 | > | |
207 | > | this->getPressureTensor(press); |
208 | > | |
209 | > | pressureZ = p_convert * press[2][2]; |
210 | > | |
211 | > | return pressureZ; |
212 | > | } |
213 | > | |
214 | > | |
215 | > | void Thermo::getPressureTensor(double press[3][3]){ |
216 | // returns pressure tensor in units amu*fs^-2*Ang^-1 | |
217 | // routine derived via viral theorem description in: | |
218 | // Paci, E. and Marchi, M. J.Phys.Chem. 1996, 100, 4314-4322 | |
# | Line 181 | Line 222 | void Thermo::getPressureTensor(double press[9]){ | |
222 | double molmass, volume; | |
223 | double vcom[3]; | |
224 | double p_local[9], p_global[9]; | |
225 | < | double theBox[3]; |
185 | < | //double* tau; |
186 | < | int i, nMols; |
225 | > | int i, j, k, nMols; |
226 | Molecule* molecules; | |
227 | ||
228 | < | nMols = entry_plug->n_mol; |
229 | < | molecules = entry_plug->molecules; |
230 | < | //tau = entry_plug->tau; |
228 | > | nMols = info->n_mol; |
229 | > | molecules = info->molecules; |
230 | > | //tau = info->tau; |
231 | ||
232 | // use velocities of molecular centers of mass and molecular masses: | |
233 | for (i=0; i < 9; i++) { | |
# | Line 220 | Line 259 | void Thermo::getPressureTensor(double press[9]){ | |
259 | } | |
260 | #endif // is_mpi | |
261 | ||
262 | < | volume = entry_plug->boxVol; |
262 | > | volume = this->getVolume(); |
263 | ||
264 | < | for(i=0; i<9; i++) { |
265 | < | press[i] = (p_global[i] - entry_plug->tau[i]*e_convert) / volume; |
264 | > | for(i = 0; i < 3; i++) { |
265 | > | for (j = 0; j < 3; j++) { |
266 | > | k = 3*i + j; |
267 | > | press[i][j] = (p_global[k] + info->tau[k]*e_convert) / volume; |
268 | > | |
269 | > | } |
270 | } | |
271 | } | |
272 | ||
273 | void Thermo::velocitize() { | |
274 | ||
275 | < | double x,y; |
276 | < | double vx, vy, vz; |
234 | < | double jx, jy, jz; |
235 | < | int i, vr, vd; // velocity randomizer loop counters |
275 | > | double aVel[3], aJ[3], I[3][3]; |
276 | > | int i, j, vr, vd; // velocity randomizer loop counters |
277 | double vdrift[3]; | |
278 | double vbar; | |
279 | const double kb = 8.31451e-7; // kb in amu, angstroms, fs, etc. | |
# | Line 245 | Line 286 | void Thermo::velocitize() { | |
286 | int n_oriented; | |
287 | int n_constraints; | |
288 | ||
289 | < | atoms = entry_plug->atoms; |
290 | < | n_atoms = entry_plug->n_atoms; |
291 | < | temperature = entry_plug->target_temp; |
292 | < | n_oriented = entry_plug->n_oriented; |
293 | < | n_constraints = entry_plug->n_constraints; |
289 | > | atoms = info->atoms; |
290 | > | n_atoms = info->n_atoms; |
291 | > | temperature = info->target_temp; |
292 | > | n_oriented = info->n_oriented; |
293 | > | n_constraints = info->n_constraints; |
294 | ||
295 | < | kebar = kb * temperature * (double)entry_plug->ndf / |
296 | < | ( 2.0 * (double)entry_plug->ndfRaw ); |
295 | > | kebar = kb * temperature * (double)info->ndfRaw / |
296 | > | ( 2.0 * (double)info->ndf ); |
297 | ||
298 | for(vr = 0; vr < n_atoms; vr++){ | |
299 | ||
# | Line 266 | Line 307 | void Thermo::velocitize() { | |
307 | // picks random velocities from a gaussian distribution | |
308 | // centered on vbar | |
309 | ||
310 | < | vx = vbar * gaussStream->getGaussian(); |
311 | < | vy = vbar * gaussStream->getGaussian(); |
312 | < | vz = vbar * gaussStream->getGaussian(); |
310 | > | for (j=0; j<3; j++) |
311 | > | aVel[j] = vbar * gaussStream->getGaussian(); |
312 | > | |
313 | > | atoms[vr]->setVel( aVel ); |
314 | ||
273 | – | atoms[vr]->set_vx( vx ); |
274 | – | atoms[vr]->set_vy( vy ); |
275 | – | atoms[vr]->set_vz( vz ); |
315 | } | |
316 | ||
317 | // Get the Center of Mass drift velocity. | |
# | Line 284 | Line 323 | void Thermo::velocitize() { | |
323 | ||
324 | for(vd = 0; vd < n_atoms; vd++){ | |
325 | ||
326 | < | vx = atoms[vd]->get_vx(); |
288 | < | vy = atoms[vd]->get_vy(); |
289 | < | vz = atoms[vd]->get_vz(); |
290 | < | |
291 | < | vx -= vdrift[0]; |
292 | < | vy -= vdrift[1]; |
293 | < | vz -= vdrift[2]; |
326 | > | atoms[vd]->getVel(aVel); |
327 | ||
328 | < | atoms[vd]->set_vx(vx); |
329 | < | atoms[vd]->set_vy(vy); |
330 | < | atoms[vd]->set_vz(vz); |
328 | > | for (j=0; j < 3; j++) |
329 | > | aVel[j] -= vdrift[j]; |
330 | > | |
331 | > | atoms[vd]->setVel( aVel ); |
332 | } | |
333 | if( n_oriented ){ | |
334 | ||
# | Line 303 | Line 337 | void Thermo::velocitize() { | |
337 | if( atoms[i]->isDirectional() ){ | |
338 | ||
339 | dAtom = (DirectionalAtom *)atoms[i]; | |
340 | + | dAtom->getI( I ); |
341 | + | |
342 | + | for (j = 0 ; j < 3; j++) { |
343 | ||
344 | < | vbar = sqrt( 2.0 * kebar * dAtom->getIxx() ); |
345 | < | jx = vbar * gaussStream->getGaussian(); |
344 | > | vbar = sqrt( 2.0 * kebar * I[j][j] ); |
345 | > | aJ[j] = vbar * gaussStream->getGaussian(); |
346 | ||
347 | < | vbar = sqrt( 2.0 * kebar * dAtom->getIyy() ); |
348 | < | jy = vbar * gaussStream->getGaussian(); |
349 | < | |
350 | < | vbar = sqrt( 2.0 * kebar * dAtom->getIzz() ); |
314 | < | jz = vbar * gaussStream->getGaussian(); |
315 | < | |
316 | < | dAtom->setJx( jx ); |
317 | < | dAtom->setJy( jy ); |
318 | < | dAtom->setJz( jz ); |
347 | > | } |
348 | > | |
349 | > | dAtom->setJ( aJ ); |
350 | > | |
351 | } | |
352 | } | |
353 | } | |
# | Line 324 | Line 356 | void Thermo::getCOMVel(double vdrift[3]){ | |
356 | void Thermo::getCOMVel(double vdrift[3]){ | |
357 | ||
358 | double mtot, mtot_local; | |
359 | + | double aVel[3], amass; |
360 | double vdrift_local[3]; | |
361 | < | int vd, n_atoms; |
361 | > | int vd, n_atoms, j; |
362 | Atom** atoms; | |
363 | ||
364 | // We are very careless here with the distinction between n_atoms and n_local | |
365 | // We should really fix this before someone pokes an eye out. | |
366 | ||
367 | < | n_atoms = entry_plug->n_atoms; |
368 | < | atoms = entry_plug->atoms; |
367 | > | n_atoms = info->n_atoms; |
368 | > | atoms = info->atoms; |
369 | ||
370 | mtot_local = 0.0; | |
371 | vdrift_local[0] = 0.0; | |
# | Line 341 | Line 374 | void Thermo::getCOMVel(double vdrift[3]){ | |
374 | ||
375 | for(vd = 0; vd < n_atoms; vd++){ | |
376 | ||
377 | < | vdrift_local[0] += atoms[vd]->get_vx() * atoms[vd]->getMass(); |
378 | < | vdrift_local[1] += atoms[vd]->get_vy() * atoms[vd]->getMass(); |
379 | < | vdrift_local[2] += atoms[vd]->get_vz() * atoms[vd]->getMass(); |
377 | > | amass = atoms[vd]->getMass(); |
378 | > | atoms[vd]->getVel( aVel ); |
379 | > | |
380 | > | for(j = 0; j < 3; j++) |
381 | > | vdrift_local[j] += aVel[j] * amass; |
382 | ||
383 | < | mtot_local += atoms[vd]->getMass(); |
383 | > | mtot_local += amass; |
384 | } | |
385 | ||
386 | #ifdef IS_MPI | |
# | Line 364 | Line 399 | void Thermo::getCOMVel(double vdrift[3]){ | |
399 | ||
400 | } | |
401 | ||
402 | + | void Thermo::getCOM(double COM[3]){ |
403 | + | |
404 | + | double mtot, mtot_local; |
405 | + | double aPos[3], amass; |
406 | + | double COM_local[3]; |
407 | + | int i, n_atoms, j; |
408 | + | Atom** atoms; |
409 | + | |
410 | + | // We are very careless here with the distinction between n_atoms and n_local |
411 | + | // We should really fix this before someone pokes an eye out. |
412 | + | |
413 | + | n_atoms = info->n_atoms; |
414 | + | atoms = info->atoms; |
415 | + | |
416 | + | mtot_local = 0.0; |
417 | + | COM_local[0] = 0.0; |
418 | + | COM_local[1] = 0.0; |
419 | + | COM_local[2] = 0.0; |
420 | + | |
421 | + | for(i = 0; i < n_atoms; i++){ |
422 | + | |
423 | + | amass = atoms[i]->getMass(); |
424 | + | atoms[i]->getPos( aPos ); |
425 | + | |
426 | + | for(j = 0; j < 3; j++) |
427 | + | COM_local[j] += aPos[j] * amass; |
428 | + | |
429 | + | mtot_local += amass; |
430 | + | } |
431 | + | |
432 | + | #ifdef IS_MPI |
433 | + | MPI_Allreduce(&mtot_local,&mtot,1,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); |
434 | + | MPI_Allreduce(COM_local,COM,3,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); |
435 | + | #else |
436 | + | mtot = mtot_local; |
437 | + | for(i = 0; i < 3; i++) { |
438 | + | COM[i] = COM_local[i]; |
439 | + | } |
440 | + | #endif |
441 | + | |
442 | + | for (i = 0; i < 3; i++) { |
443 | + | COM[i] = COM[i] / mtot; |
444 | + | } |
445 | + | } |
– | Removed lines |
+ | Added lines |
< | Changed lines |
> | Changed lines |