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, 3 months ago) by chuckv
File size: 11279 byte(s)
Log Message:
Fixed ordering on NVT calculation in integrators.

File Contents

# User Rev Content
1 mmeineke 377 #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 gezelter 466 #include "ExtendedSystem.hpp"
11 mmeineke 377
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 gezelter 466 Verlet::Verlet( SimInfo &info, ForceFields* the_ff, ExtendedSystem* the_es ){
34 mmeineke 377
35     // get what information we need from the SimInfo object
36    
37     entry_plug = &info;
38     myFF = the_ff;
39 gezelter 466 myES = the_es;
40 mmeineke 423
41 mmeineke 377 c_natoms = info.n_atoms;
42     c_atoms = info.atoms;
43 mmeineke 423 nMols = info.n_mol;
44     molecules = info.molecules;
45 mmeineke 377 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 mmeineke 423 temp_con = new Constraint[info.n_SRI];
72 mmeineke 377
73     c_n_constrained = 0;
74     int constrained = 0;
75 mmeineke 423 SRI** theArray;
76     for(int i = 0; i < nMols; i++){
77 mmeineke 377
78 mmeineke 428 theArray = (SRI**) molecules[i].getMyBonds();
79     for(int j=0; j<molecules[i].getNBonds(); j++){
80 mmeineke 423
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 mmeineke 377
95 mmeineke 428 theArray = (SRI**) molecules[i].getMyBends();
96     for(int j=0; j<molecules[i].getNBends(); j++){
97 mmeineke 377
98 mmeineke 423 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 mmeineke 377
112 mmeineke 428 theArray = (SRI**) molecules[i].getMyTorsions();
113     for(int j=0; j<molecules[i].getNTorsions(); j++){
114 mmeineke 423
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 mmeineke 377 }
128 mmeineke 423
129    
130 mmeineke 377 }
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 mmeineke 423
139 mmeineke 377 for( int i = 0; i < c_n_constrained; i++){
140    
141     /* add 1 to the index for the fortran arrays. */
142 mmeineke 423
143 mmeineke 377 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 gezelter 468 int calcPot, calcStress;
171 mmeineke 377
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 gezelter 483 double press[9];
189    
190 mmeineke 377 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 gezelter 468 myFF->doForces(1,1);
209 mmeineke 377
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 gezelter 475 if (!strcasecmp( entry_plug->ensemble, "NPT")) {
221     calcStress = 1;
222     } else {
223     calcStress = 0;
224     }
225    
226 mmeineke 377 if( c_is_constrained ){
227     for(i = 0; i < n_loops; i++){
228    
229 gezelter 477
230 mmeineke 377 // fill R, V, and F arrays and RATTLE in fortran
231 gezelter 477
232 mmeineke 377 for( j=0; j<c_natoms; j++ ){
233 gezelter 477
234 mmeineke 377 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 chuckv 497 if (!strcasecmp( entry_plug->ensemble, "NVT"))
266     myES->NoseHooverNVT( dt / 2.0 , tStats->getKinetic() );
267    
268 mmeineke 377 // calculate the forces
269    
270 gezelter 468 myFF->doForces(calcPot,calcStress);
271 mmeineke 377
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 gezelter 471
290 mmeineke 377 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 gezelter 471 if (!strcasecmp( entry_plug->ensemble, "NVT"))
308 gezelter 477 myES->NoseHooverNVT( dt / 2.0, tStats->getKinetic() );
309    
310 gezelter 483 if (!strcasecmp( entry_plug->ensemble, "NPT") ) {
311     tStats->getPressureTensor(press);
312 gezelter 471 myES->NoseHooverAndersonNPT( dt,
313     tStats->getKinetic(),
314 gezelter 483 press);
315     }
316 gezelter 471
317 mmeineke 377 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 chuckv 479
324 gezelter 468 if( !((time+1) % status_n) ) {
325     calcPot = 1;
326 chuckv 479 calcStress = 1;
327 gezelter 468 }
328     if( !(time % status_n) ){
329     e_out->writeStat( time * dt );
330     calcPot = 0;
331 chuckv 479 if (!strcasecmp(entry_plug->ensemble, "NPT")) calcStress = 1;
332     else calcStress = 0;
333 gezelter 468 }
334 mmeineke 377 }
335     }
336     else{
337     for(i = 0; i < n_loops; i++){
338 gezelter 471
339 chuckv 497
340     move_a( dt );
341    
342 gezelter 471 if (!strcasecmp( entry_plug->ensemble, "NVT"))
343 gezelter 477 myES->NoseHooverNVT( dt / 2.0, tStats->getKinetic() );
344 mmeineke 377
345     // calculate the forces
346    
347 gezelter 468 myFF->doForces(calcPot,calcStress);
348 mmeineke 377
349     // complete the verlet move
350    
351     move_b( dt );
352    
353 gezelter 471 if (!strcasecmp( entry_plug->ensemble, "NVT"))
354 gezelter 477 myES->NoseHooverNVT( dt / 2.0 , tStats->getKinetic() );
355 gezelter 471
356 gezelter 483 if (!strcasecmp( entry_plug->ensemble, "NPT") ) {
357     tStats->getPressureTensor(press);
358 gezelter 471 myES->NoseHooverAndersonNPT( dt,
359     tStats->getKinetic(),
360 gezelter 483 press);
361     }
362 gezelter 471
363 mmeineke 377 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 gezelter 468 if( !((time+1) % status_n) ) {
370     calcPot = 1;
371 chuckv 479 calcStress = 1;
372 gezelter 468 }
373     if( !(time % status_n) ){
374     e_out->writeStat( time * dt );
375     calcPot = 0;
376 chuckv 479 if (!strcasecmp(entry_plug->ensemble, "NPT")) calcStress = 1;
377     else calcStress = 0;
378 gezelter 468 }
379 mmeineke 377 }
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     }