ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/md_code/Verlet.cpp
Revision: 10
Committed: Tue Jul 9 18:40:59 2002 UTC (21 years, 11 months ago) by mmeineke
Original Path: branches/mmeineke/mdtools/md_code/Verlet.cpp
File size: 10560 byte(s)
Log Message:
everything you need to make libmdtools

File Contents

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