ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/Verlet.cpp
Revision: 497
Committed: Mon Apr 14 21:16:37 2003 UTC (21 years, 2 months ago) by chuckv
File size: 11279 byte(s)
Log Message:
Fixed ordering on NVT calculation in integrators.

File Contents

# Content
1 #include <iostream>
2 #include <stdlib.h>
3
4 #include "Atom.hpp"
5 #include "SRI.hpp"
6 #include "Integrator.hpp"
7 #include "SimInfo.hpp"
8 #include "Thermo.hpp"
9 #include "ReadWrite.hpp"
10 #include "ExtendedSystem.hpp"
11
12 extern "C"{
13
14 void v_constrain_a_( double &dt, int &n_atoms, double* mass,
15 double* Rx, double* Ry, double* Rz,
16 double* Vx, double* Vy, double* Vz,
17 double* Fx, double* Fy, double* Fz,
18 int &n_constrained, double *constr_sqr,
19 int* constr_i, int* constr_j,
20 double &box_x, double &box_y, double &box_z );
21
22 void v_constrain_b_( double &dt, int &n_atoms, double* mass,
23 double* Rx, double* Ry, double* Rz,
24 double* Vx, double* Vy, double* Vz,
25 double* Fx, double* Fy, double* Fz,
26 double &Kinetic,
27 int &n_constrained, double *constr_sqr,
28 int* constr_i, int* constr_j,
29 double &box_x, double &box_y, double &box_z );
30 }
31
32
33 Verlet::Verlet( SimInfo &info, ForceFields* the_ff, ExtendedSystem* the_es ){
34
35 // get what information we need from the SimInfo object
36
37 entry_plug = &info;
38 myFF = the_ff;
39 myES = the_es;
40
41 c_natoms = info.n_atoms;
42 c_atoms = info.atoms;
43 nMols = info.n_mol;
44 molecules = info.molecules;
45 c_is_constrained = 0;
46 c_box_x = info.box_x;
47 c_box_y = info.box_y;
48 c_box_z = info.box_z;
49
50 // give a little love back to the SimInfo object
51
52 if( info.the_integrator != NULL ) delete info.the_integrator;
53 info.the_integrator = this;
54
55 // the rest are initialization issues
56
57 is_first = 1; // let the integrate method know when the first call is
58
59 // mass array setup
60
61 c_mass = new double[c_natoms];
62
63 for(int i = 0; i < c_natoms; i++){
64 c_mass[i] = c_atoms[i]->getMass();
65 }
66
67 // check for constraints
68
69 Constraint *temp_con;
70 Constraint *dummy_plug;
71 temp_con = new Constraint[info.n_SRI];
72
73 c_n_constrained = 0;
74 int constrained = 0;
75 SRI** theArray;
76 for(int i = 0; i < nMols; i++){
77
78 theArray = (SRI**) molecules[i].getMyBonds();
79 for(int j=0; j<molecules[i].getNBonds(); j++){
80
81 constrained = theArray[j]->is_constrained();
82
83 if(constrained){
84
85 dummy_plug = theArray[j]->get_constraint();
86 temp_con[c_n_constrained].set_a( dummy_plug->get_a() );
87 temp_con[c_n_constrained].set_b( dummy_plug->get_b() );
88 temp_con[c_n_constrained].set_dsqr( dummy_plug->get_dsqr() );
89
90 c_n_constrained++;
91 constrained = 0;
92 }
93 }
94
95 theArray = (SRI**) molecules[i].getMyBends();
96 for(int j=0; j<molecules[i].getNBends(); j++){
97
98 constrained = theArray[j]->is_constrained();
99
100 if(constrained){
101
102 dummy_plug = theArray[j]->get_constraint();
103 temp_con[c_n_constrained].set_a( dummy_plug->get_a() );
104 temp_con[c_n_constrained].set_b( dummy_plug->get_b() );
105 temp_con[c_n_constrained].set_dsqr( dummy_plug->get_dsqr() );
106
107 c_n_constrained++;
108 constrained = 0;
109 }
110 }
111
112 theArray = (SRI**) molecules[i].getMyTorsions();
113 for(int j=0; j<molecules[i].getNTorsions(); j++){
114
115 constrained = theArray[j]->is_constrained();
116
117 if(constrained){
118
119 dummy_plug = theArray[j]->get_constraint();
120 temp_con[c_n_constrained].set_a( dummy_plug->get_a() );
121 temp_con[c_n_constrained].set_b( dummy_plug->get_b() );
122 temp_con[c_n_constrained].set_dsqr( dummy_plug->get_dsqr() );
123
124 c_n_constrained++;
125 constrained = 0;
126 }
127 }
128
129
130 }
131
132 if(c_n_constrained > 0){
133
134 c_is_constrained = 1;
135 c_constrained_i = new int[c_n_constrained];
136 c_constrained_j = new int[c_n_constrained];
137 c_constrained_dsqr = new double[c_n_constrained];
138
139 for( int i = 0; i < c_n_constrained; i++){
140
141 /* add 1 to the index for the fortran arrays. */
142
143 c_constrained_i[i] = temp_con[i].get_a() + 1;
144 c_constrained_j[i] = temp_con[i].get_b() + 1;
145 c_constrained_dsqr[i] = temp_con[i].get_dsqr();
146 }
147 }
148
149 delete[] temp_con;
150 }
151
152
153 Verlet::~Verlet(){
154
155 if( c_is_constrained ){
156
157 delete[] c_constrained_i;
158 delete[] c_constrained_j;
159 delete[] c_constrained_dsqr;
160 }
161
162 delete[] c_mass;
163 c_mass = 0;
164 }
165
166
167 void Verlet::integrate( void ){
168
169 int i, j; /* loop counters */
170 int calcPot, calcStress;
171
172 double kE;
173
174 double *Rx = new double[c_natoms];
175 double *Ry = new double[c_natoms];
176 double *Rz = new double[c_natoms];
177
178 double *Vx = new double[c_natoms];
179 double *Vy = new double[c_natoms];
180 double *Vz = new double[c_natoms];
181
182 double *Fx = new double[c_natoms];
183 double *Fy = new double[c_natoms];
184 double *Fz = new double[c_natoms];
185
186 int time;
187
188 double press[9];
189
190 double dt = entry_plug->dt;
191 double runTime = entry_plug->run_time;
192 double sampleTime = entry_plug->sampleTime;
193 double statusTime = entry_plug->statusTime;
194 double thermalTime = entry_plug->thermalTime;
195
196 int n_loops = (int)( runTime / dt );
197 int sample_n = (int)( sampleTime / dt );
198 int status_n = (int)( statusTime / dt );
199 int vel_n = (int)( thermalTime / dt );
200
201 Thermo *tStats = new Thermo( entry_plug );
202
203 StatWriter* e_out = new StatWriter( entry_plug );
204 DumpWriter* dump_out = new DumpWriter( entry_plug );
205
206 // the first time integrate is called, the forces need to be initialized
207
208 myFF->doForces(1,1);
209
210 if( entry_plug->setTemp ){
211 tStats->velocitize();
212 }
213
214 dump_out->writeDump( 0.0 );
215
216 e_out->writeStat( 0.0 );
217
218 calcPot = 0;
219
220 if (!strcasecmp( entry_plug->ensemble, "NPT")) {
221 calcStress = 1;
222 } else {
223 calcStress = 0;
224 }
225
226 if( c_is_constrained ){
227 for(i = 0; i < n_loops; i++){
228
229
230 // fill R, V, and F arrays and RATTLE in fortran
231
232 for( j=0; j<c_natoms; j++ ){
233
234 Rx[j] = c_atoms[j]->getX();
235 Ry[j] = c_atoms[j]->getY();
236 Rz[j] = c_atoms[j]->getZ();
237
238 Vx[j] = c_atoms[j]->get_vx();
239 Vy[j] = c_atoms[j]->get_vy();
240 Vz[j] = c_atoms[j]->get_vz();
241
242 Fx[j] = c_atoms[j]->getFx();
243 Fy[j] = c_atoms[j]->getFy();
244 Fz[j] = c_atoms[j]->getFz();
245
246 }
247
248 v_constrain_a_( dt, c_natoms, c_mass, Rx, Ry, Rz, Vx, Vy, Vz,
249 Fx, Fy, Fz,
250 c_n_constrained, c_constrained_dsqr,
251 c_constrained_i, c_constrained_j,
252 c_box_x, c_box_y, c_box_z );
253
254 for( j=0; j<c_natoms; j++ ){
255
256 c_atoms[j]->setX(Rx[j]);
257 c_atoms[j]->setY(Ry[j]);
258 c_atoms[j]->setZ(Rz[j]);
259
260 c_atoms[j]->set_vx(Vx[j]);
261 c_atoms[j]->set_vy(Vy[j]);
262 c_atoms[j]->set_vz(Vz[j]);
263 }
264
265 if (!strcasecmp( entry_plug->ensemble, "NVT"))
266 myES->NoseHooverNVT( dt / 2.0 , tStats->getKinetic() );
267
268 // calculate the forces
269
270 myFF->doForces(calcPot,calcStress);
271
272 // finish the constrain move ( same as above. )
273
274 for( j=0; j<c_natoms; j++ ){
275
276 Rx[j] = c_atoms[j]->getX();
277 Ry[j] = c_atoms[j]->getY();
278 Rz[j] = c_atoms[j]->getZ();
279
280 Vx[j] = c_atoms[j]->get_vx();
281 Vy[j] = c_atoms[j]->get_vy();
282 Vz[j] = c_atoms[j]->get_vz();
283
284 Fx[j] = c_atoms[j]->getFx();
285 Fy[j] = c_atoms[j]->getFy();
286 Fz[j] = c_atoms[j]->getFz();
287 }
288
289
290 v_constrain_b_( dt, c_natoms, c_mass, Rx, Ry, Rz, Vx, Vy, Vz,
291 Fx, Fy, Fz,
292 kE, c_n_constrained, c_constrained_dsqr,
293 c_constrained_i, c_constrained_j,
294 c_box_x, c_box_y, c_box_z );
295
296 for( j=0; j<c_natoms; j++ ){
297
298 c_atoms[j]->setX(Rx[j]);
299 c_atoms[j]->setY(Ry[j]);
300 c_atoms[j]->setZ(Rz[j]);
301
302 c_atoms[j]->set_vx(Vx[j]);
303 c_atoms[j]->set_vy(Vy[j]);
304 c_atoms[j]->set_vz(Vz[j]);
305 }
306
307 if (!strcasecmp( entry_plug->ensemble, "NVT"))
308 myES->NoseHooverNVT( dt / 2.0, tStats->getKinetic() );
309
310 if (!strcasecmp( entry_plug->ensemble, "NPT") ) {
311 tStats->getPressureTensor(press);
312 myES->NoseHooverAndersonNPT( dt,
313 tStats->getKinetic(),
314 press);
315 }
316
317 time = i + 1;
318
319 if( entry_plug->setTemp ){
320 if( !(time % vel_n) ) tStats->velocitize();
321 }
322 if( !(time % sample_n) ) dump_out->writeDump( time * dt );
323
324 if( !((time+1) % status_n) ) {
325 calcPot = 1;
326 calcStress = 1;
327 }
328 if( !(time % status_n) ){
329 e_out->writeStat( time * dt );
330 calcPot = 0;
331 if (!strcasecmp(entry_plug->ensemble, "NPT")) calcStress = 1;
332 else calcStress = 0;
333 }
334 }
335 }
336 else{
337 for(i = 0; i < n_loops; i++){
338
339
340 move_a( dt );
341
342 if (!strcasecmp( entry_plug->ensemble, "NVT"))
343 myES->NoseHooverNVT( dt / 2.0, tStats->getKinetic() );
344
345 // calculate the forces
346
347 myFF->doForces(calcPot,calcStress);
348
349 // complete the verlet move
350
351 move_b( dt );
352
353 if (!strcasecmp( entry_plug->ensemble, "NVT"))
354 myES->NoseHooverNVT( dt / 2.0 , tStats->getKinetic() );
355
356 if (!strcasecmp( entry_plug->ensemble, "NPT") ) {
357 tStats->getPressureTensor(press);
358 myES->NoseHooverAndersonNPT( dt,
359 tStats->getKinetic(),
360 press);
361 }
362
363 time = i + 1;
364
365 if( entry_plug->setTemp ){
366 if( !(time % vel_n) ) tStats->velocitize();
367 }
368 if( !(time % sample_n) ) dump_out->writeDump( time * dt );
369 if( !((time+1) % status_n) ) {
370 calcPot = 1;
371 calcStress = 1;
372 }
373 if( !(time % status_n) ){
374 e_out->writeStat( time * dt );
375 calcPot = 0;
376 if (!strcasecmp(entry_plug->ensemble, "NPT")) calcStress = 1;
377 else calcStress = 0;
378 }
379 }
380 }
381
382 dump_out->writeFinal();
383
384 delete dump_out;
385 delete e_out;
386
387 }
388
389
390 void Verlet::move_a(double dt){
391
392 const double e_convert = 4.184e-4; // converts kcal/mol -> amu*A^2/fs^2
393
394 double qx, qy, qz;
395 double vx, vy, vz;
396 int ma;
397 double h_dt = 0.5 * dt;
398 double h_dt2 = h_dt * dt;
399
400 for( ma = 0; ma < c_natoms; ma++){
401
402 qx = c_atoms[ma]->getX() + dt * c_atoms[ma]->get_vx() +
403 h_dt2 * c_atoms[ma]->getFx() * e_convert / c_atoms[ma]->getMass();
404 qy = c_atoms[ma]->getY() + dt * c_atoms[ma]->get_vy() +
405 h_dt2 * c_atoms[ma]->getFy() * e_convert / c_atoms[ma]->getMass();
406 qz = c_atoms[ma]->getZ() + dt * c_atoms[ma]->get_vz() +
407 h_dt2 * c_atoms[ma]->getFz() * e_convert / c_atoms[ma]->getMass();
408
409 vx = c_atoms[ma]->get_vx() +
410 h_dt * c_atoms[ma]->getFx() * e_convert / c_atoms[ma]->getMass();
411 vy = c_atoms[ma]->get_vy() +
412 h_dt * c_atoms[ma]->getFy() * e_convert / c_atoms[ma]->getMass();
413 vz = c_atoms[ma]->get_vz() +
414 h_dt * c_atoms[ma]->getFz() * e_convert / c_atoms[ma]->getMass();
415
416 c_atoms[ma]->setX(qx);
417 c_atoms[ma]->setY(qy);
418 c_atoms[ma]->setZ(qz);
419
420 c_atoms[ma]->set_vx(vx);
421 c_atoms[ma]->set_vy(vy);
422 c_atoms[ma]->set_vz(vz);
423 }
424 }
425
426 void Verlet::move_b( double dt ){
427
428 const double e_convert = 4.184e-4; // converts kcal/mol -> amu*A^2/fs^2
429
430 double vx, vy, vz;
431 int mb;
432 double h_dt = 0.5 * dt;
433
434
435 for( mb = 0; mb < c_natoms; mb++){
436
437 vx = c_atoms[mb]->get_vx() +
438 h_dt * c_atoms[mb]->getFx() * e_convert / c_atoms[mb]->getMass();
439 vy = c_atoms[mb]->get_vy() +
440 h_dt * c_atoms[mb]->getFy() * e_convert / c_atoms[mb]->getMass();
441 vz = c_atoms[mb]->get_vz() +
442 h_dt * c_atoms[mb]->getFz() * e_convert / c_atoms[mb]->getMass();
443
444 c_atoms[mb]->set_vx(vx);
445 c_atoms[mb]->set_vy(vy);
446 c_atoms[mb]->set_vz(vz);
447 }
448 }