NAMD
Output.C
Go to the documentation of this file.
1 
7 /*
8  This object outputs the data collected on the master node
9 */
10 
11 #include "largefiles.h" // must be first!
12 
13 #include <string.h>
14 #include <stdlib.h>
15 
16 #include "InfoStream.h"
17 #include "IMDOutput.h"
18 #include "Output.h"
19 #include "dcdlib.h"
20 #include "strlib.h"
21 #include "Molecule.h"
22 #include "Node.h"
23 #include "Parameters.h"
24 #include "PDB.h"
25 #include "SimParameters.h"
26 #include "Vector.h"
27 #include "structures.h"
28 #include "MStream.h"
29 #include "Communicate.h"
30 #include "PatchMap.h"
31 #include "PatchMap.inl"
32 #include "ScriptTcl.h"
33 #include "Lattice.h"
34 #include "DataExchanger.h"
35 #include <fcntl.h>
36 #include <sys/stat.h>
37 #ifdef WIN32
38 #include <io.h>
39 #define access(PATH,MODE) _access(PATH,00)
40 #endif
41 
42 #if defined(WIN32) && !defined(__CYGWIN__)
43 #define PATHSEPSTR "\\"
44 #define MKDIR(X) mkdir(X)
45 #else
46 #define PATHSEPSTR "/"
47 #define MKDIR(X) mkdir(X,0777)
48 #endif
49 
50 #define NAMD_open NAMD_open64
51 #define NAMD_write NAMD_write64
52 #define NAMD_close NAMD_close64
53 
54 #ifndef O_LARGEFILE
55 #define O_LARGEFILE 0x0
56 #endif
57 
58 // same as open, only does error checking internally
59 int NAMD_open(const char *fname) {
60  int fd;
61 
62  // open the file and die if the open fails
63 #ifdef WIN32
64  while ( (fd = _open(fname, O_WRONLY|O_CREAT|O_EXCL|O_BINARY|O_LARGEFILE,_S_IREAD|_S_IWRITE)) < 0) {
65 #else
66 #ifdef NAMD_NO_O_EXCL
67  while ( (fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE,
68 #else
69  while ( (fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE,
70 #endif
71  S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
72 #endif
73  if ( errno != EINTR ) {
74  char errmsg[1024];
75  sprintf(errmsg, "Unable to open binary file %s", fname);
76  NAMD_err(errmsg);
77  }
78  }
79 
80  return fd;
81 }
82 
83 // same as write, only does error checking internally
84 void NAMD_write(int fd, const char *buf, size_t count, const char *errmsg="NAMD_write64") {
85  double firsttime = 0.;
86  while ( count ) {
87 #if defined(WIN32) && !defined(__CYGWIN__)
88  long retval = _write(fd,buf,count);
89 #else
90  ssize_t retval = write(fd,buf,count);
91 #endif
92  if ( retval < 0 && errno == EINTR ) retval = 0;
93  if ( retval < 0 && errno == ENOMEM ) {
94  if ( firsttime == 0. ) firsttime = CmiWallTimer();
95  if ( (CmiWallTimer() - firsttime) < 300. ) retval = 0;
96  }
97  if ( retval < 0 ) NAMD_err(errmsg);
98  if ( retval > count ) NAMD_bug("extra bytes written in NAMD_write64()");
99  buf += retval;
100  count -= retval;
101  }
102  if ( firsttime != 0. ) {
103  iout << iWARN << errmsg << ": NAMD_write64() retried for " << (CmiWallTimer() - firsttime) << " seconds.\n" << endi;
104  }
105 }
106 
107 // same as close, only does error checking internally
108 void NAMD_close(int fd, const char *fname) {
109 #ifdef WIN32
110  while ( _close(fd) ) {
111 #else
112  while ( close(fd) ) {
113 #endif
114  if ( errno != EINTR ) {
115  char errmsg[1024];
116  sprintf(errmsg, "Error on closing file %s", fname);
117  NAMD_err(errmsg);
118  }
119  }
120 }
121 
122 
123 #define seek_dcdfile NAMD_seek
124 
125 // These make the NAMD 1 names work in NAMD 2
126 #define namdMyNode Node::Object()
127 #define simParams simParameters
128 #define pdbData pdb
129 
130 
131 static void lattice_to_unitcell(const Lattice *lattice, double *unitcell) {
132 
133  unitcell[0] = unitcell[2] = unitcell[5] = 0.0;
134  unitcell[1] = unitcell[3] = unitcell[4] = 0.0;
135 
136  if (lattice) {
137  const Vector &a=lattice->a();
138  const Vector &b=lattice->b();
139  const Vector &c=lattice->c();
140  unitcell[0] = (lattice->a_p()) ? a.length() : 0.0;
141  unitcell[2] = (lattice->b_p()) ? b.length() : 0.0;
142  unitcell[5] = (lattice->c_p()) ? c.length() : 0.0;
143  double cosAB = (lattice->a_p() && lattice->b_p() ) ?
144  (a*b)/(unitcell[0]*unitcell[2]) : 0.0;
145  double cosAC = (lattice->a_p() && lattice->c_p() ) ?
146  (a*c)/(unitcell[0]*unitcell[5]) : 0.0;
147  double cosBC = (lattice->b_p() && lattice->c_p() ) ?
148  (b*c)/(unitcell[2]*unitcell[5]) : 0.0;
149  if (cosAB > 1.0) cosAB = 1.0; else if (cosAB < -1.0) cosAB = -1.0;
150  if (cosAC > 1.0) cosAC = 1.0; else if (cosAC < -1.0) cosAC = -1.0;
151  if (cosBC > 1.0) cosBC = 1.0; else if (cosBC < -1.0) cosBC = -1.0;
152  unitcell[1] = cosAB;
153  unitcell[3] = cosAC;
154  unitcell[4] = cosBC;
155  }
156 }
157 
158 
159 /************************************************************************/
160 /* */
161 /* FUNCTION Output */
162 /* */
163 /* This is the constructor for the Ouput class. It just sets */
164 /* up some values for the VMD connection. */
165 /* */
166 /************************************************************************/
167 
168 Output::Output() : replicaDcdActive(0) { }
169 
170 /* END OF FUNCTION Output */
171 
172 /************************************************************************/
173 /* */
174 /* FUNCTION ~Output */
175 /* */
176 /************************************************************************/
177 
179 
180 /* END OF FUNCTION ~Output */
181 
182 /************************************************************************/
183 /* */
184 /* FUNCTION coordinate */
185 /* */
186 /* INPUTS: */
187 /* timestep - Timestep coordinates were accumulated for */
188 /* n - This is the number of coordinates accumulated. */
189 /* vel - Array of Vectors containing the velocities */
190 /* */
191 /* This function receives the coordinates accumulated for a given */
192 /* timestep from the Collect object and calls the appropriate output */
193 /* functions. ALL routines used to output coordinates information */
194 /* should be called from here. */
195 /* */
196 /************************************************************************/
197 
198 int Output::coordinateNeeded(int timestep)
199 {
201 
202  if(simParams->benchTimestep) return 0;
203 
204  int positionsNeeded = 0;
205 
206  if ( timestep >= 0 ) {
207 
208  // Output a DCD trajectory
209  if ( simParams->dcdFrequency &&
210  ((timestep % simParams->dcdFrequency) == 0) )
211  { positionsNeeded |= 1; }
212 
213  // Output a restart file
214  if ( simParams->restartFrequency &&
215  ((timestep % simParams->restartFrequency) == 0) )
216  { positionsNeeded |= 2; }
217 
218  // Iteractive MD
219  if ( simParams->IMDon &&
220  ( ((timestep % simParams->IMDfreq) == 0) ||
221  (timestep == simParams->firstTimestep) ) )
222  { positionsNeeded |= 1; }
223 
224  }
225 
226  // Output final coordinates
227  if (timestep == FILE_OUTPUT || timestep == END_OF_RUN ||
228  timestep == EVAL_MEASURE)
229  {
230  positionsNeeded |= 2;
231  }
232 
233  return positionsNeeded;
234 }
235 
236 template <class xVector, class xDone>
237 void wrap_coor_int(xVector *coor, Lattice &lattice, xDone *done) {
239  if ( *done ) return;
240  *done = 1;
241  if ( ! ( simParams->wrapAll || simParams->wrapWater ) ) return;
242  const int wrapNearest = simParams->wrapNearest;
243  const int wrapAll = simParams->wrapAll;
244  Molecule *molecule = Node::Object()->molecule;
245  int n = molecule->numAtoms;
246  int i;
247 #ifndef MEM_OPT_VERSION
248  Position *con = new Position[n];
249  for ( i = 0; i < n; ++i ) {
250  con[i] = 0;
251  int ci = molecule->get_cluster(i);
252  con[ci] += coor[i];
253  }
254  for ( i = 0; i < n; ++i ) {
255  if ( ! wrapAll && ! molecule->is_water(i) ) continue;
256  int ci = molecule->get_cluster(i);
257  if ( ci == i ) {
258  Vector coni = con[i] / molecule->get_clusterSize(i);
259  Vector trans = ( wrapNearest ?
260  lattice.wrap_nearest_delta(coni) : lattice.wrap_delta(coni) );
261  con[i] = trans;
262  }
263  coor[i] = coor[i] + con[ci];
264  }
265  delete [] con;
266 #endif
267 }
268 
269 void wrap_coor(Vector *coor, Lattice &lattice, double *done) {
270  wrap_coor_int(coor,lattice,done);
271 };
272 
273 void wrap_coor(FloatVector *coor, Lattice &lattice, float *done) {
274  wrap_coor_int(coor,lattice,done);
275 };
276 
277 void Output::coordinate(int timestep, int n, Vector *coor, FloatVector *fcoor,
278  Lattice &lattice)
279 {
281  double coor_wrapped = 0;
282  float fcoor_wrapped = 0;
283 
284  if ( timestep >= 0 ) {
285 
286  // Output a DCD trajectory
287  if ( simParams->dcdFrequency &&
288  ((timestep % simParams->dcdFrequency) == 0) )
289  {
290  wrap_coor(fcoor,lattice,&fcoor_wrapped);
291  output_dcdfile(timestep, n, fcoor,
292  simParams->dcdUnitCell ? &lattice : NULL);
293  }
294 
295  // Output a restart file
296  if ( simParams->restartFrequency &&
297  ((timestep % simParams->restartFrequency) == 0) )
298  {
299  iout << "WRITING COORDINATES TO RESTART FILE AT STEP "
300  << timestep << "\n" << endi;
301  wrap_coor(coor,lattice,&coor_wrapped);
302  output_restart_coordinates(coor, n, timestep);
303  iout << "FINISHED WRITING RESTART COORDINATES\n" <<endi;
304  fflush(stdout);
305  }
306 
307  // Interactive MD
308  if ( simParams->IMDon &&
309  ( ((timestep % simParams->IMDfreq) == 0) ||
310  (timestep == simParams->firstTimestep) ) )
311  {
312  IMDOutput *imd = Node::Object()->imd;
313  wrap_coor(fcoor,lattice,&fcoor_wrapped);
314  if (imd != NULL) imd->gather_coordinates(timestep, n, fcoor);
315  }
316 
317  }
318 
319  if (timestep == EVAL_MEASURE)
320  {
321 #ifdef NAMD_TCL
322  wrap_coor(coor,lattice,&coor_wrapped);
323  Node::Object()->getScript()->measure(coor);
324 #endif
325  }
326 
327  // Output final coordinates
328  if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
329  {
330  int realstep = ( timestep == FILE_OUTPUT ?
331  simParams->firstTimestep : simParams->N );
332  iout << "WRITING COORDINATES TO OUTPUT FILE AT STEP "
333  << realstep << "\n" << endi;
334  fflush(stdout);
335  wrap_coor(coor,lattice,&coor_wrapped);
336  output_final_coordinates(coor, n, realstep);
337  }
338 
339  // Close trajectory files
340  if (timestep == END_OF_RUN)
341  {
342  if (simParams->dcdFrequency) output_dcdfile(END_OF_RUN,0,0,
343  simParams->dcdUnitCell ? &lattice : NULL);
344  }
345 
346 }
347 /* END OF FUNCTION coordinate */
348 
349 /************************************************************************/
350 /* */
351 /* FUNCTION velocity */
352 /* */
353 /* INPUTS: */
354 /* timestep - Timestep velocities were accumulated for */
355 /* n - This is the number of velocities accumulated. */
356 /* vel - Array of Vectors containing the velocities */
357 /* */
358 /* This function receives the velocities accumulated for a given */
359 /* timestep from the Collect object and calls the appropriate output */
360 /* functions. ALL routines used to output velocity information should*/
361 /* be called from here. */
362 /* */
363 /************************************************************************/
364 
365 int Output::velocityNeeded(int timestep)
366 {
368 
369  if(simParams->benchTimestep) return 0;
370 
371  int velocitiesNeeded = 0;
372 
373  if ( timestep >= 0 ) {
374 
375  // Output a velocity DCD trajectory
376  if ( simParams->velDcdFrequency &&
377  ((timestep % simParams->velDcdFrequency) == 0) )
378  { velocitiesNeeded |= 1; }
379 
380  // Output a restart file
381  if ( simParams->restartFrequency &&
382  ((timestep % simParams->restartFrequency) == 0) )
383  { velocitiesNeeded |= 2; }
384 
385  }
386 
387  // Output final velocities
388  if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
389  {
390  velocitiesNeeded |= 2;
391  }
392 
393  return velocitiesNeeded;
394 }
395 
396 void Output::velocity(int timestep, int n, Vector *vel)
397 {
399 
400  if ( timestep >= 0 ) {
401 
402  // Output velocity DCD trajectory
403  if ( simParams->velDcdFrequency &&
404  ((timestep % simParams->velDcdFrequency) == 0) )
405  {
406  output_veldcdfile(timestep, n, vel);
407  }
408 
409  // Output restart file
410  if ( simParams->restartFrequency &&
411  ((timestep % simParams->restartFrequency) == 0) )
412  {
413  iout << "WRITING VELOCITIES TO RESTART FILE AT STEP "
414  << timestep << "\n" << endi;
415  output_restart_velocities(timestep, n, vel);
416  iout << "FINISHED WRITING RESTART VELOCITIES\n" <<endi;
417  fflush(stdout);
418  }
419 
420  }
421 
422  // Output final velocities
423  if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
424  {
425  int realstep = ( timestep == FILE_OUTPUT ?
426  simParams->firstTimestep : simParams->N );
427  iout << "WRITING VELOCITIES TO OUTPUT FILE AT STEP "
428  << realstep << "\n" << endi;
429  fflush(stdout);
430  output_final_velocities(realstep, n, vel);
431  }
432 
433  // Close trajectory files
434  if (timestep == END_OF_RUN)
435  {
436  if (simParams->velDcdFrequency) output_veldcdfile(END_OF_RUN,0,0);
437  // close force dcd file here since no final force output below
438  if (simParams->forceDcdFrequency) output_forcedcdfile(END_OF_RUN,0,0);
439  }
440 
441 }
442 /* END OF FUNCTION velocity */
443 
444 /************************************************************************/
445 /* */
446 /* FUNCTION force */
447 /* */
448 /* INPUTS: */
449 /* timestep - Timestep forces were accumulated for */
450 /* n - This is the number of forces accumulated. */
451 /* frc - Array of Vectors containing the forces */
452 /* */
453 /* This function receives the forces accumulated for a given */
454 /* timestep from the Collect object and calls the appropriate output */
455 /* functions. ALL routines used to output force information should*/
456 /* be called from here. */
457 /* */
458 /************************************************************************/
459 
460 int Output::forceNeeded(int timestep)
461 {
463 
464  if(simParams->benchTimestep) return 0;
465 
466  int forcesNeeded = 0;
467 
468  if ( timestep >= 0 ) {
469 
470  // Output a force DCD trajectory
471  if ( simParams->forceDcdFrequency &&
472  ((timestep % simParams->forceDcdFrequency) == 0) )
473  { forcesNeeded |= 1; }
474 
475  }
476 
477  // Output forces
478  if (timestep == FORCE_OUTPUT)
479  {
480  forcesNeeded |= 2;
481  }
482 
483  return forcesNeeded;
484 }
485 
486 void Output::force(int timestep, int n, Vector *frc)
487 {
489 
490  if ( timestep >= 0 ) {
491 
492  // Output force DCD trajectory
493  if ( simParams->forceDcdFrequency &&
494  ((timestep % simParams->forceDcdFrequency) == 0) )
495  {
496  output_forcedcdfile(timestep, n, frc);
497  }
498 
499  }
500 
501  // Output forces
502  if (timestep == FORCE_OUTPUT)
503  {
504  int realstep = simParams->firstTimestep;
505  iout << "WRITING FORCES TO OUTPUT FILE AT STEP "
506  << realstep << "\n" << endi;
507  fflush(stdout);
508  output_forces(realstep, n, frc);
509  }
510 
511  // Trajectory file closed by velocity() above
512 
513 }
514 /* END OF FUNCTION force */
515 
516 /************************************************************************/
517 /* */
518 /* FUNCTION output_restart_coordinates */
519 /* */
520 /* INPUTS: */
521 /* coor - Array of vectors containing current positions */
522 /* n - Number of coordinates to output */
523 /* timestep - Timestep for which the coordinates are being written */
524 /* */
525 /* This function writes out the current positions of all the atoms */
526 /* in PDB format to the restart file specified by the user in the */
527 /* configuration file. */
528 /* */
529 /************************************************************************/
530 
531 void Output::output_restart_coordinates(Vector *coor, int n, int timestep)
532 
533 {
534  char comment[128]; // Comment for header of PDB file
535  char timestepstr[20];
536 
537  int baselen = strlen(namdMyNode->simParams->restartFilename);
538  char *restart_name = new char[baselen+26];
539  const char *bsuffix = ".old";
540 
541  strcpy(restart_name, namdMyNode->simParams->restartFilename);
542  if ( namdMyNode->simParams->restartSave ) {
543  sprintf(timestepstr,".%d",timestep);
544  strcat(restart_name, timestepstr);
545  bsuffix = ".BAK";
546  }
547  strcat(restart_name, ".coor");
548 
549  NAMD_backup_file(restart_name,bsuffix);
550 
551  // Check to see if we should generate a binary or PDB file
552  if (!namdMyNode->simParams->binaryRestart)
553  {
554  // Generate a PDB restart file
555  sprintf(comment, "RESTART COORDINATES WRITTEN BY NAMD AT TIMESTEP %d", timestep);
556 
557  namdMyNode->pdbData->set_all_positions(coor);
558  namdMyNode->pdbData->write(restart_name, comment);
559  }
560  else
561  {
562  // Generate a binary restart file
563  write_binary_file(restart_name, n, coor);
564  }
565 
566  delete [] restart_name;
567 
568  if ( namdMyNode->simParams->restartSaveDcd ) {
569  if ( ! output_dcdfile(END_OF_RUN, 0, 0, 0) ) { // close old file
570  const char *old_name = namdMyNode->simParams->dcdFilename;
571  int old_len = strlen(old_name);
572  char *new_name = new char[old_len+26];
573  strcpy(new_name, old_name);
574  if ( old_len >= 4 && ! strcmp(new_name+old_len-4,".dcd") ) {
575  old_len -= 4;
576  new_name[old_len] = 0;
577  }
578  sprintf(timestepstr,".%d",timestep);
579  strcat(new_name, timestepstr);
580  strcat(new_name, ".dcd");
581  iout << "RENAMING COORDINATE DCD FILE " << old_name << " TO " << new_name << "\n" << endi;
582  NAMD_backup_file(new_name,".BAK");
583  while ( rename(old_name, new_name) ) {
584  if ( errno == EINTR || errno == EXDEV ) continue;
585  char err_msg[257];
586  sprintf(err_msg, "Unable to rename DCD file %s to %s", old_name, new_name);
587  NAMD_err(err_msg);
588  }
589  delete [] new_name;
590  }
591  }
592 
593 }
594 /* END OF FUNCTION output_restart_coordinates */
595 
596 /************************************************************************/
597 /* */
598 /* FUNCTION output_restart_velocities */
599 /* */
600 /* INPUTS: */
601 /* vel - Array of vectors containing current velocities */
602 /* timestep - Timestep for which the velocities are being written */
603 /* */
604 /* This function writes out the current velocites of all the atoms */
605 /* in PDB format to the restart file specified by the user in the */
606 /* configuration file. */
607 /* */
608 /************************************************************************/
609 
610 void Output::output_restart_velocities(int timestep, int n, Vector *vel)
611 
612 {
613  char comment[128]; // comment for the header of PDB file
614  char timestepstr[20];
615 
616  int baselen = strlen(namdMyNode->simParams->restartFilename);
617  char *restart_name = new char[baselen+26];
618  const char *bsuffix = ".old";
619 
620  strcpy(restart_name, namdMyNode->simParams->restartFilename);
621  if ( namdMyNode->simParams->restartSave ) {
622  sprintf(timestepstr,".%d",timestep);
623  strcat(restart_name, timestepstr);
624  bsuffix = ".BAK";
625  }
626  strcat(restart_name, ".vel");
627 
628  NAMD_backup_file(restart_name,bsuffix);
629 
630  // Check to see if we should write out a PDB or a binary file
631  if (!namdMyNode->simParams->binaryRestart)
632  {
633  // Write the coordinates to a PDB file. Multiple them by 20
634  // first to make the numbers bigger
635  sprintf(comment, "RESTART VELOCITIES WRITTEN BY NAMD AT TIMESTEP %d", timestep);
636 
637  scale_vels(vel, n, PDBVELFACTOR);
638  namdMyNode->pdbData->set_all_positions(vel);
639  namdMyNode->pdbData->write(restart_name, comment);
640  scale_vels(vel, n, PDBVELINVFACTOR);
641  }
642  else
643  {
644  // Write the velocities to a binary file
645  write_binary_file(restart_name, n, vel);
646  }
647 
648  delete [] restart_name;
649 }
650 /* END OF FUNCTION output_restart_velocities */
651 
652 
653 
654 // This is here so it can access Output.h and Node.h
656 
657  Output *output = Node::Object()->output;
658  if ( ! output ) return;
659 
660  output->output_dcdfile(END_OF_RUN, 0, 0, 0);
661 
662 }
663 
665 
666  Output *output = Node::Object()->output;
667  if ( ! output ) return;
668 
669  output->output_veldcdfile(END_OF_RUN, 0, 0);
670 
671 }
672 
673 void Output::setReplicaDcdIndex(int index) {
674  replicaDcdActive = 1;
675  replicaDcdIndex = index;
676 }
677 
678 void Output::replicaDcdInit(int index, const char *filename) {
679  replicaDcdActive = 1;
680  replicaDcdIndex = index;
681  int msgsize = sizeof(ReplicaDcdInitMsg) + strlen(filename);
682  ReplicaDcdInitMsg *msg = (ReplicaDcdInitMsg *) CmiAlloc(msgsize);
683  msg->srcPart = CmiMyPartition();
684  msg->dcdIndex = replicaDcdIndex;
685  strcpy(msg->data, filename);
686  sendReplicaDcdInit(abs(replicaDcdIndex) % CmiNumPartitions(), msg, msgsize);
687 }
688 
690  replicaDcdFile &f = replicaDcdFiles[msg->dcdIndex];
691  if ( f.fileid ) {
692  iout << "CLOSING REPLICA DCD FILE " << msg->dcdIndex << " " << f.filename.c_str() << "\n" << endi;
693  close_dcd_write(f.fileid);
694  f.fileid = 0;
695  }
696  f.filename = (const char*) msg->data;
697  sendReplicaDcdAck(msg->srcPart, (ReplicaDcdAckMsg*) CmiAlloc(sizeof(ReplicaDcdAckMsg)));
698 }
699 
701  if ( ! replicaDcdFiles.count(msg->dcdIndex) ) {
702  char err_msg[257];
703  sprintf(err_msg, "Unknown replicaDcdFile identifier %d\n", msg->dcdIndex);
704  NAMD_die(err_msg);
705  }
706  replicaDcdFile &f = replicaDcdFiles[msg->dcdIndex];
707 
708  if ( ! f.fileid ) {
709  // Open the DCD file
710  iout << "OPENING REPLICA DCD FILE " << msg->dcdIndex << " " << f.filename.c_str() << "\n" << endi;
711 
712  f.fileid=open_dcd_write(f.filename.c_str());
713 
714  if (f.fileid == DCD_FILEEXISTS) {
715  char err_msg[257];
716  sprintf(err_msg, "DCD file %s already exists!!", f.filename.c_str());
717  NAMD_err(err_msg);
718  } else if (f.fileid < 0) {
719  char err_msg[257];
720  sprintf(err_msg, "Couldn't open DCD file %s", f.filename.c_str());
721  NAMD_err(err_msg);
722  } else if (! f.fileid) {
723  NAMD_bug("Output::recvReplicaDcdData open_dcd_write returned fileid of zero");
724  }
725 
726  // Write out the header
727  int ret_code = write_dcdheader(f.fileid, f.filename.c_str(),
728  msg->numAtoms, msg->NFILE, msg->NPRIV, msg->NSAVC, msg->NSTEP,
729  msg->DELTA, msg->with_unitcell);
730 
731  if (ret_code<0) {
732  NAMD_err("Writing of DCD header failed!!");
733  }
734  }
735 
736  // Write out the values for this timestep
737  iout << "WRITING TO REPLICA DCD FILE " << msg->dcdIndex << " " << f.filename.c_str() << "\n" << endi;
738  float *msgx = (float*) msg->data;
739  float *msgy = msgx + msg->numAtoms;
740  float *msgz = msgy + msg->numAtoms;
741  int ret_code = write_dcdstep(f.fileid, msg->numAtoms, msgx, msgy, msgz,
742  msg->with_unitcell ? msg->unitcell : 0);
743  if (ret_code < 0) NAMD_err("Writing of DCD step failed!!");
744 
745  sendReplicaDcdAck(msg->srcPart, (ReplicaDcdAckMsg*) CmiAlloc(sizeof(ReplicaDcdAckMsg)));
746 }
747 
748 
749 /************************************************************************/
750 /* */
751 /* FUNCTION output_dcdfile */
752 /* */
753 /* INPUTS: */
754 /* timestep - Current timestep */
755 /* n - Number of atoms in simulation */
756 /* coor - Coordinate vectors for all atoms */
757 /* lattice - periodic cell data; NULL if not to be written */
758 /* */
759 /* This function maintains the interface between the Output object */
760 /* and the dcd writing routines contained in dcdlib. */
761 /* */
762 /************************************************************************/
763 
764 #define RAD2DEG 180.0/3.14159265359
765 
766 int Output::output_dcdfile(int timestep, int n, FloatVector *coor,
767  const Lattice *lattice)
768 
769 {
770  static Bool first=TRUE; // Flag indicating first call
771  static int fileid; // File id for the dcd file
772 
773  static float *x, *y, *z; // Arrays to hold x, y, and z arrays
774  static int n_alloc; // allocated size
775 
776  int i; // Loop counter
777  int ret_code; // Return code from DCD calls
778  SimParameters *simParams = namdMyNode->simParams;
779 
780  // If this is the last time we will be writing coordinates,
781  // close the file before exiting
782  if ( timestep == END_OF_RUN ) {
783  for ( std::map<int,replicaDcdFile>::iterator it = replicaDcdFiles.begin();
784  it != replicaDcdFiles.end(); ++it ) {
785  replicaDcdFile &f = it->second;
786  if ( f.fileid ) {
787  iout << "CLOSING REPLICA DCD FILE " << it->first << " " << f.filename.c_str() << "\n" << endi;
788  close_dcd_write(f.fileid);
789  f.fileid = 0;
790  }
791  }
792  int rval = 0;
793  if ( ! first ) {
794  iout << "CLOSING COORDINATE DCD FILE " << simParams->dcdFilename << "\n" << endi;
795  close_dcd_write(fileid);
796  } else {
797  iout << "COORDINATE DCD FILE " << simParams->dcdFilename << " WAS NOT CREATED\n" << endi;
798  rval = -1;
799  }
800  first = 1;
801  fileid = 0;
802  return rval;
803  }
804 
805  if ( replicaDcdActive ) {
806  int msgsize = sizeof(ReplicaDcdDataMsg) + 3*n*sizeof(float);
807  ReplicaDcdDataMsg *msg = (ReplicaDcdDataMsg *) CmiAlloc(msgsize);
808  float *msgx = (float*) msg->data;
809  float *msgy = msgx + n;
810  float *msgz = msgy + n;
811  for (i=0; i<n; i++) { msgx[i] = coor[i].x; }
812  for (i=0; i<n; i++) { msgy[i] = coor[i].y; }
813  for (i=0; i<n; i++) { msgz[i] = coor[i].z; }
814  msg->numAtoms = n;
815  lattice_to_unitcell(lattice,msg->unitcell);
816  msg->with_unitcell = lattice ? 1 : 0;
817  msg->NSAVC = simParams->dcdFrequency;
818  msg->NPRIV = timestep;
819  msg->NSTEP = msg->NPRIV - msg->NSAVC;
820  msg->NFILE = 0;
821  msg->DELTA = simParams->dt/TIMEFACTOR;
822  msg->srcPart = CmiMyPartition();
823  msg->dcdIndex = replicaDcdIndex;
824  sendReplicaDcdData(abs(replicaDcdIndex) % CmiNumPartitions(), msg, msgsize);
825  return 0;
826  }
827 
828  if (first)
829  {
830  // Allocate x, y, and z arrays since the DCD file routines
831  // need them passed as three independant arrays to be
832  // efficient
833  if ( n > n_alloc ) {
834  delete [] x; x = new float[3*n];
835  y = x + n;
836  z = x + 2*n;
837  n_alloc = n;
838  }
839 
840  // Open the DCD file
841  iout << "OPENING COORDINATE DCD FILE\n" << endi;
842 
843  fileid=open_dcd_write(simParams->dcdFilename);
844 
845  if (fileid == DCD_FILEEXISTS)
846  {
847  char err_msg[257];
848 
849  sprintf(err_msg, "DCD file %s already exists!!",
850  simParams->dcdFilename);
851 
852  NAMD_err(err_msg);
853  }
854  else if (fileid < 0)
855  {
856  char err_msg[257];
857 
858  sprintf(err_msg, "Couldn't open DCD file %s",
859  simParams->dcdFilename);
860 
861  NAMD_err(err_msg);
862  }
863 
864  int NSAVC, NFILE, NPRIV, NSTEP;
865  NSAVC = simParams->dcdFrequency;
866  NPRIV = timestep;
867  NSTEP = NPRIV - NSAVC;
868  NFILE = 0;
869 
870  // Write out the header
871  ret_code = write_dcdheader(fileid,
872  simParams->dcdFilename,
873  n, NFILE, NPRIV, NSAVC, NSTEP,
874  simParams->dt/TIMEFACTOR, lattice != NULL);
875 
876 
877  if (ret_code<0)
878  {
879  NAMD_err("Writing of DCD header failed!!");
880  }
881 
882  first = FALSE;
883  }
884 
885  // Copy the coordinates for output
886  for (i=0; i<n; i++)
887  {
888  x[i] = coor[i].x;
889  y[i] = coor[i].y;
890  z[i] = coor[i].z;
891  }
892 
893  // Write out the values for this timestep
894  iout << "WRITING COORDINATES TO DCD FILE " << simParams->dcdFilename << " AT STEP "
895  << timestep << "\n" << endi;
896  fflush(stdout);
897  if (lattice) {
898  double unitcell[6];
899  lattice_to_unitcell(lattice,unitcell);
900  ret_code = write_dcdstep(fileid, n, x, y, z, unitcell);
901  } else {
902  ret_code = write_dcdstep(fileid, n, x, y, z, NULL);
903  }
904  if (ret_code < 0)
905  {
906  NAMD_err("Writing of DCD step failed!!");
907  }
908 
909  return 0;
910 }
911 /* END OF FUNCTION output_dcdfile */
912 
913 /************************************************************************/
914 /* */
915 /* FUNCTION output_final_coordinates */
916 /* */
917 /* INPUTS: */
918 /* coor - Array of vectors containing final coordinates */
919 /* n - Number of coordinates to output */
920 /* timestep - Timestep that coordinates are being written in */
921 /* */
922 /* This function writes out the final coordinates for the */
923 /* simulation in PDB format to the file specified in the config */
924 /* file. */
925 /* */
926 /************************************************************************/
927 
928 void Output::output_final_coordinates(Vector *coor, int n, int timestep)
929 
930 {
931  char output_name[140]; // Output filename
932  char comment[128]; // comment for PDB header
933 
934  // Built the output filename
935  strcpy(output_name, namdMyNode->simParams->outputFilename);
936  strcat(output_name, ".coor");
937 
938  NAMD_backup_file(output_name);
939 
940  // Check to see if we should write out a binary file or a
941  // PDB file
942  if (!namdMyNode->simParams->binaryOutput)
943  {
944  sprintf(comment, "FINAL COORDINATES WRITTEN BY NAMD AT TIMESTEP %d", timestep);
945 
946  namdMyNode->pdbData->set_all_positions(coor);
947  namdMyNode->pdbData->write(output_name, comment);
948  }
949  else
950  {
951  // Write the velocities to a binary file
952  write_binary_file(output_name, n, coor);
953  }
954 }
955 /* END OF FUNCTION output_final_coordinates */
956 
957 /************************************************************************/
958 /* */
959 /* FUNCTION output_final_velocities */
960 /* */
961 /* INPUTS: */
962 /* vel - Array of vectors containing final velocities */
963 /* timestep - Timestep that vleocities are being written in */
964 /* */
965 /* This function writes out the final vleocities for the */
966 /* simulation in PDB format to the file specified in the config */
967 /* file. */
968 /* */
969 /************************************************************************/
970 
971 void Output::output_final_velocities(int timestep, int n, Vector *vel)
972 
973 {
974  char output_name[140]; // Output filename
975  char comment[128]; // Comment for PDB header
976 
977  // Build the output filename
978  strcpy(output_name, namdMyNode->simParams->outputFilename);
979  strcat(output_name, ".vel");
980 
981  NAMD_backup_file(output_name);
982 
983  // Check to see if we should write a PDB or binary file
984  if (!(namdMyNode->simParams->binaryOutput))
985  {
986  // Write the final velocities to a PDB file
987  sprintf(comment, "FINAL VELOCITIES WRITTEN BY NAMD AT TIMESTEP %d", timestep);
988 
989  scale_vels(vel, n, PDBVELFACTOR);
990  namdMyNode->pdbData->set_all_positions(vel);
991  namdMyNode->pdbData->write(output_name, comment);
992  scale_vels(vel, n, PDBVELINVFACTOR);
993  }
994  else
995  {
996  // Write the coordinates to a binary file
997  write_binary_file(output_name, n, vel);
998  }
999 
1000 }
1001 /* END OF FUNCTION output_final_velocities */
1002 
1003 /************************************************************************/
1004 /* */
1005 /* FUNCTION output_veldcdfile */
1006 /* */
1007 /* INPUTS: */
1008 /* timestep - Current timestep */
1009 /* n - Number of atoms in simulation */
1010 /* coor - velocity vectors for all atoms */
1011 /* */
1012 /* This function maintains the interface between the Output object */
1013 /* and the dcd writing routines contained in dcdlib. This fucntion */
1014 /* writes out the velocity vectors in DCD format. */
1015 /* */
1016 /************************************************************************/
1017 
1018 void Output::output_veldcdfile(int timestep, int n, Vector *vel)
1019 
1020 {
1021  static Bool first=TRUE; // Flag indicating first call
1022  static int fileid; // File id for the dcd file
1023  static float *x, *y, *z; // Arrays to hold x, y, and z arrays
1024  static int n_alloc; // allocated size
1025  int i; // Loop counter
1026  int ret_code; // Return code from DCD calls
1028 
1029  // If this is the last time we will be writing coordinates,
1030  // close the file before exiting
1031  if ( timestep == END_OF_RUN ) {
1032  if ( ! first ) {
1033  iout << "CLOSING VELOCITY DCD FILE\n" << endi;
1034  close_dcd_write(fileid);
1035  } else {
1036  iout << "VELOCITY DCD FILE WAS NOT CREATED\n" << endi;
1037  }
1038  first = TRUE;
1039  fileid = 0;
1040  return;
1041  }
1042 
1043  if (first)
1044  {
1045  // Allocate x, y, and z arrays since the DCD file routines
1046  // need them passed as three independant arrays to be
1047  // efficient
1048  if ( n > n_alloc ) {
1049  delete [] x; x = new float[3*n];
1050  y = x + n;
1051  z = x + 2*n;
1052  n_alloc = n;
1053  }
1054 
1055  // Open the DCD file
1056  iout << "OPENING VELOCITY DCD FILE\n" << endi;
1057 
1058  fileid=open_dcd_write(namdMyNode->simParams->velDcdFilename);
1059 
1060  if (fileid == DCD_FILEEXISTS)
1061  {
1062  char err_msg[257];
1063 
1064  sprintf(err_msg, "Velocity DCD file %s already exists!!",
1065  namdMyNode->simParams->velDcdFilename);
1066 
1067  NAMD_err(err_msg);
1068  }
1069  else if (fileid < 0)
1070  {
1071  char err_msg[257];
1072 
1073  sprintf(err_msg, "Couldn't open velocity DCD file %s",
1074  namdMyNode->simParams->velDcdFilename);
1075 
1076  NAMD_err(err_msg);
1077  }
1078 
1079  int NSAVC, NFILE, NPRIV, NSTEP;
1080  NSAVC = simParams->velDcdFrequency;
1081  NPRIV = timestep;
1082  NSTEP = NPRIV - NSAVC;
1083  NFILE = 0;
1084 
1085  // Write out the header
1086  const int with_unitcell = 0;
1087  ret_code = write_dcdheader(fileid,
1088  simParams->velDcdFilename,
1089  n, NFILE, NPRIV, NSAVC, NSTEP,
1090  simParams->dt/TIMEFACTOR, with_unitcell);
1091 
1092 
1093  if (ret_code<0)
1094  {
1095  NAMD_err("Writing of velocity DCD header failed!!");
1096  }
1097 
1098  first = FALSE;
1099  }
1100 
1101  // Copy the coordinates for output
1102  for (i=0; i<n; i++)
1103  {
1104  x[i] = vel[i].x;
1105  y[i] = vel[i].y;
1106  z[i] = vel[i].z;
1107  }
1108 
1109  // Write out the values for this timestep
1110  iout << "WRITING VELOCITIES TO DCD FILE AT STEP "
1111  << timestep << "\n" << endi;
1112  fflush(stdout);
1113  ret_code = write_dcdstep(fileid, n, x, y, z, NULL);
1114 
1115  if (ret_code < 0)
1116  {
1117  NAMD_err("Writing of velocity DCD step failed!!");
1118  }
1119 
1120 }
1121 /* END OF FUNCTION output_veldcdfile */
1122 
1123 /************************************************************************/
1124 /* */
1125 /* FUNCTION output_forces */
1126 /* */
1127 /* INPUTS: */
1128 /* frc - Array of vectors containing final forces */
1129 /* timestep - Timestep that vleocities are being written in */
1130 /* */
1131 /* This function writes out the final vleocities for the */
1132 /* simulation in PDB format to the file specified in the config */
1133 /* file. */
1134 /* */
1135 /************************************************************************/
1136 
1137 void Output::output_forces(int timestep, int n, Vector *frc)
1138 
1139 {
1140  char output_name[140]; // Output filename
1141  char comment[128]; // Comment for PDB header
1142 
1143  // Build the output filename
1144  strcpy(output_name, namdMyNode->simParams->outputFilename);
1145  strcat(output_name, ".force");
1146 
1147  NAMD_backup_file(output_name);
1148 
1149  // Check to see if we should write a PDB or binary file
1150  if (!(namdMyNode->simParams->binaryOutput))
1151  {
1152  // Write the forces to a PDB file
1153  sprintf(comment, "FORCES WRITTEN BY NAMD AT TIMESTEP %d", timestep);
1154 
1155  namdMyNode->pdbData->set_all_positions(frc);
1156  namdMyNode->pdbData->write(output_name, comment);
1157  }
1158  else
1159  {
1160  // Write the coordinates to a binary file
1161  write_binary_file(output_name, n, frc);
1162  }
1163 
1164 }
1165 /* END OF FUNCTION output_forces */
1166 
1167 /************************************************************************/
1168 /* */
1169 /* FUNCTION output_forcedcdfile */
1170 /* */
1171 /* INPUTS: */
1172 /* timestep - Current timestep */
1173 /* n - Number of atoms in simulation */
1174 /* frc - force vectors for all atoms */
1175 /* */
1176 /* This function maintains the interface between the Output object */
1177 /* and the dcd writing routines contained in dcdlib. This fucntion */
1178 /* writes out the force vectors in DCD format. */
1179 /* */
1180 /************************************************************************/
1181 
1182 void Output::output_forcedcdfile(int timestep, int n, Vector *frc)
1183 
1184 {
1185  static Bool first=TRUE; // Flag indicating first call
1186  static int fileid; // File id for the dcd file
1187  static float *x, *y, *z; // Arrays to hold x, y, and z arrays
1188  static int n_alloc; // allocated size
1189  int i; // Loop counter
1190  int ret_code; // Return code from DCD calls
1191  SimParameters *simParams = Node::Object()->simParameters;
1192 
1193  // If this is the last time we will be writing coordinates,
1194  // close the file before exiting
1195  if ( timestep == END_OF_RUN ) {
1196  if ( ! first ) {
1197  iout << "CLOSING FORCE DCD FILE\n" << endi;
1198  close_dcd_write(fileid);
1199  } else {
1200  iout << "FORCE DCD FILE WAS NOT CREATED\n" << endi;
1201  }
1202  return;
1203  }
1204 
1205  if (first)
1206  {
1207  // Allocate x, y, and z arrays since the DCD file routines
1208  // need them passed as three independant arrays to be
1209  // efficient
1210  if ( n > n_alloc ) {
1211  delete [] x; x = new float[3*n];
1212  y = x + n;
1213  z = x + 2*n;
1214  n_alloc = n;
1215  }
1216 
1217  // Open the DCD file
1218  iout << "OPENING FORCE DCD FILE\n" << endi;
1219 
1220  fileid=open_dcd_write(namdMyNode->simParams->forceDcdFilename);
1221 
1222  if (fileid == DCD_FILEEXISTS)
1223  {
1224  char err_msg[257];
1225 
1226  sprintf(err_msg, "Force DCD file %s already exists!!",
1227  namdMyNode->simParams->forceDcdFilename);
1228 
1229  NAMD_err(err_msg);
1230  }
1231  else if (fileid < 0)
1232  {
1233  char err_msg[257];
1234 
1235  sprintf(err_msg, "Couldn't open force DCD file %s",
1236  namdMyNode->simParams->forceDcdFilename);
1237 
1238  NAMD_err(err_msg);
1239  }
1240 
1241  int NSAVC, NFILE, NPRIV, NSTEP;
1242  NSAVC = simParams->forceDcdFrequency;
1243  NPRIV = timestep;
1244  NSTEP = NPRIV - NSAVC;
1245  NFILE = 0;
1246 
1247  // Write out the header
1248  const int with_unitcell = 0;
1249  ret_code = write_dcdheader(fileid,
1250  simParams->forceDcdFilename,
1251  n, NFILE, NPRIV, NSAVC, NSTEP,
1252  simParams->dt/TIMEFACTOR, with_unitcell);
1253 
1254 
1255  if (ret_code<0)
1256  {
1257  NAMD_err("Writing of force DCD header failed!!");
1258  }
1259 
1260  first = FALSE;
1261  }
1262 
1263  // Copy the coordinates for output
1264  for (i=0; i<n; i++)
1265  {
1266  x[i] = frc[i].x;
1267  y[i] = frc[i].y;
1268  z[i] = frc[i].z;
1269  }
1270 
1271  // Write out the values for this timestep
1272  iout << "WRITING FORCES TO DCD FILE AT STEP "
1273  << timestep << "\n" << endi;
1274  fflush(stdout);
1275  ret_code = write_dcdstep(fileid, n, x, y, z, NULL);
1276 
1277  if (ret_code < 0)
1278  {
1279  NAMD_err("Writing of force DCD step failed!!");
1280  }
1281 
1282 }
1283 /* END OF FUNCTION output_forcedcdfile */
1284 
1285 /************************************************************************/
1286 /* */
1287 /* FUNCTION write_binary_file */
1288 /* */
1289 /* INPUTS: */
1290 /* fname - file name to write velocities to */
1291 /* n - Number of atoms in system */
1292 /* vels - Array of vectors */
1293 /* */
1294 /* This function writes out vectors in binary format to */
1295 /* the specified file. */
1296 /* */
1297 /************************************************************************/
1298 
1299 void Output::write_binary_file(char *fname, int n, Vector *vecs)
1300 
1301 {
1302  char errmsg[256];
1303  int fd; // File descriptor
1304  int32 n32 = n;
1305 
1306  fd = NAMD_open(fname);
1307 
1308  sprintf(errmsg, "Error on write to binary file %s", fname);
1309 
1310  // Write out the number of atoms and the vectors
1311  NAMD_write(fd, (char *) &n32, sizeof(int32), errmsg);
1312  NAMD_write(fd, (char *) vecs, sizeof(Vector)*n, errmsg);
1313 
1314  NAMD_close(fd, fname);
1315 }
1316 /* END OF FUNCTION write_binary_file */
1317 
1318 /************************************************************************/
1319 /* */
1320 /* FUNCTION scale_vels */
1321 /* */
1322 /* INPUTS: */
1323 /* v - Array of velocity vectors */
1324 /* n - Number of atoms in system */
1325 /* fact - Scaling factor */
1326 /* */
1327 /* This function scales all the vectors passed in by a constant */
1328 /* factor. This is used before writing out velocity vectors that */
1329 /* need to be resized. */
1330 /* */
1331 /************************************************************************/
1332 
1333 void Output::scale_vels(Vector *v, int n, Real fact)
1334 
1335 {
1336  int i;
1337 
1338  for (i=0; i<n; i++)
1339  {
1340  v[i].x *= fact;
1341  v[i].y *= fact;
1342  v[i].z *= fact;
1343  }
1344 }
1345 /* END OF FUNCTION scale_vels */
1346 
1347 
1348 #ifdef MEM_OPT_VERSION
1349 void ParOutput::velocityMaster(int timestep, int n){
1351  SimParameters *simParams = Node::Object()->simParameters;
1352 
1353  if ( timestep >= 0 ) {
1354 
1355  // Output velocity DCD trajectory
1356  if ( simParams->velDcdFrequency &&
1357  ((timestep % simParams->velDcdFrequency) == 0) )
1358  {
1359  output_veldcdfile_master(timestep, n);
1360  }
1361 
1362  // Output restart file
1363  if ( simParams->restartFrequency &&
1364  ((timestep % simParams->restartFrequency) == 0) )
1365  {
1366  iout << "WRITING VELOCITIES TO RESTART FILE AT STEP "
1367  << timestep << "\n" << endi;
1368  output_restart_velocities_master(timestep, n);
1369  iout << "FINISHED WRITING RESTART VELOCITIES\n" <<endi;
1370  fflush(stdout);
1371  }
1372 
1373  }
1374 
1375  // Output final velocities
1376  if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
1377  {
1378  int realstep = ( timestep == FILE_OUTPUT ?
1379  simParams->firstTimestep : simParams->N );
1380  iout << "WRITING VELOCITIES TO OUTPUT FILE AT STEP "
1381  << realstep << "\n" << endi;
1382  fflush(stdout);
1383  output_final_velocities_master(n);
1384  }
1385 
1386  // Close trajectory files
1387  if (timestep == END_OF_RUN)
1388  {
1389  if (simParams->velDcdFrequency) output_veldcdfile_master(END_OF_RUN,0);
1390  if (simParams->forceDcdFrequency) output_forcedcdfile_master(END_OF_RUN,0);
1391  }
1392 
1393 }
1394 
1395 //output atoms' velocities from id fID to tID.
1396 void ParOutput::velocitySlave(int timestep, int fID, int tID, Vector *vecs){
1397  SimParameters *simParams = Node::Object()->simParameters;
1398 
1399  if ( timestep >= 0 ) {
1400 
1401  // Output velocity DCD trajectory
1402  if ( simParams->velDcdFrequency &&
1403  ((timestep % simParams->velDcdFrequency) == 0) )
1404  {
1405  output_veldcdfile_slave(timestep, fID, tID, vecs);
1406  }
1407 
1408  // Output restart file
1409  if ( simParams->restartFrequency &&
1410  ((timestep % simParams->restartFrequency) == 0) )
1411  {
1412  int64 offset = sizeof(int)+sizeof(Vector)*((int64)fID);
1413  output_restart_velocities_slave(timestep, fID, tID, vecs, offset);
1414  }
1415 
1416  }
1417 
1418  // Output final velocities
1419  if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
1420  {
1421  int64 offset = sizeof(int)+sizeof(Vector)*((int64)fID);
1422  output_final_velocities_slave(fID, tID, vecs, offset);
1423  }
1424 
1425  // Close trajectory files
1426  if (timestep == END_OF_RUN)
1427  {
1428  if (simParams->velDcdFrequency) output_veldcdfile_slave(END_OF_RUN, 0, 0, NULL);
1429  if (simParams->forceDcdFrequency) output_forcedcdfile_slave(END_OF_RUN, 0, 0, NULL);
1430  }
1431 }
1432 
1433 void ParOutput::output_veldcdfile_master(int timestep, int n){
1434  int ret_code; // Return code from DCD calls
1435  SimParameters *simParams = Node::Object()->simParameters;
1436 
1437  // If this is the last time we will be writing coordinates,
1438  // close the file before exiting
1439  if ( timestep == END_OF_RUN ) {
1440  if ( ! veldcdFirst ) {
1441  iout << "CLOSING VELOCITY DCD FILE\n" << endi;
1442  close_dcd_write(veldcdFileID);
1443  } else {
1444  iout << "VELOCITY DCD FILE WAS NOT CREATED\n" << endi;
1445  }
1446  return;
1447  }
1448 
1449  if (veldcdFirst)
1450  {
1451  // Open the DCD file
1452  iout << "OPENING VELOCITY DCD FILE\n" << endi;
1453 
1454 #ifndef OUTPUT_SINGLE_FILE
1455 #error OUTPUT_SINGLE_FILE not defined!
1456 #endif
1457 
1458  #if OUTPUT_SINGLE_FILE
1459  char *veldcdFilename = simParams->velDcdFilename;
1460  #else
1461  char *veldcdFilename = buildFileName(veldcdType);
1462  #endif
1463 
1464  veldcdFileID=open_dcd_write(veldcdFilename);
1465 
1466  if (veldcdFileID == DCD_FILEEXISTS)
1467  {
1468  char err_msg[257];
1469  sprintf(err_msg, "Velocity DCD file %s already exists!",veldcdFilename);
1470  NAMD_err(err_msg);
1471  }
1472  else if (veldcdFileID < 0)
1473  {
1474  char err_msg[257];
1475  sprintf(err_msg, "Couldn't open velocity DCD file %s",veldcdFilename);
1476  NAMD_err(err_msg);
1477  }
1478 
1479  #if !OUTPUT_SINGLE_FILE
1480  // Write out extra fields as MAGIC number etc.
1481  int32 tmpInt = OUTPUT_MAGIC_NUMBER;
1482  float tmpFlt = OUTPUT_FILE_VERSION;
1483  NAMD_write(veldcdFileID, (char *) &tmpInt, sizeof(int32));
1484  NAMD_write(veldcdFileID, (char *) &tmpFlt, sizeof(float));
1485  tmpInt = simParams->numoutputprocs;
1486  NAMD_write(veldcdFileID, (char *) &tmpInt, sizeof(int32));
1487  #endif
1488 
1489  int NSAVC, NFILE, NPRIV, NSTEP;
1490  NSAVC = simParams->velDcdFrequency;
1491  NPRIV = timestep;
1492  NSTEP = NPRIV - NSAVC;
1493  NFILE = 0;
1494 
1495  // Write out the header
1496  const int with_unitcell = 0;
1497  ret_code = write_dcdheader(veldcdFileID,
1498  veldcdFilename,
1499  n, NFILE, NPRIV, NSAVC, NSTEP,
1500  simParams->dt/TIMEFACTOR, with_unitcell);
1501 
1502 
1503  if (ret_code<0)
1504  {
1505  NAMD_err("Writing of velocity DCD header failed!!");
1506  }
1507 
1508  #if !OUTPUT_SINGLE_FILE
1509  //In this case, the file name is dynamically allocated
1510  delete [] veldcdFilename;
1511  #endif
1512 
1513  veldcdFirst = FALSE;
1514  }
1515 
1516  // Write out the values for this timestep
1517  iout << "WRITING VELOCITIES TO DCD FILE AT STEP "
1518  << timestep << "\n" << endi;
1519  fflush(stdout);
1520 
1521  //In the case of writing to multiple files, only the header
1522  //of the dcd file needs to be updated. Note that the format of
1523  //the new dcd file has also changed! -Chao Mei
1524 
1525 #if OUTPUT_SINGLE_FILE
1526  //write X,Y,Z headers
1527  int totalAtoms = namdMyNode->molecule->numAtoms;
1528  write_dcdstep_par_XYZUnits(veldcdFileID, totalAtoms);
1529 #endif
1530 
1531  //update the header
1532  update_dcdstep_par_header(veldcdFileID);
1533 
1534 }
1535 
1536 void ParOutput::output_veldcdfile_slave(int timestep, int fID, int tID, Vector *vecs){
1537  int ret_code; // Return code from DCD calls
1538  SimParameters *simParams = Node::Object()->simParameters;
1539 
1540  // If this is the last time we will be writing coordinates,
1541  // close the file before exiting
1542  if ( timestep == END_OF_RUN ) {
1543  if ( ! veldcdFirst ) {
1544  close_dcd_write(veldcdFileID);
1545  }
1546 #if OUTPUT_SINGLE_FILE
1547  delete [] veldcdX;
1548  delete [] veldcdY;
1549  delete [] veldcdZ;
1550 #endif
1551  return;
1552  }
1553 
1554  int parN = tID-fID+1;
1555 
1556  if (veldcdFirst)
1557  {
1558 
1559  #if OUTPUT_SINGLE_FILE
1560  char *veldcdFilename = namdMyNode->simParams->velDcdFilename;
1561  #else
1562  char *veldcdFilename = buildFileName(veldcdType);
1563  #endif
1564  veldcdFileID=open_dcd_write_par_slave(veldcdFilename);
1565  if(veldcdFileID < 0)
1566  {
1567  char err_msg[257];
1568  sprintf(err_msg, "Couldn't open velocity DCD file %s",veldcdFilename);
1569  NAMD_err(err_msg);
1570  }
1571  #if OUTPUT_SINGLE_FILE
1572  //If outputting to a single file, dcd files conforms to the old format
1573  //as data are organized as 3 seperate arrays of X,Y,Z, while in the new
1574  //format used in outputing multiple files, the data are organized as an
1575  //array of XYZs.
1576  veldcdX = new float[parN];
1577  veldcdY = new float[parN];
1578  veldcdZ = new float[parN];
1579  //seek to beginning of X,Y,Z sections which means skipping header.
1580  //Cell data is not needed because this is velocity trajectory
1581  int skipbytes = get_dcdheader_size();
1582  seek_dcdfile(veldcdFileID, skipbytes, SEEK_SET);
1583  #endif
1584 
1585  #if !OUTPUT_SINGLE_FILE
1586  delete [] veldcdFilename;
1587  // Write out extra fields as MAGIC number etc.
1588  int32 tmpInt = OUTPUT_MAGIC_NUMBER;
1589  float tmpFlt = OUTPUT_FILE_VERSION;
1590  NAMD_write(veldcdFileID, (char *) &tmpInt, sizeof(int32));
1591  NAMD_write(veldcdFileID, (char *) &tmpFlt, sizeof(float));
1592  NAMD_write(veldcdFileID, (char *) &outputID, sizeof(int));
1593  NAMD_write(veldcdFileID, (char *) &fID, sizeof(int));
1594  NAMD_write(veldcdFileID, (char *) &tID, sizeof(int));
1595  #endif
1596 
1597  veldcdFirst = FALSE;
1598  }
1599 
1600 #if OUTPUT_SINGLE_FILE
1601  //The following seek will set the stream position to the
1602  //beginning of the place where a new timestep output should
1603  //be performed.
1604  CmiAssert(sizeof(off_t)==8);
1605  int totalAtoms = namdMyNode->molecule->numAtoms;
1606 
1607  for(int i=0; i<parN; i++){
1608  veldcdX[i] = vecs[i].x;
1609  veldcdY[i] = vecs[i].y;
1610  veldcdZ[i] = vecs[i].z;
1611  }
1612 
1613  write_dcdstep_par_slave(veldcdFileID, fID, tID, totalAtoms, veldcdX, veldcdY, veldcdZ);
1614 
1615  //same with the slave output for coordiantes trajectory file
1616  //but cell data is not needed because this is velocity trajectory
1617  int atomsRemains = (totalAtoms-1)-(tID+1)+1;
1618  off_t offset = ((off_t)atomsRemains)*sizeof(float)+1*sizeof(int);
1619  seek_dcdfile(veldcdFileID, offset, SEEK_CUR);
1620 
1621 #else
1622  //write the timestep
1623  NAMD_write(veldcdFileID, (char *)&timestep, sizeof(int));
1624  //write the values for this timestep
1625  NAMD_write(veldcdFileID, (char *)vecs, sizeof(Vector)*parN);
1626 #endif
1627 }
1628 
1629 void ParOutput::output_restart_velocities_master(int timestep, int n){
1630 #if OUTPUT_SINGLE_FILE
1631  char timestepstr[20];
1632 
1633  int baselen = strlen(namdMyNode->simParams->restartFilename);
1634  char *restart_name = new char[baselen+26];
1635 
1636  strcpy(restart_name, namdMyNode->simParams->restartFilename);
1637  if ( namdMyNode->simParams->restartSave ) {
1638  sprintf(timestepstr,".%d",timestep);
1639  strcat(restart_name, timestepstr);
1640  }
1641  strcat(restart_name, ".vel");
1642 #else
1643  char *restart_name = NULL;
1644  if ( namdMyNode->simParams->restartSave )
1645  restart_name = buildFileName(velType);
1646  else
1647  restart_name = buildFileName(velType,timestep);
1648 #endif
1649 
1650  NAMD_backup_file(restart_name,".old");
1651 
1652  //Always output a binary file
1653  write_binary_file_master(restart_name, n);
1654 
1655  delete [] restart_name;
1656 }
1657 
1658 void ParOutput::output_restart_velocities_slave(int timestep, int fID, int tID, Vector *vecs, int64 offset){
1659 #if OUTPUT_SINGLE_FILE
1660  char timestepstr[20];
1661 
1662  int baselen = strlen(namdMyNode->simParams->restartFilename);
1663  char *restart_name = new char[baselen+26];
1664 
1665  strcpy(restart_name, namdMyNode->simParams->restartFilename);
1666  if ( namdMyNode->simParams->restartSave ) {
1667  sprintf(timestepstr,".%d",timestep);
1668  strcat(restart_name, timestepstr);
1669  }
1670  strcat(restart_name, ".vel");
1671 #else
1672  char *restart_name = NULL;
1673  if ( namdMyNode->simParams->restartSave )
1674  restart_name = buildFileName(velType);
1675  else
1676  restart_name = buildFileName(velType,timestep);
1677 
1678  NAMD_backup_file(restart_name,".old");
1679 #endif
1680 
1681  //Always output a binary file
1682  write_binary_file_slave(restart_name, fID, tID, vecs, offset);
1683 
1684  delete [] restart_name;
1685 }
1686 
1687 void ParOutput::output_final_velocities_master(int n){
1688 #if OUTPUT_SINGLE_FILE
1689  char *output_name = new char[strlen(namdMyNode->simParams->outputFilename)+8];
1690  // Build the output filename
1691  strcpy(output_name, namdMyNode->simParams->outputFilename);
1692  strcat(output_name, ".vel");
1693 #else
1694  char *output_name = buildFileName(velType);
1695 #endif
1696 
1697  NAMD_backup_file(output_name);
1698 
1699  //Write the velocities to a binary file
1700  write_binary_file_master(output_name, n);
1701 }
1702 
1703 void ParOutput::output_final_velocities_slave(int fID, int tID, Vector *vecs, int64 offset){
1704 #if OUTPUT_SINGLE_FILE
1705  char *output_name = new char[strlen(namdMyNode->simParams->outputFilename)+8];
1706  // Build the output filename
1707  strcpy(output_name, namdMyNode->simParams->outputFilename);
1708  strcat(output_name, ".vel");
1709 #else
1710  char *output_name = buildFileName(velType);
1711  NAMD_backup_file(output_name);
1712 #endif
1713 
1714  //Write the velocities to a binary file
1715  write_binary_file_slave(output_name, fID, tID, vecs, offset);
1716 
1717  delete [] output_name;
1718 }
1719 
1720 void ParOutput::write_binary_file_master(char *fname, int n){
1721  char errmsg[256];
1722  int fd; // File descriptor
1723  int32 n32 = n;
1724 
1725  fd = NAMD_open(fname);
1726 
1727  sprintf(errmsg, "Error on write to binary file %s", fname);
1728 
1729  #if !OUTPUT_SINGLE_FILE
1730  // Write out extra fields as MAGIC number etc.
1731  int32 tmpInt = OUTPUT_MAGIC_NUMBER;
1732  float tmpFlt = OUTPUT_FILE_VERSION;
1733  NAMD_write(fd, (char *) &tmpInt, sizeof(int32), errmsg);
1734  NAMD_write(fd, (char *) &tmpFlt, sizeof(float), errmsg);
1735  tmpInt = namdMyNode->simParams->numoutputprocs;
1736  NAMD_write(fd, (char *) &tmpInt, sizeof(int32), errmsg);
1737  #endif
1738 
1739  // Write out the number of atoms and the vectors
1740  NAMD_write(fd, (char *) &n32, sizeof(int32), errmsg);
1741 
1742  NAMD_close(fd, fname);
1743 }
1744 
1745 void ParOutput::write_binary_file_slave(char *fname, int fID, int tID, Vector *vecs, int64 offset){
1746  char errmsg[256];
1747 
1748 #if OUTPUT_SINGLE_FILE
1749  //the mode has to be "r+" because the file already exists
1750  FILE *ofp = fopen(fname, "rb+");
1751  if ( ! ofp ) {
1752  sprintf(errmsg, "Error on opening binary file %s", fname);
1753  NAMD_err(errmsg);
1754  }
1755 
1756  //if the output is a single file, then the file position needs to be set correctly
1757 #ifdef WIN32
1758  if ( _fseeki64(ofp, offset, SEEK_SET) )
1759 #else
1760  if ( fseeko(ofp, offset, SEEK_SET) )
1761 #endif
1762  {
1763  sprintf(errmsg, "Error on seeking binary file %s", fname);
1764  NAMD_err(errmsg);
1765  }
1766 #else
1767  //the mode has to be "w+" because the file doesn't exist yet
1768  FILE *ofp = fopen(fname, "wb+");
1769  if ( ! ofp ) {
1770  sprintf(errmsg, "Error on opening binary file %s", fname);
1771  NAMD_err(errmsg);
1772  }
1773 
1774  // Write out extra fields as MAGIC number etc.
1775  int32 tmpInt = OUTPUT_MAGIC_NUMBER;
1776  float tmpFlt = OUTPUT_FILE_VERSION;
1777  fwrite(&tmpInt, sizeof(int32), 1, ofp);
1778  fwrite(&tmpFlt, sizeof(float), 1, ofp);
1779  fwrite(&outputID, sizeof(int), 1, ofp);
1780  fwrite(&fID, sizeof(int), 1, ofp);
1781  fwrite(&tID, sizeof(int), 1, ofp);
1782 #endif
1783 
1784  int parN = tID-fID+1;
1785  if ( fwrite(vecs, sizeof(Vector), parN, ofp) != parN ) {
1786  sprintf(errmsg, "Error on writing to binary file %s", fname);
1787  NAMD_err(errmsg);
1788  }
1789 
1790  if ( fclose(ofp) ) {
1791  sprintf(errmsg, "Error on closing binary file %s", fname);
1792  NAMD_err(errmsg);
1793  }
1794 }
1796 
1797 
1799 void ParOutput::forceMaster(int timestep, int n){
1800  SimParameters *simParams = Node::Object()->simParameters;
1801 
1802  if ( timestep >= 0 ) {
1803 
1804  // Output force DCD trajectory
1805  if ( simParams->forceDcdFrequency &&
1806  ((timestep % simParams->forceDcdFrequency) == 0) )
1807  {
1808  output_forcedcdfile_master(timestep, n);
1809  }
1810 
1811  }
1812 
1813  // Output forces
1814  if (timestep == FORCE_OUTPUT)
1815  {
1816  int realstep = simParams->firstTimestep;
1817  iout << "WRITING FORCES TO OUTPUT FILE AT STEP "
1818  << realstep << "\n" << endi;
1819  fflush(stdout);
1820  output_forces_master(n);
1821  }
1822 
1823  // Close trajectory files in velocityMaster above
1824 }
1825 
1826 //output atoms' forces from id fID to tID.
1827 void ParOutput::forceSlave(int timestep, int fID, int tID, Vector *vecs){
1828  SimParameters *simParams = Node::Object()->simParameters;
1829 
1830  if ( timestep >= 0 ) {
1831 
1832  // Output force DCD trajectory
1833  if ( simParams->forceDcdFrequency &&
1834  ((timestep % simParams->forceDcdFrequency) == 0) )
1835  {
1836  output_forcedcdfile_slave(timestep, fID, tID, vecs);
1837  }
1838 
1839  }
1840 
1841  // Output forces
1842  if (timestep == FORCE_OUTPUT)
1843  {
1844  int64 offset = sizeof(int)+sizeof(Vector)*((int64)fID);
1845  output_forces_slave(fID, tID, vecs, offset);
1846  }
1847 
1848  // Close trajectory files in velocitySlave above
1849 }
1850 
1851 void ParOutput::output_forcedcdfile_master(int timestep, int n){
1852  int ret_code; // Return code from DCD calls
1853  SimParameters *simParams = Node::Object()->simParameters;
1854 
1855  // If this is the last time we will be writing coordinates,
1856  // close the file before exiting
1857  if ( timestep == END_OF_RUN ) {
1858  if ( ! forcedcdFirst ) {
1859  iout << "CLOSING FORCE DCD FILE\n" << endi;
1860  close_dcd_write(forcedcdFileID);
1861  } else {
1862  iout << "FORCE DCD FILE WAS NOT CREATED\n" << endi;
1863  }
1864  return;
1865  }
1866 
1867  if (forcedcdFirst)
1868  {
1869  // Open the DCD file
1870  iout << "OPENING FORCE DCD FILE\n" << endi;
1871 
1872  #if OUTPUT_SINGLE_FILE
1873  char *forcedcdFilename = simParams->forceDcdFilename;
1874  #else
1875  char *forcedcdFilename = buildFileName(forcedcdType);
1876  #endif
1877 
1878  forcedcdFileID=open_dcd_write(forcedcdFilename);
1879 
1880  if (forcedcdFileID == DCD_FILEEXISTS)
1881  {
1882  char err_msg[257];
1883  sprintf(err_msg, "Force DCD file %s already exists!",forcedcdFilename);
1884  NAMD_err(err_msg);
1885  }
1886  else if (forcedcdFileID < 0)
1887  {
1888  char err_msg[257];
1889  sprintf(err_msg, "Couldn't open force DCD file %s",forcedcdFilename);
1890  NAMD_err(err_msg);
1891  }
1892 
1893  #if !OUTPUT_SINGLE_FILE
1894  // Write out extra fields as MAGIC number etc.
1895  int32 tmpInt = OUTPUT_MAGIC_NUMBER;
1896  float tmpFlt = OUTPUT_FILE_VERSION;
1897  NAMD_write(forcedcdFileID, (char *) &tmpInt, sizeof(int32));
1898  NAMD_write(forcedcdFileID, (char *) &tmpFlt, sizeof(float));
1899  tmpInt = simParams->numoutputprocs;
1900  NAMD_write(forcedcdFileID, (char *) &tmpInt, sizeof(int32));
1901  #endif
1902 
1903  int NSAVC, NFILE, NPRIV, NSTEP;
1904  NSAVC = simParams->forceDcdFrequency;
1905  NPRIV = timestep;
1906  NSTEP = NPRIV - NSAVC;
1907  NFILE = 0;
1908 
1909  // Write out the header
1910  const int with_unitcell = 0;
1911  ret_code = write_dcdheader(forcedcdFileID,
1912  forcedcdFilename,
1913  n, NFILE, NPRIV, NSAVC, NSTEP,
1914  simParams->dt/TIMEFACTOR, with_unitcell);
1915 
1916 
1917  if (ret_code<0)
1918  {
1919  NAMD_err("Writing of force DCD header failed!!");
1920  }
1921 
1922  #if !OUTPUT_SINGLE_FILE
1923  //In this case, the file name is dynamically allocated
1924  delete [] forcedcdFilename;
1925  #endif
1926 
1927  forcedcdFirst = FALSE;
1928  }
1929 
1930  // Write out the values for this timestep
1931  iout << "WRITING FORCES TO DCD FILE AT STEP "
1932  << timestep << "\n" << endi;
1933  fflush(stdout);
1934 
1935  //In the case of writing to multiple files, only the header
1936  //of the dcd file needs to be updated. Note that the format of
1937  //the new dcd file has also changed! -Chao Mei
1938 
1939 #if OUTPUT_SINGLE_FILE
1940  //write X,Y,Z headers
1941  int totalAtoms = namdMyNode->molecule->numAtoms;
1942  write_dcdstep_par_XYZUnits(forcedcdFileID, totalAtoms);
1943 #endif
1944 
1945  //update the header
1946  update_dcdstep_par_header(forcedcdFileID);
1947 
1948 }
1949 
1950 void ParOutput::output_forcedcdfile_slave(int timestep, int fID, int tID, Vector *vecs){
1951  int ret_code; // Return code from DCD calls
1952  SimParameters *simParams = Node::Object()->simParameters;
1953 
1954  // If this is the last time we will be writing coordinates,
1955  // close the file before exiting
1956  if ( timestep == END_OF_RUN ) {
1957  if ( ! forcedcdFirst ) {
1958  close_dcd_write(forcedcdFileID);
1959  }
1960 #if OUTPUT_SINGLE_FILE
1961  delete [] forcedcdX;
1962  delete [] forcedcdY;
1963  delete [] forcedcdZ;
1964 #endif
1965  return;
1966  }
1967 
1968  int parN = tID-fID+1;
1969 
1970  if (forcedcdFirst)
1971  {
1972 
1973  #if OUTPUT_SINGLE_FILE
1974  char *forcedcdFilename = namdMyNode->simParams->forceDcdFilename;
1975  #else
1976  char *forcedcdFilename = buildFileName(forcedcdType);
1977  #endif
1978  forcedcdFileID=open_dcd_write_par_slave(forcedcdFilename);
1979  if(forcedcdFileID < 0)
1980  {
1981  char err_msg[257];
1982  sprintf(err_msg, "Couldn't open force DCD file %s",forcedcdFilename);
1983  NAMD_err(err_msg);
1984  }
1985  #if OUTPUT_SINGLE_FILE
1986  //If outputting to a single file, dcd files conforms to the old format
1987  //as data are organized as 3 seperate arrays of X,Y,Z, while in the new
1988  //format used in outputing multiple files, the data are organized as an
1989  //array of XYZs.
1990  forcedcdX = new float[parN];
1991  forcedcdY = new float[parN];
1992  forcedcdZ = new float[parN];
1993  //seek to beginning of X,Y,Z sections which means skipping header.
1994  //Cell data is not needed because this is force trajectory
1995  int skipbytes = get_dcdheader_size();
1996  seek_dcdfile(forcedcdFileID, skipbytes, SEEK_SET);
1997  #endif
1998 
1999  #if !OUTPUT_SINGLE_FILE
2000  delete [] forcedcdFilename;
2001  // Write out extra fields as MAGIC number etc.
2002  int32 tmpInt = OUTPUT_MAGIC_NUMBER;
2003  float tmpFlt = OUTPUT_FILE_VERSION;
2004  NAMD_write(forcedcdFileID, (char *) &tmpInt, sizeof(int32));
2005  NAMD_write(forcedcdFileID, (char *) &tmpFlt, sizeof(float));
2006  NAMD_write(forcedcdFileID, (char *) &outputID, sizeof(int));
2007  NAMD_write(forcedcdFileID, (char *) &fID, sizeof(int));
2008  NAMD_write(forcedcdFileID, (char *) &tID, sizeof(int));
2009  #endif
2010 
2011  forcedcdFirst = FALSE;
2012  }
2013 
2014 #if OUTPUT_SINGLE_FILE
2015  //The following seek will set the stream position to the
2016  //beginning of the place where a new timestep output should
2017  //be performed.
2018  CmiAssert(sizeof(off_t)==8);
2019  int totalAtoms = namdMyNode->molecule->numAtoms;
2020 
2021  for(int i=0; i<parN; i++){
2022  forcedcdX[i] = vecs[i].x;
2023  forcedcdY[i] = vecs[i].y;
2024  forcedcdZ[i] = vecs[i].z;
2025  }
2026 
2027  write_dcdstep_par_slave(forcedcdFileID, fID, tID, totalAtoms, forcedcdX, forcedcdY, forcedcdZ);
2028  //same with the slave output for coordiantes trajectory file
2029  //but cell data is not needed because this is force trajectory
2030  int atomsRemains = (totalAtoms-1)-(tID+1)+1;
2031  off_t offset = ((off_t)atomsRemains)*sizeof(float)+1*sizeof(int);
2032  seek_dcdfile(forcedcdFileID, offset, SEEK_CUR);
2033 #else
2034  //write the timestep
2035  NAMD_write(forcedcdFileID, (char *)&timestep, sizeof(int));
2036  //write the values for this timestep
2037  NAMD_write(forcedcdFileID, (char *)vecs, sizeof(Vector)*parN);
2038 #endif
2039 }
2040 
2041 void ParOutput::output_forces_master(int n){
2042 #if OUTPUT_SINGLE_FILE
2043  char *output_name = new char[strlen(namdMyNode->simParams->outputFilename)+8];
2044  // Build the output filename
2045  strcpy(output_name, namdMyNode->simParams->outputFilename);
2046  strcat(output_name, ".force");
2047 #else
2048  char *output_name = buildFileName(forceType);
2049 #endif
2050 
2051  NAMD_backup_file(output_name);
2052 
2053  //Write the force to a binary file
2054  write_binary_file_master(output_name, n);
2055 }
2056 
2057 void ParOutput::output_forces_slave(int fID, int tID, Vector *vecs, int64 offset){
2058 #if OUTPUT_SINGLE_FILE
2059  char *output_name = new char[strlen(namdMyNode->simParams->outputFilename)+8];
2060  // Build the output filename
2061  strcpy(output_name, namdMyNode->simParams->outputFilename);
2062  strcat(output_name, ".force");
2063 #else
2064  char *output_name = buildFileName(forceType);
2065  NAMD_backup_file(output_name);
2066 #endif
2067 
2068  //Write the forces to a binary file
2069  write_binary_file_slave(output_name, fID, tID, vecs, offset);
2070 
2071  delete [] output_name;
2072 }
2074 
2075 
2077 void ParOutput::coordinateMaster(int timestep, int n, Lattice &lat){
2078  SimParameters *simParams = Node::Object()->simParameters;
2079 
2080  if ( timestep >= 0 ) {
2081  // Output a DCD trajectory
2082  if ( simParams->dcdFrequency &&
2083  ((timestep % simParams->dcdFrequency) == 0) )
2084  {
2085  output_dcdfile_master(timestep, n,
2086  simParams->dcdUnitCell ? &lat : NULL);
2087  }
2088 
2089  // Output a restart file
2090  if ( simParams->restartFrequency &&
2091  ((timestep % simParams->restartFrequency) == 0) )
2092  {
2093  iout << "WRITING COORDINATES TO RESTART FILE AT STEP "
2094  << timestep << "\n" << endi;
2095  output_restart_coordinates_master(timestep, n);
2096  iout << "FINISHED WRITING RESTART COORDINATES\n" <<endi;
2097  fflush(stdout);
2098  }
2099 
2100 /* Interactive MD is not supported in Parallel IO
2101  // Interactive MD
2102  if ( simParams->IMDon &&
2103  ( ((timestep % simParams->IMDfreq) == 0) ||
2104  (timestep == simParams->firstTimestep) ) )
2105  {
2106  IMDOutput *imd = Node::Object()->imd;
2107  wrap_coor(fcoor,lattice,&fcoor_wrapped);
2108  if (imd != NULL) imd->gather_coordinates(timestep, n, fcoor);
2109  }
2110 */
2111  }
2112 
2113 /* EVAL_MEASURE of a timestep is not supported in Parallel IO
2114  if (timestep == EVAL_MEASURE)
2115  {
2116  #ifdef NAMD_TCL
2117  wrap_coor(coor,lattice,&coor_wrapped);
2118  Node::Object()->getScript()->measure(coor);
2119  #endif
2120  }
2121 */
2122  // Output final coordinates
2123  if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
2124  {
2125  int realstep = ( timestep == FILE_OUTPUT ?
2126  simParams->firstTimestep : simParams->N );
2127  iout << "WRITING COORDINATES TO OUTPUT FILE AT STEP "
2128  << realstep << "\n" << endi;
2129  fflush(stdout);
2130  output_final_coordinates_master(n);
2131  }
2132 
2133  // Close trajectory files
2134  if (timestep == END_OF_RUN)
2135  {
2136  if (simParams->dcdFrequency) output_dcdfile_master(END_OF_RUN,0,NULL);
2137  }
2138 }
2139 
2140 void ParOutput::coordinateSlave(int timestep, int fID, int tID, Vector *vecs, FloatVector *fvecs){
2141  SimParameters *simParams = Node::Object()->simParameters;
2142 
2143  if ( timestep >= 0 ) {
2144  // Output a DCD trajectory
2145  if ( simParams->dcdFrequency &&
2146  ((timestep % simParams->dcdFrequency) == 0) )
2147  {
2148  output_dcdfile_slave(timestep, fID, tID, fvecs);
2149  }
2150 
2151  // Output a restart file
2152  if ( simParams->restartFrequency &&
2153  ((timestep % simParams->restartFrequency) == 0) )
2154  {
2155  int64 offset = sizeof(int)+sizeof(Vector)*((int64)fID);
2156  output_restart_coordinates_slave(timestep, fID, tID, vecs, offset);
2157  }
2158 
2159 /* Interactive MD is not supported in Parallel IO
2160  // Interactive MD
2161  if ( simParams->IMDon &&
2162  ( ((timestep % simParams->IMDfreq) == 0) ||
2163  (timestep == simParams->firstTimestep) ) )
2164  {
2165  IMDOutput *imd = Node::Object()->imd;
2166  wrap_coor(fcoor,lattice,&fcoor_wrapped);
2167  if (imd != NULL) imd->gather_coordinates(timestep, n, fcoor);
2168  }
2169 */
2170  }
2171 
2172 /* EVAL_MEASURE of a timestep is not supported in Parallel IO
2173  if (timestep == EVAL_MEASURE)
2174  {
2175  #ifdef NAMD_TCL
2176  wrap_coor(coor,lattice,&coor_wrapped);
2177  Node::Object()->getScript()->measure(coor);
2178  #endif
2179  }
2180 */
2181  // Output final coordinates
2182  if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
2183  {
2184  int64 offset = sizeof(int)+sizeof(Vector)*((int64)fID);
2185  output_final_coordinates_slave(fID, tID, vecs, offset);
2186  }
2187 
2188  // Close trajectory files
2189  if (timestep == END_OF_RUN)
2190  {
2191  if (simParams->dcdFrequency) output_dcdfile_slave(END_OF_RUN,0,0,NULL);
2192  }
2193 }
2194 
2195 void ParOutput::output_dcdfile_master(int timestep, int n, const Lattice *lattice){
2196  int ret_code; // Return code from DCD calls
2197  SimParameters *simParams = namdMyNode->simParams;
2198 
2199  // If this is the last time we will be writing coordinates,
2200  // close the file before exiting
2201  if ( timestep == END_OF_RUN ) {
2202  if ( ! dcdFirst ) {
2203  iout << "CLOSING COORDINATE DCD FILE\n" << endi;
2204  close_dcd_write(dcdFileID);
2205  } else {
2206  iout << "COORDINATE DCD FILE WAS NOT CREATED\n" << endi;
2207  }
2208  return;
2209  }
2210 
2211  if (dcdFirst)
2212  {
2213  // Open the DCD file
2214  iout << "OPENING COORDINATE DCD FILE\n" << endi;
2215 
2216  #if OUTPUT_SINGLE_FILE
2217  char *dcdFilename = simParams->dcdFilename;
2218  #else
2219  char *dcdFilename = buildFileName(dcdType);
2220  #endif
2221 
2222 
2223  dcdFileID=open_dcd_write(dcdFilename);
2224 
2225  if (dcdFileID == DCD_FILEEXISTS)
2226  {
2227  char err_msg[257];
2228  sprintf(err_msg, "DCD file %s already exists!!",dcdFilename);
2229  NAMD_err(err_msg);
2230  }
2231  else if (dcdFileID < 0)
2232  {
2233  char err_msg[257];
2234  sprintf(err_msg, "Couldn't open DCD file %s",dcdFilename);
2235  NAMD_err(err_msg);
2236  }
2237 
2238  #if !OUTPUT_SINGLE_FILE
2239  // Write out extra fields as MAGIC number etc.
2240  int32 tmpInt = OUTPUT_MAGIC_NUMBER;
2241  float tmpFlt = OUTPUT_FILE_VERSION;
2242  NAMD_write(dcdFileID, (char *) &tmpInt, sizeof(int32));
2243  NAMD_write(dcdFileID, (char *) &tmpFlt, sizeof(float));
2244  tmpInt = simParams->numoutputprocs;
2245  NAMD_write(dcdFileID, (char *) &tmpInt, sizeof(int32));
2246  #endif
2247 
2248  int NSAVC, NFILE, NPRIV, NSTEP;
2249  NSAVC = simParams->dcdFrequency;
2250  NPRIV = timestep;
2251  NSTEP = NPRIV - NSAVC;
2252  NFILE = 0;
2253 
2254  // Write out the header
2255  ret_code = write_dcdheader(dcdFileID,
2256  dcdFilename,
2257  n, NFILE, NPRIV, NSAVC, NSTEP,
2258  simParams->dt/TIMEFACTOR, lattice != NULL);
2259 
2260 
2261  if (ret_code<0)
2262  {
2263  NAMD_err("Writing of DCD header failed!!");
2264  }
2265 
2266  #if !OUTPUT_SINGLE_FILE
2267  //dcdFilename needs to be freed as it is dynamically allocated
2268  delete [] dcdFilename;
2269  #endif
2270 
2271  dcdFirst = FALSE;
2272  }
2273 
2274  // Write out the values for this timestep
2275  iout << "WRITING COORDINATES TO DCD FILE AT STEP "
2276  << timestep << "\n" << endi;
2277  fflush(stdout);
2278 
2279  //In the case of writing to multiple files, the header of the
2280  //dcd file needs to be updated. In addition, the lattice data
2281  //needs to be written if necessary. Note that the format of
2282  //the new dcd file has also changed! -Chao Mei
2283 
2284  // Write out the Cell data
2285  if (lattice) {
2286  double unitcell[6];
2287  lattice_to_unitcell(lattice,unitcell);
2288  write_dcdstep_par_cell(dcdFileID, unitcell);
2289  }
2290 
2291 #if OUTPUT_SINGLE_FILE
2292  //write X,Y,Z headers
2293  int totalAtoms = namdMyNode->molecule->numAtoms;
2294  write_dcdstep_par_XYZUnits(dcdFileID, totalAtoms);
2295 #endif
2296 
2297  //update the header
2298  update_dcdstep_par_header(dcdFileID);
2299 }
2300 void ParOutput::output_dcdfile_slave(int timestep, int fID, int tID, FloatVector *fvecs){
2301  int ret_code; // Return code from DCD calls
2302  SimParameters *simParams = Node::Object()->simParameters;
2303 
2304  // If this is the last time we will be writing coordinates,
2305  // close the file before exiting
2306  if ( timestep == END_OF_RUN ) {
2307  if ( ! dcdFirst ) {
2308  close_dcd_write(dcdFileID);
2309  }
2310 #if OUTPUT_SINGLE_FILE
2311  delete [] dcdX;
2312  delete [] dcdY;
2313  delete [] dcdZ;
2314 #endif
2315  return;
2316  }
2317 
2318  int parN = tID-fID+1;
2319 
2320  if (dcdFirst)
2321  {
2322 
2323  #if OUTPUT_SINGLE_FILE
2324  char *dcdFilename = simParams->dcdFilename;
2325  #else
2326  char *dcdFilename = buildFileName(dcdType);
2327  #endif
2328  dcdFileID=open_dcd_write_par_slave(dcdFilename);
2329  if(dcdFileID < 0)
2330  {
2331  char err_msg[257];
2332  sprintf(err_msg, "Couldn't open DCD file %s", dcdFilename);
2333  NAMD_err(err_msg);
2334  }
2335 
2336  #if OUTPUT_SINGLE_FILE
2337  dcdX = new float[parN];
2338  dcdY = new float[parN];
2339  dcdZ = new float[parN];
2340  //seek to beginning of X,Y,Z sections which means skipping header
2341  //skip the cell data if necessary
2342  int skipbytes = get_dcdheader_size();
2343  if(simParams->dcdUnitCell) {
2344  skipbytes += sizeof(int)*2 + 6*sizeof(double);
2345  }
2346  seek_dcdfile(dcdFileID, skipbytes, SEEK_SET);
2347  #endif
2348 
2349  #if !OUTPUT_SINGLE_FILE
2350  delete [] dcdFilename;
2351 
2352  // Write out extra fields as MAGIC number etc.
2353  int32 tmpInt = OUTPUT_MAGIC_NUMBER;
2354  float tmpFlt = OUTPUT_FILE_VERSION;
2355  NAMD_write(dcdFileID, (char *) &tmpInt, sizeof(int32));
2356  NAMD_write(dcdFileID, (char *) &tmpFlt, sizeof(float));
2357  NAMD_write(dcdFileID, (char *) &outputID, sizeof(int));
2358  NAMD_write(dcdFileID, (char *) &fID, sizeof(int));
2359  NAMD_write(dcdFileID, (char *) &tID, sizeof(int));
2360  #endif
2361  dcdFirst = FALSE;
2362  }
2363 
2364 #if OUTPUT_SINGLE_FILE
2365  //The following seek will set the stream position to the
2366  //beginning of the place where a new timestep output should
2367  //be performed.
2368  CmiAssert(sizeof(off_t)==8);
2369  int totalAtoms = namdMyNode->molecule->numAtoms;
2370 
2371  for(int i=0; i<parN; i++){
2372  dcdX[i] = fvecs[i].x;
2373  dcdY[i] = fvecs[i].y;
2374  dcdZ[i] = fvecs[i].z;
2375  }
2376 
2377  write_dcdstep_par_slave(dcdFileID, fID, tID, totalAtoms, dcdX, dcdY, dcdZ);
2378 
2379  //1. Always foward to the beginning position of X,Y,Z sections in the
2380  //next timeframe.
2381  //2. SHOULD AVOID USING SEEK_END: although the file size is updated on the
2382  //master proc, slave procs should rely on this update by seeking
2383  //from SEEK_END because such info may not be updated in a timely manner
2384  //when this slave proc needs it.
2385 
2386  //We know the current position of file after slave writing is at the
2387  //end of Z output for atom "tID" (tID is the atom id indexed from 0)
2388  //(totalAtoms-1) is the last atom id, (tID+1) is the next atom id
2389  int atomsRemains = (totalAtoms-1)-(tID+1)+1;
2390  off_t offset = ((off_t)atomsRemains)*sizeof(float)+1*sizeof(int);
2391  //then skip the cell data if necessary
2392  if(simParams->dcdUnitCell) {
2393  offset += sizeof(int)*2 + 6*sizeof(double);
2394  }
2395  seek_dcdfile(dcdFileID, offset, SEEK_CUR);
2396 #else
2397  //write the timestep
2398  NAMD_write(dcdFileID, (char *)&timestep, sizeof(int));
2399  //write the values for this timestep
2400  NAMD_write(dcdFileID, (char *)fvecs, sizeof(FloatVector)*parN);
2401 #endif
2402 }
2403 
2404 void ParOutput::output_restart_coordinates_master(int timestep, int n){
2405 #if OUTPUT_SINGLE_FILE
2406  char timestepstr[20];
2407 
2408  int baselen = strlen(namdMyNode->simParams->restartFilename);
2409  char *restart_name = new char[baselen+26];
2410 
2411  strcpy(restart_name, namdMyNode->simParams->restartFilename);
2412  if ( namdMyNode->simParams->restartSave ) {
2413  sprintf(timestepstr,".%d",timestep);
2414  strcat(restart_name, timestepstr);
2415  }
2416  strcat(restart_name, ".coor");
2417 #else
2418  char *restart_name = NULL;
2419  if ( namdMyNode->simParams->restartSave )
2420  restart_name = buildFileName(coorType);
2421  else
2422  restart_name = buildFileName(coorType,timestep);
2423 #endif
2424 
2425  NAMD_backup_file(restart_name,".old");
2426 
2427  // Generate a binary restart file
2428  write_binary_file_master(restart_name, n);
2429 
2430  delete [] restart_name;
2431 }
2432 void ParOutput::output_restart_coordinates_slave(int timestep, int fID, int tID, Vector *vecs, int64 offset){
2433 #if OUTPUT_SINGLE_FILE
2434  char timestepstr[20];
2435 
2436  int baselen = strlen(namdMyNode->simParams->restartFilename);
2437  char *restart_name = new char[baselen+26];
2438 
2439  strcpy(restart_name, namdMyNode->simParams->restartFilename);
2440  if ( namdMyNode->simParams->restartSave ) {
2441  sprintf(timestepstr,".%d",timestep);
2442  strcat(restart_name, timestepstr);
2443  }
2444  strcat(restart_name, ".coor");
2445 #else
2446  char *restart_name = NULL;
2447  if ( namdMyNode->simParams->restartSave )
2448  restart_name = buildFileName(coorType);
2449  else
2450  restart_name = buildFileName(coorType,timestep);
2451 
2452  NAMD_backup_file(restart_name,".old");
2453 #endif
2454 
2455  // Generate a binary restart file
2456  write_binary_file_slave(restart_name, fID, tID, vecs, offset);
2457 
2458  delete [] restart_name;
2459 }
2460 
2461 void ParOutput::output_final_coordinates_master(int n){
2462 #if OUTPUT_SINGLE_FILE
2463  char *output_name = new char[strlen(namdMyNode->simParams->outputFilename)+8];
2464 
2465  // Built the output filename
2466  strcpy(output_name, namdMyNode->simParams->outputFilename);
2467  strcat(output_name, ".coor");
2468 #else
2469  char *output_name = buildFileName(coorType);
2470 #endif
2471 
2472  NAMD_backup_file(output_name);
2473 
2474  // Write the coordinates to a binary file
2475  write_binary_file_master(output_name, n);
2476 
2477  delete [] output_name;
2478 }
2479 void ParOutput::output_final_coordinates_slave(int fID, int tID, Vector *vecs, int64 offset){
2480 #if OUTPUT_SINGLE_FILE
2481  char *output_name = new char[strlen(namdMyNode->simParams->outputFilename)+8];
2482 
2483  // Built the output filename
2484  strcpy(output_name, namdMyNode->simParams->outputFilename);
2485  strcat(output_name, ".coor");
2486 #else
2487  char *output_name = buildFileName(coorType);
2488  NAMD_backup_file(output_name);
2489 #endif
2490 
2491  // Write the coordinates to a binary file
2492  write_binary_file_slave(output_name, fID, tID, vecs, offset);
2493 
2494  delete [] output_name;
2495 }
2497 
2499 #if !OUTPUT_SINGLE_FILE
2500 char *ParOutput::buildFileName(OUTPUTFILETYPE type, int timestep){
2501  char *filename = NULL;
2502  const char *typeName = NULL;
2503  switch(type) {
2504  case dcdType:
2505  typeName = "dcd";
2506  break;
2507  case forcedcdType:
2508  typeName = "forcedcd";
2509  break;
2510  case veldcdType:
2511  typeName = "veldcd";
2512  break;
2513  case coorType:
2514  typeName = "coor";
2515  break;
2516  case forceType:
2517  typeName = "force";
2518  break;
2519  case velType:
2520  typeName = "vel";
2521  break;
2522  default:
2523  typeName = "invalid";
2524  break;
2525  }
2526  int baselen = strlen(namdMyNode->simParams->outputFilename);
2527  filename = new char[baselen+32];
2528  memset(filename, 0, baselen+32);
2529 
2530 #if 0
2531  strcpy(filename, namdMyNode->simParams->outputFilename);
2532 
2533  //check if the directory exists or not
2534  if(access(filename, F_OK)!=0) {
2535  int ret = MKDIR(filename);
2536  if(ret!=0) {
2537  char errmsg[512];
2538  sprintf(errmsg, "Error in creating top-level directory %s!", filename);
2539  NAMD_err(errmsg);
2540  }
2541  }
2542 
2543  strcat(filename, PATHSEPSTR);
2544  strcat(filename, typeName);
2545 
2546  //check if the directory exists or not
2547  if(access(filename, F_OK)!=0) {
2548  int ret = MKDIR(filename);
2549  if(ret!=0) {
2550  char errmsg[512];
2551  sprintf(errmsg, "Error in creating middle-level directory %s!", filename);
2552  NAMD_err(errmsg);
2553  }
2554  }
2555 #else
2556  sprintf(filename, "%s%s%s", namdMyNode->simParams->outputFilename, PATHSEPSTR, typeName);
2557 #endif
2558 
2559  char tmpstr[20];
2560  if(outputID == -1) {
2561  //indicating the output from master
2562  if(timestep!=-9999) {
2563  //not the default value
2564  sprintf(tmpstr, "%smeta.%d", PATHSEPSTR, timestep);
2565  }else{
2566  sprintf(tmpstr, "%smeta", PATHSEPSTR);
2567  }
2568  }else{
2569  //indicating the output from slave
2570  sprintf(tmpstr, "%s%d", PATHSEPSTR, outputID);
2571  strcat(filename, tmpstr);
2572  #if 0
2573  if(access(filename, F_OK)!=0) {
2574  int ret = MKDIR(filename);
2575  if(ret!=0) {
2576  char errmsg[512];
2577  sprintf(errmsg, "Error in creating last-level directory %s!", filename);
2578  NAMD_err(errmsg);
2579  }
2580  }
2581  #endif
2582  if(timestep!=-9999) {
2583  //not the default value
2584  sprintf(tmpstr, "%s%s_%d.%d", PATHSEPSTR,typeName,outputID,timestep);
2585  }else{
2586  sprintf(tmpstr,"%s%s_%d", PATHSEPSTR,typeName,outputID);
2587  }
2588  }
2589 
2590  strcat(filename, tmpstr);
2591  return filename;
2592 }
2593 #endif
2594 #endif
static Node * Object()
Definition: Node.h:86
int open_dcd_write_par_slave(char *dcdname)
Definition: dcdlib.C:689
static int velocityNeeded(int)
Definition: Output.C:365
OUTPUTFILETYPE
Definition: Output.h:34
void NAMD_err(const char *err_msg)
Definition: common.C:106
void close_veldcdfile()
Definition: Output.C:664
void sendReplicaDcdInit(int dstPart, ReplicaDcdInitMsg *msg, int msgsize)
Definition: DataExchanger.C:45
static int coordinateNeeded(int)
Definition: Output.C:198
short int32
Definition: dumpdcd.c:24
void setReplicaDcdIndex(int index)
Definition: Output.C:673
int update_dcdstep_par_header(int fd)
Definition: dcdlib.C:839
#define FILE_OUTPUT
Definition: Output.h:25
IMDOutput * imd
Definition: Node.h:183
ScriptTcl * getScript(void)
Definition: Node.h:192
#define EVAL_MEASURE
Definition: Output.h:27
Definition: Vector.h:64
Output * output
Definition: Node.h:182
SimParameters * simParameters
Definition: Node.h:178
~Output()
Definition: Output.C:178
char velDcdFilename[NAMD_FILENAME_BUFFER_SIZE]
Vector wrap_delta(const Position &pos1) const
Definition: Lattice.h:206
float Real
Definition: common.h:109
std::ostream & endi(std::ostream &s)
Definition: InfoStream.C:54
BigReal z
Definition: Vector.h:66
float y
Definition: Vector.h:18
#define PATHSEPSTR
Definition: Output.C:46
#define FALSE
Definition: common.h:118
#define MKDIR(X)
Definition: Output.C:47
std::ostream & iWARN(std::ostream &s)
Definition: InfoStream.C:82
void coordinate(int, int, Vector *, FloatVector *, Lattice &)
Definition: Output.C:277
int get_cluster(int anum) const
Definition: Molecule.h:1027
void gather_coordinates(int timestep, int N, FloatVector *coords)
Definition: IMDOutput.C:29
#define NAMD_write
Definition: dcdlib.C:24
#define OUTPUT_FILE_VERSION
Definition: Output.h:32
#define NAMD_close
Definition: Output.C:52
#define iout
Definition: InfoStream.h:51
#define seek_dcdfile
Definition: Output.C:123
BigReal length(void) const
Definition: Vector.h:169
static int forceNeeded(int)
Definition: Output.C:460
void close_dcdfile()
Definition: Output.C:655
int open_dcd_write(const char *dcdname)
Definition: dcdlib.C:662
#define NAMD_open
Definition: Output.C:50
#define DCD_FILEEXISTS
Definition: dcdlib.h:52
void wrap_coor(Vector *coor, Lattice &lattice, double *done)
Definition: Output.C:269
void recvReplicaDcdInit(ReplicaDcdInitMsg *msg)
Definition: Output.C:689
Definition: Output.h:43
int write_dcdstep_par_XYZUnits(int fd, int N)
Definition: dcdlib.C:810
int get_dcdheader_size()
Definition: dcdlib.C:1005
float x
Definition: Vector.h:18
int write_dcdstep_par_cell(int fd, double *cell)
Definition: dcdlib.C:785
#define OUTPUT_MAGIC_NUMBER
Definition: Output.h:31
float z
Definition: Vector.h:18
void sendReplicaDcdData(int dstPart, ReplicaDcdDataMsg *msg, int msgsize)
Definition: DataExchanger.C:56
void replicaDcdInit(int index, const char *filename)
Definition: Output.C:678
void NAMD_bug(const char *err_msg)
Definition: common.C:129
#define namdMyNode
Definition: Output.C:126
char dcdFilename[NAMD_FILENAME_BUFFER_SIZE]
gridSize z
int Bool
Definition: common.h:133
void velocity(int, int, Vector *)
Definition: Output.C:396
void recvReplicaDcdData(ReplicaDcdDataMsg *msg)
Definition: Output.C:700
int write_dcdstep(int fd, int N, float *X, float *Y, float *Z, double *cell)
Definition: dcdlib.C:736
BigReal x
Definition: Vector.h:66
int numAtoms
Definition: Molecule.h:557
#define END_OF_RUN
Definition: Output.h:26
void NAMD_die(const char *err_msg)
Definition: common.C:85
int write_dcdheader(int fd, const char *filename, int N, int NFILE, int NPRIV, int NSAVC, int NSTEP, double DELTA, int with_unitcell)
Definition: dcdlib.C:915
void NAMD_backup_file(const char *filename, const char *extension)
Definition: common.C:167
Definition: Output.h:40
char forceDcdFilename[NAMD_FILENAME_BUFFER_SIZE]
long long int64
Definition: common.h:34
#define simParams
Definition: Output.C:127
#define O_LARGEFILE
Definition: Output.C:55
Output()
Definition: Output.C:168
void sendReplicaDcdAck(int dstPart, ReplicaDcdAckMsg *msg)
Definition: DataExchanger.C:67
BigReal y
Definition: Vector.h:66
Vector b() const
Definition: Lattice.h:253
int write_dcdstep_par_slave(int fd, int parL, int parU, int N, float *X, float *Y, float *Z)
Definition: dcdlib.C:864
#define PDBVELFACTOR
Definition: common.h:50
#define TIMEFACTOR
Definition: common.h:48
double unitcell[6]
Definition: DataExchanger.h:49
gridSize y
Definition: Output.h:35
Vector wrap_nearest_delta(Position pos1) const
Definition: Lattice.h:217
int b_p() const
Definition: Lattice.h:274
gridSize x
void close_dcd_write(int fd)
Definition: dcdlib.C:1063
Bool is_water(int)
void measure(Vector *)
Definition: ScriptTcl.C:1387
int a_p() const
Definition: Lattice.h:273
Molecule * molecule
Definition: Node.h:176
Vector a() const
Definition: Lattice.h:252
#define TRUE
Definition: common.h:119
void wrap_coor_int(xVector *coor, Lattice &lattice, xDone *done)
Definition: Output.C:237
int get_clusterSize(int anum) const
Definition: Molecule.h:1028
void force(int, int, Vector *)
Definition: Output.C:486
Vector c() const
Definition: Lattice.h:254
#define FORCE_OUTPUT
Definition: Output.h:28
static void lattice_to_unitcell(const Lattice *lattice, double *unitcell)
Definition: Output.C:131
int c_p() const
Definition: Lattice.h:275
#define PDBVELINVFACTOR
Definition: common.h:51
for(int i=0;i< n1;++i)