# | Line 4 | Line 4 | using namespace std; | |
---|---|---|
4 | ||
5 | #ifdef IS_MPI | |
6 | #include <mpi.h> | |
7 | – | #include <mpi++.h> |
7 | #endif //is_mpi | |
8 | ||
9 | #include "Thermo.hpp" | |
10 | #include "SRI.hpp" | |
11 | #include "Integrator.hpp" | |
12 | + | #include "simError.h" |
13 | + | |
14 | + | #ifdef IS_MPI |
15 | #define __C | |
16 | < | //#include "mpiSimulation.hpp" |
16 | > | #include "mpiSimulation.hpp" |
17 | > | #endif // is_mpi |
18 | ||
19 | + | |
20 | #define BASE_SEED 123456789 | |
21 | ||
22 | Thermo::Thermo( SimInfo* the_entry_plug ) { | |
# | Line 68 | Line 72 | double Thermo::getKinetic(){ | |
72 | } | |
73 | } | |
74 | #ifdef IS_MPI | |
75 | < | MPI::COMM_WORLD.Allreduce(&kinetic,&kinetic_global,1,MPI_DOUBLE,MPI_SUM); |
75 | > | MPI_Allreduce(&kinetic,&kinetic_global,1,MPI_DOUBLE, |
76 | > | MPI_SUM, MPI_COMM_WORLD); |
77 | kinetic = kinetic_global; | |
78 | #endif //is_mpi | |
79 | ||
# | Line 82 | Line 87 | double Thermo::getPotential(){ | |
87 | double potential_local; | |
88 | double potential; | |
89 | int el, nSRI; | |
90 | < | SRI** sris; |
90 | > | Molecule* molecules; |
91 | ||
92 | < | sris = entry_plug->sr_interactions; |
92 | > | molecules = entry_plug->molecules; |
93 | nSRI = entry_plug->n_SRI; | |
94 | ||
95 | potential_local = 0.0; | |
96 | + | potential = 0.0; |
97 | potential_local += entry_plug->lrPot; | |
98 | ||
99 | < | for( el=0; el<nSRI; el++ ){ |
100 | < | potential_local += sris[el]->get_potential(); |
99 | > | for( el=0; el<entry_plug->n_mol; el++ ){ |
100 | > | potential_local += molecules[el].getPotential(); |
101 | } | |
102 | ||
103 | // Get total potential for entire system from MPI. | |
104 | #ifdef IS_MPI | |
105 | < | MPI::COMM_WORLD.Allreduce(&potential_local,&potential,1,MPI_DOUBLE,MPI_SUM); |
105 | > | MPI_Allreduce(&potential_local,&potential,1,MPI_DOUBLE, |
106 | > | MPI_SUM, MPI_COMM_WORLD); |
107 | #else | |
108 | potential = potential_local; | |
109 | #endif // is_mpi | |
110 | ||
111 | + | #ifdef IS_MPI |
112 | + | /* |
113 | + | std::cerr << "node " << worldRank << ": after pot = " << potential << "\n"; |
114 | + | */ |
115 | + | #endif |
116 | + | |
117 | return potential; | |
118 | } | |
119 | ||
# | Line 116 | Line 129 | double Thermo::getTemperature(){ | |
129 | ||
130 | const double kb = 1.9872179E-3; // boltzman's constant in kcal/(mol K) | |
131 | double temperature; | |
119 | – | int ndf_local, ndf; |
132 | ||
133 | < | ndf_local = 3 * entry_plug->n_atoms + 3 * entry_plug->n_oriented |
134 | < | - entry_plug->n_constraints; |
133 | > | temperature = ( 2.0 * this->getKinetic() ) / ((double)entry_plug->ndf * kb ); |
134 | > | return temperature; |
135 | > | } |
136 | ||
137 | < | #ifdef IS_MPI |
125 | < | MPI::COMM_WORLD.Allreduce(&ndf_local,&ndf,1,MPI_INT,MPI_SUM); |
126 | < | #else |
127 | < | ndf = ndf_local; |
128 | < | #endif |
137 | > | double Thermo::getEnthalpy() { |
138 | ||
139 | < | ndf = ndf - 3; |
139 | > | const double e_convert = 4.184E-4; // convert kcal/mol -> (amu A^2)/fs^2 |
140 | > | double u, p, v; |
141 | > | double press[9]; |
142 | > | |
143 | > | u = this->getTotalE(); |
144 | > | |
145 | > | this->getPressureTensor(press); |
146 | > | p = (press[0] + press[4] + press[8]) / 3.0; |
147 | > | |
148 | > | v = this->getVolume(); |
149 | > | |
150 | > | return (u + (p*v)/e_convert); |
151 | > | } |
152 | > | |
153 | > | double Thermo::getVolume() { |
154 | > | double theBox[3]; |
155 | > | |
156 | > | entry_plug->getBox(theBox); |
157 | > | return (theBox[0] * theBox[1] * theBox[2]); |
158 | > | } |
159 | > | |
160 | > | double Thermo::getPressure() { |
161 | > | // returns the pressure in units of atm |
162 | > | // Relies on the calculation of the full molecular pressure tensor |
163 | ||
164 | < | temperature = ( 2.0 * this->getKinetic() ) / ( ndf * kb ); |
165 | < | return temperature; |
164 | > | const double p_convert = 1.63882576e8; |
165 | > | double press[9]; |
166 | > | double pressure; |
167 | > | |
168 | > | this->getPressureTensor(press); |
169 | > | |
170 | > | pressure = p_convert * (press[0] + press[4] + press[8]) / 3.0; |
171 | > | |
172 | > | return pressure; |
173 | } | |
174 | ||
136 | – | double Thermo::getPressure(){ |
175 | ||
176 | < | // const double conv_Pa_atm = 9.901E-6; // convert Pa -> atm |
177 | < | // const double conv_internal_Pa = 1.661E-7; //convert amu/(fs^2 A) -> Pa |
178 | < | // const double conv_A_m = 1.0E-10; //convert A -> m |
176 | > | void Thermo::getPressureTensor(double press[9]){ |
177 | > | // returns pressure tensor in units amu*fs^-2*Ang^-1 |
178 | > | // routine derived via viral theorem description in: |
179 | > | // Paci, E. and Marchi, M. J.Phys.Chem. 1996, 100, 4314-4322 |
180 | ||
181 | < | return 0.0; |
181 | > | const double e_convert = 4.184e-4; |
182 | > | |
183 | > | double molmass, volume; |
184 | > | double vcom[3]; |
185 | > | double p_local[9], p_global[9]; |
186 | > | double theBox[3]; |
187 | > | //double* tau; |
188 | > | int i, nMols; |
189 | > | Molecule* molecules; |
190 | > | |
191 | > | nMols = entry_plug->n_mol; |
192 | > | molecules = entry_plug->molecules; |
193 | > | //tau = entry_plug->tau; |
194 | > | |
195 | > | // use velocities of molecular centers of mass and molecular masses: |
196 | > | for (i=0; i < 9; i++) { |
197 | > | p_local[i] = 0.0; |
198 | > | p_global[i] = 0.0; |
199 | > | } |
200 | > | |
201 | > | for (i=0; i < nMols; i++) { |
202 | > | molmass = molecules[i].getCOMvel(vcom); |
203 | > | |
204 | > | p_local[0] += molmass * (vcom[0] * vcom[0]); |
205 | > | p_local[1] += molmass * (vcom[0] * vcom[1]); |
206 | > | p_local[2] += molmass * (vcom[0] * vcom[2]); |
207 | > | p_local[3] += molmass * (vcom[1] * vcom[0]); |
208 | > | p_local[4] += molmass * (vcom[1] * vcom[1]); |
209 | > | p_local[5] += molmass * (vcom[1] * vcom[2]); |
210 | > | p_local[6] += molmass * (vcom[2] * vcom[0]); |
211 | > | p_local[7] += molmass * (vcom[2] * vcom[1]); |
212 | > | p_local[8] += molmass * (vcom[2] * vcom[2]); |
213 | > | } |
214 | > | |
215 | > | // Get total for entire system from MPI. |
216 | > | |
217 | > | #ifdef IS_MPI |
218 | > | MPI_Allreduce(p_local,p_global,9,MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); |
219 | > | #else |
220 | > | for (i=0; i<9; i++) { |
221 | > | p_global[i] = p_local[i]; |
222 | > | } |
223 | > | #endif // is_mpi |
224 | > | |
225 | > | entry_plug->getBox(theBox); |
226 | > | |
227 | > | volume = theBox[0] * theBox[1] * theBox[2]; |
228 | > | |
229 | > | for(i=0; i<9; i++) { |
230 | > | press[i] = (p_global[i] - entry_plug->tau[i]*e_convert) / volume; |
231 | > | } |
232 | } | |
233 | ||
234 | void Thermo::velocitize() { | |
# | Line 148 | Line 237 | void Thermo::velocitize() { | |
237 | double vx, vy, vz; | |
238 | double jx, jy, jz; | |
239 | int i, vr, vd; // velocity randomizer loop counters | |
240 | < | double *vdrift; |
240 | > | double vdrift[3]; |
241 | double vbar; | |
242 | const double kb = 8.31451e-7; // kb in amu, angstroms, fs, etc. | |
243 | double av2; | |
244 | double kebar; | |
156 | – | int ndf; // number of degrees of freedom |
157 | – | int ndfRaw; // the raw number of degrees of freedom |
245 | int n_atoms; | |
246 | Atom** atoms; | |
247 | DirectionalAtom* dAtom; | |
# | Line 168 | Line 255 | void Thermo::velocitize() { | |
255 | n_oriented = entry_plug->n_oriented; | |
256 | n_constraints = entry_plug->n_constraints; | |
257 | ||
258 | < | |
259 | < | ndfRaw = 3 * n_atoms + 3 * n_oriented; |
173 | < | ndf = ndfRaw - n_constraints - 3; |
174 | < | kebar = kb * temperature * (double)ndf / ( 2.0 * (double)ndfRaw ); |
258 | > | kebar = kb * temperature * (double)entry_plug->ndf / |
259 | > | ( 2.0 * (double)entry_plug->ndfRaw ); |
260 | ||
261 | for(vr = 0; vr < n_atoms; vr++){ | |
262 | ||
# | Line 179 | Line 264 | void Thermo::velocitize() { | |
264 | ||
265 | av2 = 2.0 * kebar / atoms[vr]->getMass(); | |
266 | vbar = sqrt( av2 ); | |
267 | < | |
267 | > | |
268 | // vbar = sqrt( 8.31451e-7 * temperature / atoms[vr]->getMass() ); | |
269 | ||
270 | // picks random velocities from a gaussian distribution | |
# | Line 196 | Line 281 | void Thermo::velocitize() { | |
281 | ||
282 | // Get the Center of Mass drift velocity. | |
283 | ||
284 | < | vdrift = getCOMVel(); |
284 | > | getCOMVel(vdrift); |
285 | ||
286 | // Corrects for the center of mass drift. | |
287 | // sums all the momentum and divides by total mass. | |
# | Line 228 | Line 313 | void Thermo::velocitize() { | |
313 | ||
314 | vbar = sqrt( 2.0 * kebar * dAtom->getIyy() ); | |
315 | jy = vbar * gaussStream->getGaussian(); | |
316 | < | |
316 | > | |
317 | vbar = sqrt( 2.0 * kebar * dAtom->getIzz() ); | |
318 | jz = vbar * gaussStream->getGaussian(); | |
319 | ||
# | Line 240 | Line 325 | void Thermo::velocitize() { | |
325 | } | |
326 | } | |
327 | ||
328 | < | double* Thermo::getCOMVel(){ |
328 | > | void Thermo::getCOMVel(double vdrift[3]){ |
329 | ||
330 | double mtot, mtot_local; | |
246 | – | double* vdrift; |
331 | double vdrift_local[3]; | |
332 | int vd, n_atoms; | |
333 | Atom** atoms; | |
334 | ||
251 | – | vdrift = new double[3]; |
335 | // We are very careless here with the distinction between n_atoms and n_local | |
336 | // We should really fix this before someone pokes an eye out. | |
337 | ||
# | Line 270 | Line 353 | double* Thermo::getCOMVel(){ | |
353 | } | |
354 | ||
355 | #ifdef IS_MPI | |
356 | < | MPI::COMM_WORLD.Allreduce(&mtot_local,&mtot,1,MPI_DOUBLE,MPI_SUM); |
357 | < | MPI::COMM_WORLD.Allreduce(&vdrift_local,&vdrift,3,MPI_DOUBLE,MPI_SUM); |
356 | > | MPI_Allreduce(&mtot_local,&mtot,1,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); |
357 | > | MPI_Allreduce(vdrift_local,vdrift,3,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); |
358 | #else | |
359 | mtot = mtot_local; | |
360 | for(vd = 0; vd < 3; vd++) { | |
# | Line 283 | Line 366 | double* Thermo::getCOMVel(){ | |
366 | vdrift[vd] = vdrift[vd] / mtot; | |
367 | } | |
368 | ||
286 | – | return vdrift; |
369 | } | |
370 |
– | Removed lines |
+ | Added lines |
< | Changed lines |
> | Changed lines |