00001
00007
00008
00009
00010
00011 #include "largefiles.h"
00012
00013 #include <string.h>
00014 #include <stdlib.h>
00015
00016 #include "InfoStream.h"
00017 #include "IMDOutput.h"
00018 #include "Output.h"
00019 #include "dcdlib.h"
00020 #include "strlib.h"
00021 #include "Molecule.h"
00022 #include "Node.h"
00023 #include "Parameters.h"
00024 #include "PDB.h"
00025 #include "SimParameters.h"
00026 #include "Vector.h"
00027 #include "structures.h"
00028 #include "MStream.h"
00029 #include "Communicate.h"
00030 #include "PatchMap.h"
00031 #include "PatchMap.inl"
00032 #include "ScriptTcl.h"
00033 #include "Lattice.h"
00034 #include "DataExchanger.h"
00035 #include <fcntl.h>
00036 #include <sys/stat.h>
00037 #ifdef WIN32
00038 #include <io.h>
00039 #define access(PATH,MODE) _access(PATH,00)
00040 #endif
00041
00042 #if defined(WIN32) && !defined(__CYGWIN__)
00043 #define PATHSEPSTR "\\"
00044 #define MKDIR(X) mkdir(X)
00045 #else
00046 #define PATHSEPSTR "/"
00047 #define MKDIR(X) mkdir(X,0777)
00048 #endif
00049
00050 #define NAMD_open NAMD_open64
00051 #define NAMD_write NAMD_write64
00052 #define NAMD_close NAMD_close64
00053
00054 #ifndef O_LARGEFILE
00055 #define O_LARGEFILE 0x0
00056 #endif
00057
00058
00059 int NAMD_open(const char *fname) {
00060 int fd;
00061
00062
00063 #ifdef WIN32
00064 while ( (fd = _open(fname, O_WRONLY|O_CREAT|O_EXCL|O_BINARY|O_LARGEFILE,_S_IREAD|_S_IWRITE)) < 0) {
00065 #else
00066 #ifdef NAMD_NO_O_EXCL
00067 while ( (fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE,
00068 #else
00069 while ( (fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE,
00070 #endif
00071 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
00072 #endif
00073 if ( errno != EINTR ) {
00074 char errmsg[1024];
00075 sprintf(errmsg, "Unable to open binary file %s", fname);
00076 NAMD_err(errmsg);
00077 }
00078 }
00079
00080 return fd;
00081 }
00082
00083
00084 void NAMD_write(int fd, const char *buf, size_t count, const char *errmsg="NAMD_write64") {
00085 double firsttime = 0.;
00086 while ( count ) {
00087 #if defined(WIN32) && !defined(__CYGWIN__)
00088 long retval = _write(fd,buf,count);
00089 #else
00090 ssize_t retval = write(fd,buf,count);
00091 #endif
00092 if ( retval < 0 && errno == EINTR ) retval = 0;
00093 if ( retval < 0 && errno == ENOMEM ) {
00094 if ( firsttime == 0. ) firsttime = CmiWallTimer();
00095 if ( (CmiWallTimer() - firsttime) < 300. ) retval = 0;
00096 }
00097 if ( retval < 0 ) NAMD_err(errmsg);
00098 if ( retval > count ) NAMD_bug("extra bytes written in NAMD_write64()");
00099 buf += retval;
00100 count -= retval;
00101 }
00102 if ( firsttime != 0. ) {
00103 iout << iWARN << errmsg << ": NAMD_write64() retried for " << (CmiWallTimer() - firsttime) << " seconds.\n" << endi;
00104 }
00105 }
00106
00107
00108 void NAMD_close(int fd, const char *fname) {
00109 #ifdef WIN32
00110 while ( _close(fd) ) {
00111 #else
00112 while ( close(fd) ) {
00113 #endif
00114 if ( errno != EINTR ) {
00115 char errmsg[1024];
00116 sprintf(errmsg, "Error on closing file %s", fname);
00117 NAMD_err(errmsg);
00118 }
00119 }
00120 }
00121
00122
00123 #define seek_dcdfile NAMD_seek
00124
00125
00126 #define namdMyNode Node::Object()
00127 #define simParams simParameters
00128 #define pdbData pdb
00129
00130
00131 static void lattice_to_unitcell(const Lattice *lattice, double *unitcell) {
00132
00133 unitcell[0] = unitcell[2] = unitcell[5] = 0.0;
00134 unitcell[1] = unitcell[3] = unitcell[4] = 0.0;
00135
00136 if (lattice) {
00137 const Vector &a=lattice->a();
00138 const Vector &b=lattice->b();
00139 const Vector &c=lattice->c();
00140 unitcell[0] = (lattice->a_p()) ? a.length() : 0.0;
00141 unitcell[2] = (lattice->b_p()) ? b.length() : 0.0;
00142 unitcell[5] = (lattice->c_p()) ? c.length() : 0.0;
00143 double cosAB = (lattice->a_p() && lattice->b_p() ) ?
00144 (a*b)/(unitcell[0]*unitcell[2]) : 0.0;
00145 double cosAC = (lattice->a_p() && lattice->c_p() ) ?
00146 (a*c)/(unitcell[0]*unitcell[5]) : 0.0;
00147 double cosBC = (lattice->b_p() && lattice->c_p() ) ?
00148 (b*c)/(unitcell[2]*unitcell[5]) : 0.0;
00149 if (cosAB > 1.0) cosAB = 1.0; else if (cosAB < -1.0) cosAB = -1.0;
00150 if (cosAC > 1.0) cosAC = 1.0; else if (cosAC < -1.0) cosAC = -1.0;
00151 if (cosBC > 1.0) cosBC = 1.0; else if (cosBC < -1.0) cosBC = -1.0;
00152 unitcell[1] = cosAB;
00153 unitcell[3] = cosAC;
00154 unitcell[4] = cosBC;
00155 }
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 Output::Output() : replicaDcdActive(0) { }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 Output::~Output() { }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 int Output::coordinateNeeded(int timestep)
00199 {
00200 SimParameters *simParams = Node::Object()->simParameters;
00201
00202 if(simParams->benchTimestep) return 0;
00203
00204 int positionsNeeded = 0;
00205
00206 if ( timestep >= 0 ) {
00207
00208
00209 if ( simParams->dcdFrequency &&
00210 ((timestep % simParams->dcdFrequency) == 0) )
00211 { positionsNeeded |= 1; }
00212
00213
00214 if ( simParams->restartFrequency &&
00215 ((timestep % simParams->restartFrequency) == 0) )
00216 { positionsNeeded |= 2; }
00217
00218
00219 if ( simParams->IMDon &&
00220 ( ((timestep % simParams->IMDfreq) == 0) ||
00221 (timestep == simParams->firstTimestep) ) )
00222 { positionsNeeded |= 1; }
00223
00224 }
00225
00226
00227 if (timestep == FILE_OUTPUT || timestep == END_OF_RUN ||
00228 timestep == EVAL_MEASURE)
00229 {
00230 positionsNeeded |= 2;
00231 }
00232
00233 return positionsNeeded;
00234 }
00235
00236 template <class xVector, class xDone>
00237 void wrap_coor_int(xVector *coor, Lattice &lattice, xDone *done) {
00238 SimParameters *simParams = Node::Object()->simParameters;
00239 if ( *done ) return;
00240 *done = 1;
00241 if ( ! ( simParams->wrapAll || simParams->wrapWater ) ) return;
00242 const int wrapNearest = simParams->wrapNearest;
00243 const int wrapAll = simParams->wrapAll;
00244 Molecule *molecule = Node::Object()->molecule;
00245 int n = molecule->numAtoms;
00246 int i;
00247 #ifndef MEM_OPT_VERSION
00248 Position *con = new Position[n];
00249 for ( i = 0; i < n; ++i ) {
00250 con[i] = 0;
00251 int ci = molecule->get_cluster(i);
00252 con[ci] += coor[i];
00253 }
00254 for ( i = 0; i < n; ++i ) {
00255 if ( ! wrapAll && ! molecule->is_water(i) ) continue;
00256 int ci = molecule->get_cluster(i);
00257 if ( ci == i ) {
00258 Vector coni = con[i] / molecule->get_clusterSize(i);
00259 Vector trans = ( wrapNearest ?
00260 lattice.wrap_nearest_delta(coni) : lattice.wrap_delta(coni) );
00261 con[i] = trans;
00262 }
00263 coor[i] = coor[i] + con[ci];
00264 }
00265 delete [] con;
00266 #endif
00267 }
00268
00269 void wrap_coor(Vector *coor, Lattice &lattice, double *done) {
00270 wrap_coor_int(coor,lattice,done);
00271 };
00272
00273 void wrap_coor(FloatVector *coor, Lattice &lattice, float *done) {
00274 wrap_coor_int(coor,lattice,done);
00275 };
00276
00277 void Output::coordinate(int timestep, int n, Vector *coor, FloatVector *fcoor,
00278 Lattice &lattice)
00279 {
00280 SimParameters *simParams = Node::Object()->simParameters;
00281 double coor_wrapped = 0;
00282 float fcoor_wrapped = 0;
00283
00284 if ( timestep >= 0 ) {
00285
00286
00287 if ( simParams->dcdFrequency &&
00288 ((timestep % simParams->dcdFrequency) == 0) )
00289 {
00290 wrap_coor(fcoor,lattice,&fcoor_wrapped);
00291 output_dcdfile(timestep, n, fcoor,
00292 simParams->dcdUnitCell ? &lattice : NULL);
00293 }
00294
00295
00296 if ( simParams->restartFrequency &&
00297 ((timestep % simParams->restartFrequency) == 0) )
00298 {
00299 iout << "WRITING COORDINATES TO RESTART FILE AT STEP "
00300 << timestep << "\n" << endi;
00301 wrap_coor(coor,lattice,&coor_wrapped);
00302 output_restart_coordinates(coor, n, timestep);
00303 iout << "FINISHED WRITING RESTART COORDINATES\n" <<endi;
00304 fflush(stdout);
00305 }
00306
00307
00308 if ( simParams->IMDon &&
00309 ( ((timestep % simParams->IMDfreq) == 0) ||
00310 (timestep == simParams->firstTimestep) ) )
00311 {
00312 IMDOutput *imd = Node::Object()->imd;
00313 wrap_coor(fcoor,lattice,&fcoor_wrapped);
00314 if (imd != NULL) imd->gather_coordinates(timestep, n, fcoor);
00315 }
00316
00317 }
00318
00319 if (timestep == EVAL_MEASURE)
00320 {
00321 #ifdef NAMD_TCL
00322 wrap_coor(coor,lattice,&coor_wrapped);
00323 Node::Object()->getScript()->measure(coor);
00324 #endif
00325 }
00326
00327
00328 if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
00329 {
00330 int realstep = ( timestep == FILE_OUTPUT ?
00331 simParams->firstTimestep : simParams->N );
00332 iout << "WRITING COORDINATES TO OUTPUT FILE AT STEP "
00333 << realstep << "\n" << endi;
00334 fflush(stdout);
00335 wrap_coor(coor,lattice,&coor_wrapped);
00336 output_final_coordinates(coor, n, realstep);
00337 }
00338
00339
00340 if (timestep == END_OF_RUN)
00341 {
00342 if (simParams->dcdFrequency) output_dcdfile(END_OF_RUN,0,0,
00343 simParams->dcdUnitCell ? &lattice : NULL);
00344 }
00345
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 int Output::velocityNeeded(int timestep)
00366 {
00367 SimParameters *simParams = Node::Object()->simParameters;
00368
00369 if(simParams->benchTimestep) return 0;
00370
00371 int velocitiesNeeded = 0;
00372
00373 if ( timestep >= 0 ) {
00374
00375
00376 if ( simParams->velDcdFrequency &&
00377 ((timestep % simParams->velDcdFrequency) == 0) )
00378 { velocitiesNeeded |= 1; }
00379
00380
00381 if ( simParams->restartFrequency &&
00382 ((timestep % simParams->restartFrequency) == 0) )
00383 { velocitiesNeeded |= 2; }
00384
00385 }
00386
00387
00388 if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
00389 {
00390 velocitiesNeeded |= 2;
00391 }
00392
00393 return velocitiesNeeded;
00394 }
00395
00396 void Output::velocity(int timestep, int n, Vector *vel)
00397 {
00398 SimParameters *simParams = Node::Object()->simParameters;
00399
00400 if ( timestep >= 0 ) {
00401
00402
00403 if ( simParams->velDcdFrequency &&
00404 ((timestep % simParams->velDcdFrequency) == 0) )
00405 {
00406 output_veldcdfile(timestep, n, vel);
00407 }
00408
00409
00410 if ( simParams->restartFrequency &&
00411 ((timestep % simParams->restartFrequency) == 0) )
00412 {
00413 iout << "WRITING VELOCITIES TO RESTART FILE AT STEP "
00414 << timestep << "\n" << endi;
00415 output_restart_velocities(timestep, n, vel);
00416 iout << "FINISHED WRITING RESTART VELOCITIES\n" <<endi;
00417 fflush(stdout);
00418 }
00419
00420 }
00421
00422
00423 if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
00424 {
00425 int realstep = ( timestep == FILE_OUTPUT ?
00426 simParams->firstTimestep : simParams->N );
00427 iout << "WRITING VELOCITIES TO OUTPUT FILE AT STEP "
00428 << realstep << "\n" << endi;
00429 fflush(stdout);
00430 output_final_velocities(realstep, n, vel);
00431 }
00432
00433
00434 if (timestep == END_OF_RUN)
00435 {
00436 if (simParams->velDcdFrequency) output_veldcdfile(END_OF_RUN,0,0);
00437
00438 if (simParams->forceDcdFrequency) output_forcedcdfile(END_OF_RUN,0,0);
00439 }
00440
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 int Output::forceNeeded(int timestep)
00461 {
00462 SimParameters *simParams = Node::Object()->simParameters;
00463
00464 if(simParams->benchTimestep) return 0;
00465
00466 int forcesNeeded = 0;
00467
00468 if ( timestep >= 0 ) {
00469
00470
00471 if ( simParams->forceDcdFrequency &&
00472 ((timestep % simParams->forceDcdFrequency) == 0) )
00473 { forcesNeeded |= 1; }
00474
00475 }
00476
00477
00478 if (timestep == FORCE_OUTPUT)
00479 {
00480 forcesNeeded |= 2;
00481 }
00482
00483 return forcesNeeded;
00484 }
00485
00486 void Output::force(int timestep, int n, Vector *frc)
00487 {
00488 SimParameters *simParams = Node::Object()->simParameters;
00489
00490 if ( timestep >= 0 ) {
00491
00492
00493 if ( simParams->forceDcdFrequency &&
00494 ((timestep % simParams->forceDcdFrequency) == 0) )
00495 {
00496 output_forcedcdfile(timestep, n, frc);
00497 }
00498
00499 }
00500
00501
00502 if (timestep == FORCE_OUTPUT)
00503 {
00504 int realstep = simParams->firstTimestep;
00505 iout << "WRITING FORCES TO OUTPUT FILE AT STEP "
00506 << realstep << "\n" << endi;
00507 fflush(stdout);
00508 output_forces(realstep, n, frc);
00509 }
00510
00511
00512
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 void Output::output_restart_coordinates(Vector *coor, int n, int timestep)
00532
00533 {
00534 char comment[128];
00535 char timestepstr[20];
00536
00537 int baselen = strlen(namdMyNode->simParams->restartFilename);
00538 char *restart_name = new char[baselen+26];
00539 const char *bsuffix = ".old";
00540
00541 strcpy(restart_name, namdMyNode->simParams->restartFilename);
00542 if ( namdMyNode->simParams->restartSave ) {
00543 sprintf(timestepstr,".%d",timestep);
00544 strcat(restart_name, timestepstr);
00545 bsuffix = ".BAK";
00546 }
00547 strcat(restart_name, ".coor");
00548
00549 NAMD_backup_file(restart_name,bsuffix);
00550
00551
00552 if (!namdMyNode->simParams->binaryRestart)
00553 {
00554
00555 sprintf(comment, "RESTART COORDINATES WRITTEN BY NAMD AT TIMESTEP %d", timestep);
00556
00557 namdMyNode->pdbData->set_all_positions(coor);
00558 namdMyNode->pdbData->write(restart_name, comment);
00559 }
00560 else
00561 {
00562
00563 write_binary_file(restart_name, n, coor);
00564 }
00565
00566 delete [] restart_name;
00567
00568 if ( namdMyNode->simParams->restartSaveDcd ) {
00569 if ( ! output_dcdfile(END_OF_RUN, 0, 0, 0) ) {
00570 const char *old_name = namdMyNode->simParams->dcdFilename;
00571 int old_len = strlen(old_name);
00572 char *new_name = new char[old_len+26];
00573 strcpy(new_name, old_name);
00574 if ( old_len >= 4 && ! strcmp(new_name+old_len-4,".dcd") ) {
00575 old_len -= 4;
00576 new_name[old_len] = 0;
00577 }
00578 sprintf(timestepstr,".%d",timestep);
00579 strcat(new_name, timestepstr);
00580 strcat(new_name, ".dcd");
00581 iout << "RENAMING COORDINATE DCD FILE " << old_name << " TO " << new_name << "\n" << endi;
00582 NAMD_backup_file(new_name,".BAK");
00583 while ( rename(old_name, new_name) ) {
00584 if ( errno == EINTR || errno == EXDEV ) continue;
00585 char err_msg[257];
00586 sprintf(err_msg, "Unable to rename DCD file %s to %s", old_name, new_name);
00587 NAMD_err(err_msg);
00588 }
00589 delete [] new_name;
00590 }
00591 }
00592
00593 }
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 void Output::output_restart_velocities(int timestep, int n, Vector *vel)
00611
00612 {
00613 char comment[128];
00614 char timestepstr[20];
00615
00616 int baselen = strlen(namdMyNode->simParams->restartFilename);
00617 char *restart_name = new char[baselen+26];
00618 const char *bsuffix = ".old";
00619
00620 strcpy(restart_name, namdMyNode->simParams->restartFilename);
00621 if ( namdMyNode->simParams->restartSave ) {
00622 sprintf(timestepstr,".%d",timestep);
00623 strcat(restart_name, timestepstr);
00624 bsuffix = ".BAK";
00625 }
00626 strcat(restart_name, ".vel");
00627
00628 NAMD_backup_file(restart_name,bsuffix);
00629
00630
00631 if (!namdMyNode->simParams->binaryRestart)
00632 {
00633
00634
00635 sprintf(comment, "RESTART VELOCITIES WRITTEN BY NAMD AT TIMESTEP %d", timestep);
00636
00637 scale_vels(vel, n, PDBVELFACTOR);
00638 namdMyNode->pdbData->set_all_positions(vel);
00639 namdMyNode->pdbData->write(restart_name, comment);
00640 scale_vels(vel, n, PDBVELINVFACTOR);
00641 }
00642 else
00643 {
00644
00645 write_binary_file(restart_name, n, vel);
00646 }
00647
00648 delete [] restart_name;
00649 }
00650
00651
00652
00653
00654
00655 void SimParameters::close_dcdfile() {
00656
00657 Output *output = Node::Object()->output;
00658 if ( ! output ) return;
00659
00660 output->output_dcdfile(END_OF_RUN, 0, 0, 0);
00661
00662 }
00663
00664 void SimParameters::close_veldcdfile() {
00665
00666 Output *output = Node::Object()->output;
00667 if ( ! output ) return;
00668
00669 output->output_veldcdfile(END_OF_RUN, 0, 0);
00670
00671 }
00672
00673 void Output::setReplicaDcdIndex(int index) {
00674 replicaDcdActive = 1;
00675 replicaDcdIndex = index;
00676 }
00677
00678 void Output::replicaDcdInit(int index, const char *filename) {
00679 replicaDcdActive = 1;
00680 replicaDcdIndex = index;
00681 int msgsize = sizeof(ReplicaDcdInitMsg) + strlen(filename);
00682 ReplicaDcdInitMsg *msg = (ReplicaDcdInitMsg *) CmiAlloc(msgsize);
00683 msg->srcPart = CmiMyPartition();
00684 msg->dcdIndex = replicaDcdIndex;
00685 strcpy(msg->data, filename);
00686 sendReplicaDcdInit(abs(replicaDcdIndex) % CmiNumPartitions(), msg, msgsize);
00687 }
00688
00689 void Output::recvReplicaDcdInit(ReplicaDcdInitMsg *msg) {
00690 replicaDcdFile &f = replicaDcdFiles[msg->dcdIndex];
00691 if ( f.fileid ) {
00692 iout << "CLOSING REPLICA DCD FILE " << msg->dcdIndex << " " << f.filename.c_str() << "\n" << endi;
00693 close_dcd_write(f.fileid);
00694 f.fileid = 0;
00695 }
00696 f.filename = (const char*) msg->data;
00697 sendReplicaDcdAck(msg->srcPart, (ReplicaDcdAckMsg*) CmiAlloc(sizeof(ReplicaDcdAckMsg)));
00698 }
00699
00700 void Output::recvReplicaDcdData(ReplicaDcdDataMsg *msg) {
00701 if ( ! replicaDcdFiles.count(msg->dcdIndex) ) {
00702 char err_msg[257];
00703 sprintf(err_msg, "Unknown replicaDcdFile identifier %d\n", msg->dcdIndex);
00704 NAMD_die(err_msg);
00705 }
00706 replicaDcdFile &f = replicaDcdFiles[msg->dcdIndex];
00707
00708 if ( ! f.fileid ) {
00709
00710 iout << "OPENING REPLICA DCD FILE " << msg->dcdIndex << " " << f.filename.c_str() << "\n" << endi;
00711
00712 f.fileid=open_dcd_write(f.filename.c_str());
00713
00714 if (f.fileid == DCD_FILEEXISTS) {
00715 char err_msg[257];
00716 sprintf(err_msg, "DCD file %s already exists!!", f.filename.c_str());
00717 NAMD_err(err_msg);
00718 } else if (f.fileid < 0) {
00719 char err_msg[257];
00720 sprintf(err_msg, "Couldn't open DCD file %s", f.filename.c_str());
00721 NAMD_err(err_msg);
00722 } else if (! f.fileid) {
00723 NAMD_bug("Output::recvReplicaDcdData open_dcd_write returned fileid of zero");
00724 }
00725
00726
00727 int ret_code = write_dcdheader(f.fileid, f.filename.c_str(),
00728 msg->numAtoms, msg->NFILE, msg->NPRIV, msg->NSAVC, msg->NSTEP,
00729 msg->DELTA, msg->with_unitcell);
00730
00731 if (ret_code<0) {
00732 NAMD_err("Writing of DCD header failed!!");
00733 }
00734 }
00735
00736
00737 iout << "WRITING TO REPLICA DCD FILE " << msg->dcdIndex << " " << f.filename.c_str() << "\n" << endi;
00738 float *msgx = (float*) msg->data;
00739 float *msgy = msgx + msg->numAtoms;
00740 float *msgz = msgy + msg->numAtoms;
00741 int ret_code = write_dcdstep(f.fileid, msg->numAtoms, msgx, msgy, msgz,
00742 msg->with_unitcell ? msg->unitcell : 0);
00743 if (ret_code < 0) NAMD_err("Writing of DCD step failed!!");
00744
00745 sendReplicaDcdAck(msg->srcPart, (ReplicaDcdAckMsg*) CmiAlloc(sizeof(ReplicaDcdAckMsg)));
00746 }
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764 #define RAD2DEG 180.0/3.14159265359
00765
00766 int Output::output_dcdfile(int timestep, int n, FloatVector *coor,
00767 const Lattice *lattice)
00768
00769 {
00770 static Bool first=TRUE;
00771 static int fileid;
00772
00773 static float *x, *y, *z;
00774 static int n_alloc;
00775
00776 int i;
00777 int ret_code;
00778 SimParameters *simParams = namdMyNode->simParams;
00779
00780
00781
00782 if ( timestep == END_OF_RUN ) {
00783 for ( std::map<int,replicaDcdFile>::iterator it = replicaDcdFiles.begin();
00784 it != replicaDcdFiles.end(); ++it ) {
00785 replicaDcdFile &f = it->second;
00786 if ( f.fileid ) {
00787 iout << "CLOSING REPLICA DCD FILE " << it->first << " " << f.filename.c_str() << "\n" << endi;
00788 close_dcd_write(f.fileid);
00789 f.fileid = 0;
00790 }
00791 }
00792 int rval = 0;
00793 if ( ! first ) {
00794 iout << "CLOSING COORDINATE DCD FILE " << simParams->dcdFilename << "\n" << endi;
00795 close_dcd_write(fileid);
00796 } else {
00797 iout << "COORDINATE DCD FILE " << simParams->dcdFilename << " WAS NOT CREATED\n" << endi;
00798 rval = -1;
00799 }
00800 first = 1;
00801 fileid = 0;
00802 return rval;
00803 }
00804
00805 if ( replicaDcdActive ) {
00806 int msgsize = sizeof(ReplicaDcdDataMsg) + 3*n*sizeof(float);
00807 ReplicaDcdDataMsg *msg = (ReplicaDcdDataMsg *) CmiAlloc(msgsize);
00808 float *msgx = (float*) msg->data;
00809 float *msgy = msgx + n;
00810 float *msgz = msgy + n;
00811 for (i=0; i<n; i++) { msgx[i] = coor[i].x; }
00812 for (i=0; i<n; i++) { msgy[i] = coor[i].y; }
00813 for (i=0; i<n; i++) { msgz[i] = coor[i].z; }
00814 msg->numAtoms = n;
00815 lattice_to_unitcell(lattice,msg->unitcell);
00816 msg->with_unitcell = lattice ? 1 : 0;
00817 msg->NSAVC = simParams->dcdFrequency;
00818 msg->NPRIV = timestep;
00819 msg->NSTEP = msg->NPRIV - msg->NSAVC;
00820 msg->NFILE = 0;
00821 msg->DELTA = simParams->dt/TIMEFACTOR;
00822 msg->srcPart = CmiMyPartition();
00823 msg->dcdIndex = replicaDcdIndex;
00824 sendReplicaDcdData(abs(replicaDcdIndex) % CmiNumPartitions(), msg, msgsize);
00825 return 0;
00826 }
00827
00828 if (first)
00829 {
00830
00831
00832
00833 if ( n > n_alloc ) {
00834 delete [] x; x = new float[3*n];
00835 y = x + n;
00836 z = x + 2*n;
00837 n_alloc = n;
00838 }
00839
00840
00841 iout << "OPENING COORDINATE DCD FILE\n" << endi;
00842
00843 fileid=open_dcd_write(simParams->dcdFilename);
00844
00845 if (fileid == DCD_FILEEXISTS)
00846 {
00847 char err_msg[257];
00848
00849 sprintf(err_msg, "DCD file %s already exists!!",
00850 simParams->dcdFilename);
00851
00852 NAMD_err(err_msg);
00853 }
00854 else if (fileid < 0)
00855 {
00856 char err_msg[257];
00857
00858 sprintf(err_msg, "Couldn't open DCD file %s",
00859 simParams->dcdFilename);
00860
00861 NAMD_err(err_msg);
00862 }
00863
00864 int NSAVC, NFILE, NPRIV, NSTEP;
00865 NSAVC = simParams->dcdFrequency;
00866 NPRIV = timestep;
00867 NSTEP = NPRIV - NSAVC;
00868 NFILE = 0;
00869
00870
00871 ret_code = write_dcdheader(fileid,
00872 simParams->dcdFilename,
00873 n, NFILE, NPRIV, NSAVC, NSTEP,
00874 simParams->dt/TIMEFACTOR, lattice != NULL);
00875
00876
00877 if (ret_code<0)
00878 {
00879 NAMD_err("Writing of DCD header failed!!");
00880 }
00881
00882 first = FALSE;
00883 }
00884
00885
00886 for (i=0; i<n; i++)
00887 {
00888 x[i] = coor[i].x;
00889 y[i] = coor[i].y;
00890 z[i] = coor[i].z;
00891 }
00892
00893
00894 iout << "WRITING COORDINATES TO DCD FILE " << simParams->dcdFilename << " AT STEP "
00895 << timestep << "\n" << endi;
00896 fflush(stdout);
00897 if (lattice) {
00898 double unitcell[6];
00899 lattice_to_unitcell(lattice,unitcell);
00900 ret_code = write_dcdstep(fileid, n, x, y, z, unitcell);
00901 } else {
00902 ret_code = write_dcdstep(fileid, n, x, y, z, NULL);
00903 }
00904 if (ret_code < 0)
00905 {
00906 NAMD_err("Writing of DCD step failed!!");
00907 }
00908
00909 return 0;
00910 }
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928 void Output::output_final_coordinates(Vector *coor, int n, int timestep)
00929
00930 {
00931 char output_name[140];
00932 char comment[128];
00933
00934
00935 strcpy(output_name, namdMyNode->simParams->outputFilename);
00936 strcat(output_name, ".coor");
00937
00938 NAMD_backup_file(output_name);
00939
00940
00941
00942 if (!namdMyNode->simParams->binaryOutput)
00943 {
00944 sprintf(comment, "FINAL COORDINATES WRITTEN BY NAMD AT TIMESTEP %d", timestep);
00945
00946 namdMyNode->pdbData->set_all_positions(coor);
00947 namdMyNode->pdbData->write(output_name, comment);
00948 }
00949 else
00950 {
00951
00952 write_binary_file(output_name, n, coor);
00953 }
00954 }
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971 void Output::output_final_velocities(int timestep, int n, Vector *vel)
00972
00973 {
00974 char output_name[140];
00975 char comment[128];
00976
00977
00978 strcpy(output_name, namdMyNode->simParams->outputFilename);
00979 strcat(output_name, ".vel");
00980
00981 NAMD_backup_file(output_name);
00982
00983
00984 if (!(namdMyNode->simParams->binaryOutput))
00985 {
00986
00987 sprintf(comment, "FINAL VELOCITIES WRITTEN BY NAMD AT TIMESTEP %d", timestep);
00988
00989 scale_vels(vel, n, PDBVELFACTOR);
00990 namdMyNode->pdbData->set_all_positions(vel);
00991 namdMyNode->pdbData->write(output_name, comment);
00992 scale_vels(vel, n, PDBVELINVFACTOR);
00993 }
00994 else
00995 {
00996
00997 write_binary_file(output_name, n, vel);
00998 }
00999
01000 }
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018 void Output::output_veldcdfile(int timestep, int n, Vector *vel)
01019
01020 {
01021 static Bool first=TRUE;
01022 static int fileid;
01023 static float *x, *y, *z;
01024 static int n_alloc;
01025 int i;
01026 int ret_code;
01027 SimParameters *simParams = Node::Object()->simParameters;
01028
01029
01030
01031 if ( timestep == END_OF_RUN ) {
01032 if ( ! first ) {
01033 iout << "CLOSING VELOCITY DCD FILE\n" << endi;
01034 close_dcd_write(fileid);
01035 } else {
01036 iout << "VELOCITY DCD FILE WAS NOT CREATED\n" << endi;
01037 }
01038 first = TRUE;
01039 fileid = 0;
01040 return;
01041 }
01042
01043 if (first)
01044 {
01045
01046
01047
01048 if ( n > n_alloc ) {
01049 delete [] x; x = new float[3*n];
01050 y = x + n;
01051 z = x + 2*n;
01052 n_alloc = n;
01053 }
01054
01055
01056 iout << "OPENING VELOCITY DCD FILE\n" << endi;
01057
01058 fileid=open_dcd_write(namdMyNode->simParams->velDcdFilename);
01059
01060 if (fileid == DCD_FILEEXISTS)
01061 {
01062 char err_msg[257];
01063
01064 sprintf(err_msg, "Velocity DCD file %s already exists!!",
01065 namdMyNode->simParams->velDcdFilename);
01066
01067 NAMD_err(err_msg);
01068 }
01069 else if (fileid < 0)
01070 {
01071 char err_msg[257];
01072
01073 sprintf(err_msg, "Couldn't open velocity DCD file %s",
01074 namdMyNode->simParams->velDcdFilename);
01075
01076 NAMD_err(err_msg);
01077 }
01078
01079 int NSAVC, NFILE, NPRIV, NSTEP;
01080 NSAVC = simParams->velDcdFrequency;
01081 NPRIV = timestep;
01082 NSTEP = NPRIV - NSAVC;
01083 NFILE = 0;
01084
01085
01086 const int with_unitcell = 0;
01087 ret_code = write_dcdheader(fileid,
01088 simParams->velDcdFilename,
01089 n, NFILE, NPRIV, NSAVC, NSTEP,
01090 simParams->dt/TIMEFACTOR, with_unitcell);
01091
01092
01093 if (ret_code<0)
01094 {
01095 NAMD_err("Writing of velocity DCD header failed!!");
01096 }
01097
01098 first = FALSE;
01099 }
01100
01101
01102 for (i=0; i<n; i++)
01103 {
01104 x[i] = vel[i].x;
01105 y[i] = vel[i].y;
01106 z[i] = vel[i].z;
01107 }
01108
01109
01110 iout << "WRITING VELOCITIES TO DCD FILE AT STEP "
01111 << timestep << "\n" << endi;
01112 fflush(stdout);
01113 ret_code = write_dcdstep(fileid, n, x, y, z, NULL);
01114
01115 if (ret_code < 0)
01116 {
01117 NAMD_err("Writing of velocity DCD step failed!!");
01118 }
01119
01120 }
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137 void Output::output_forces(int timestep, int n, Vector *frc)
01138
01139 {
01140 char output_name[140];
01141 char comment[128];
01142
01143
01144 strcpy(output_name, namdMyNode->simParams->outputFilename);
01145 strcat(output_name, ".force");
01146
01147 NAMD_backup_file(output_name);
01148
01149
01150 if (!(namdMyNode->simParams->binaryOutput))
01151 {
01152
01153 sprintf(comment, "FORCES WRITTEN BY NAMD AT TIMESTEP %d", timestep);
01154
01155 namdMyNode->pdbData->set_all_positions(frc);
01156 namdMyNode->pdbData->write(output_name, comment);
01157 }
01158 else
01159 {
01160
01161 write_binary_file(output_name, n, frc);
01162 }
01163
01164 }
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182 void Output::output_forcedcdfile(int timestep, int n, Vector *frc)
01183
01184 {
01185 static Bool first=TRUE;
01186 static int fileid;
01187 static float *x, *y, *z;
01188 static int n_alloc;
01189 int i;
01190 int ret_code;
01191 SimParameters *simParams = Node::Object()->simParameters;
01192
01193
01194
01195 if ( timestep == END_OF_RUN ) {
01196 if ( ! first ) {
01197 iout << "CLOSING FORCE DCD FILE\n" << endi;
01198 close_dcd_write(fileid);
01199 } else {
01200 iout << "FORCE DCD FILE WAS NOT CREATED\n" << endi;
01201 }
01202 return;
01203 }
01204
01205 if (first)
01206 {
01207
01208
01209
01210 if ( n > n_alloc ) {
01211 delete [] x; x = new float[3*n];
01212 y = x + n;
01213 z = x + 2*n;
01214 n_alloc = n;
01215 }
01216
01217
01218 iout << "OPENING FORCE DCD FILE\n" << endi;
01219
01220 fileid=open_dcd_write(namdMyNode->simParams->forceDcdFilename);
01221
01222 if (fileid == DCD_FILEEXISTS)
01223 {
01224 char err_msg[257];
01225
01226 sprintf(err_msg, "Force DCD file %s already exists!!",
01227 namdMyNode->simParams->forceDcdFilename);
01228
01229 NAMD_err(err_msg);
01230 }
01231 else if (fileid < 0)
01232 {
01233 char err_msg[257];
01234
01235 sprintf(err_msg, "Couldn't open force DCD file %s",
01236 namdMyNode->simParams->forceDcdFilename);
01237
01238 NAMD_err(err_msg);
01239 }
01240
01241 int NSAVC, NFILE, NPRIV, NSTEP;
01242 NSAVC = simParams->forceDcdFrequency;
01243 NPRIV = timestep;
01244 NSTEP = NPRIV - NSAVC;
01245 NFILE = 0;
01246
01247
01248 const int with_unitcell = 0;
01249 ret_code = write_dcdheader(fileid,
01250 simParams->forceDcdFilename,
01251 n, NFILE, NPRIV, NSAVC, NSTEP,
01252 simParams->dt/TIMEFACTOR, with_unitcell);
01253
01254
01255 if (ret_code<0)
01256 {
01257 NAMD_err("Writing of force DCD header failed!!");
01258 }
01259
01260 first = FALSE;
01261 }
01262
01263
01264 for (i=0; i<n; i++)
01265 {
01266 x[i] = frc[i].x;
01267 y[i] = frc[i].y;
01268 z[i] = frc[i].z;
01269 }
01270
01271
01272 iout << "WRITING FORCES TO DCD FILE AT STEP "
01273 << timestep << "\n" << endi;
01274 fflush(stdout);
01275 ret_code = write_dcdstep(fileid, n, x, y, z, NULL);
01276
01277 if (ret_code < 0)
01278 {
01279 NAMD_err("Writing of force DCD step failed!!");
01280 }
01281
01282 }
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299 void Output::write_binary_file(char *fname, int n, Vector *vecs)
01300
01301 {
01302 char errmsg[256];
01303 int fd;
01304 int32 n32 = n;
01305
01306 fd = NAMD_open(fname);
01307
01308 sprintf(errmsg, "Error on write to binary file %s", fname);
01309
01310
01311 NAMD_write(fd, (char *) &n32, sizeof(int32), errmsg);
01312 NAMD_write(fd, (char *) vecs, sizeof(Vector)*n, errmsg);
01313
01314 NAMD_close(fd, fname);
01315 }
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333 void Output::scale_vels(Vector *v, int n, Real fact)
01334
01335 {
01336 int i;
01337
01338 for (i=0; i<n; i++)
01339 {
01340 v[i].x *= fact;
01341 v[i].y *= fact;
01342 v[i].z *= fact;
01343 }
01344 }
01345
01346
01347
01348 #ifdef MEM_OPT_VERSION
01350 void ParOutput::velocityMaster(int timestep, int n){
01351 SimParameters *simParams = Node::Object()->simParameters;
01352
01353 if ( timestep >= 0 ) {
01354
01355
01356 if ( simParams->velDcdFrequency &&
01357 ((timestep % simParams->velDcdFrequency) == 0) )
01358 {
01359 output_veldcdfile_master(timestep, n);
01360 }
01361
01362
01363 if ( simParams->restartFrequency &&
01364 ((timestep % simParams->restartFrequency) == 0) )
01365 {
01366 iout << "WRITING VELOCITIES TO RESTART FILE AT STEP "
01367 << timestep << "\n" << endi;
01368 output_restart_velocities_master(timestep, n);
01369 iout << "FINISHED WRITING RESTART VELOCITIES\n" <<endi;
01370 fflush(stdout);
01371 }
01372
01373 }
01374
01375
01376 if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
01377 {
01378 int realstep = ( timestep == FILE_OUTPUT ?
01379 simParams->firstTimestep : simParams->N );
01380 iout << "WRITING VELOCITIES TO OUTPUT FILE AT STEP "
01381 << realstep << "\n" << endi;
01382 fflush(stdout);
01383 output_final_velocities_master(n);
01384 }
01385
01386
01387 if (timestep == END_OF_RUN)
01388 {
01389 if (simParams->velDcdFrequency) output_veldcdfile_master(END_OF_RUN,0);
01390 if (simParams->forceDcdFrequency) output_forcedcdfile_master(END_OF_RUN,0);
01391 }
01392
01393 }
01394
01395
01396 void ParOutput::velocitySlave(int timestep, int fID, int tID, Vector *vecs){
01397 SimParameters *simParams = Node::Object()->simParameters;
01398
01399 if ( timestep >= 0 ) {
01400
01401
01402 if ( simParams->velDcdFrequency &&
01403 ((timestep % simParams->velDcdFrequency) == 0) )
01404 {
01405 output_veldcdfile_slave(timestep, fID, tID, vecs);
01406 }
01407
01408
01409 if ( simParams->restartFrequency &&
01410 ((timestep % simParams->restartFrequency) == 0) )
01411 {
01412 int64 offset = sizeof(int)+sizeof(Vector)*((int64)fID);
01413 output_restart_velocities_slave(timestep, fID, tID, vecs, offset);
01414 }
01415
01416 }
01417
01418
01419 if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
01420 {
01421 int64 offset = sizeof(int)+sizeof(Vector)*((int64)fID);
01422 output_final_velocities_slave(fID, tID, vecs, offset);
01423 }
01424
01425
01426 if (timestep == END_OF_RUN)
01427 {
01428 if (simParams->velDcdFrequency) output_veldcdfile_slave(END_OF_RUN, 0, 0, NULL);
01429 if (simParams->forceDcdFrequency) output_forcedcdfile_slave(END_OF_RUN, 0, 0, NULL);
01430 }
01431 }
01432
01433 void ParOutput::output_veldcdfile_master(int timestep, int n){
01434 int ret_code;
01435 SimParameters *simParams = Node::Object()->simParameters;
01436
01437
01438
01439 if ( timestep == END_OF_RUN ) {
01440 if ( ! veldcdFirst ) {
01441 iout << "CLOSING VELOCITY DCD FILE\n" << endi;
01442 close_dcd_write(veldcdFileID);
01443 } else {
01444 iout << "VELOCITY DCD FILE WAS NOT CREATED\n" << endi;
01445 }
01446 return;
01447 }
01448
01449 if (veldcdFirst)
01450 {
01451
01452 iout << "OPENING VELOCITY DCD FILE\n" << endi;
01453
01454 #ifndef OUTPUT_SINGLE_FILE
01455 #error OUTPUT_SINGLE_FILE not defined!
01456 #endif
01457
01458 #if OUTPUT_SINGLE_FILE
01459 char *veldcdFilename = simParams->velDcdFilename;
01460 #else
01461 char *veldcdFilename = buildFileName(veldcdType);
01462 #endif
01463
01464 veldcdFileID=open_dcd_write(veldcdFilename);
01465
01466 if (veldcdFileID == DCD_FILEEXISTS)
01467 {
01468 char err_msg[257];
01469 sprintf(err_msg, "Velocity DCD file %s already exists!",veldcdFilename);
01470 NAMD_err(err_msg);
01471 }
01472 else if (veldcdFileID < 0)
01473 {
01474 char err_msg[257];
01475 sprintf(err_msg, "Couldn't open velocity DCD file %s",veldcdFilename);
01476 NAMD_err(err_msg);
01477 }
01478
01479 #if !OUTPUT_SINGLE_FILE
01480
01481 int32 tmpInt = OUTPUT_MAGIC_NUMBER;
01482 float tmpFlt = OUTPUT_FILE_VERSION;
01483 NAMD_write(veldcdFileID, (char *) &tmpInt, sizeof(int32));
01484 NAMD_write(veldcdFileID, (char *) &tmpFlt, sizeof(float));
01485 tmpInt = simParams->numoutputprocs;
01486 NAMD_write(veldcdFileID, (char *) &tmpInt, sizeof(int32));
01487 #endif
01488
01489 int NSAVC, NFILE, NPRIV, NSTEP;
01490 NSAVC = simParams->velDcdFrequency;
01491 NPRIV = timestep;
01492 NSTEP = NPRIV - NSAVC;
01493 NFILE = 0;
01494
01495
01496 const int with_unitcell = 0;
01497 ret_code = write_dcdheader(veldcdFileID,
01498 veldcdFilename,
01499 n, NFILE, NPRIV, NSAVC, NSTEP,
01500 simParams->dt/TIMEFACTOR, with_unitcell);
01501
01502
01503 if (ret_code<0)
01504 {
01505 NAMD_err("Writing of velocity DCD header failed!!");
01506 }
01507
01508 #if !OUTPUT_SINGLE_FILE
01509
01510 delete [] veldcdFilename;
01511 #endif
01512
01513 veldcdFirst = FALSE;
01514 }
01515
01516
01517 iout << "WRITING VELOCITIES TO DCD FILE AT STEP "
01518 << timestep << "\n" << endi;
01519 fflush(stdout);
01520
01521
01522
01523
01524
01525 #if OUTPUT_SINGLE_FILE
01526
01527 int totalAtoms = namdMyNode->molecule->numAtoms;
01528 write_dcdstep_par_XYZUnits(veldcdFileID, totalAtoms);
01529 #endif
01530
01531
01532 update_dcdstep_par_header(veldcdFileID);
01533
01534 }
01535
01536 void ParOutput::output_veldcdfile_slave(int timestep, int fID, int tID, Vector *vecs){
01537 int ret_code;
01538 SimParameters *simParams = Node::Object()->simParameters;
01539
01540
01541
01542 if ( timestep == END_OF_RUN ) {
01543 if ( ! veldcdFirst ) {
01544 close_dcd_write(veldcdFileID);
01545 }
01546 #if OUTPUT_SINGLE_FILE
01547 delete [] veldcdX;
01548 delete [] veldcdY;
01549 delete [] veldcdZ;
01550 #endif
01551 return;
01552 }
01553
01554 int parN = tID-fID+1;
01555
01556 if (veldcdFirst)
01557 {
01558
01559 #if OUTPUT_SINGLE_FILE
01560 char *veldcdFilename = namdMyNode->simParams->velDcdFilename;
01561 #else
01562 char *veldcdFilename = buildFileName(veldcdType);
01563 #endif
01564 veldcdFileID=open_dcd_write_par_slave(veldcdFilename);
01565 if(veldcdFileID < 0)
01566 {
01567 char err_msg[257];
01568 sprintf(err_msg, "Couldn't open velocity DCD file %s",veldcdFilename);
01569 NAMD_err(err_msg);
01570 }
01571 #if OUTPUT_SINGLE_FILE
01572
01573
01574
01575
01576 veldcdX = new float[parN];
01577 veldcdY = new float[parN];
01578 veldcdZ = new float[parN];
01579
01580
01581 int skipbytes = get_dcdheader_size();
01582 seek_dcdfile(veldcdFileID, skipbytes, SEEK_SET);
01583 #endif
01584
01585 #if !OUTPUT_SINGLE_FILE
01586 delete [] veldcdFilename;
01587
01588 int32 tmpInt = OUTPUT_MAGIC_NUMBER;
01589 float tmpFlt = OUTPUT_FILE_VERSION;
01590 NAMD_write(veldcdFileID, (char *) &tmpInt, sizeof(int32));
01591 NAMD_write(veldcdFileID, (char *) &tmpFlt, sizeof(float));
01592 NAMD_write(veldcdFileID, (char *) &outputID, sizeof(int));
01593 NAMD_write(veldcdFileID, (char *) &fID, sizeof(int));
01594 NAMD_write(veldcdFileID, (char *) &tID, sizeof(int));
01595 #endif
01596
01597 veldcdFirst = FALSE;
01598 }
01599
01600 #if OUTPUT_SINGLE_FILE
01601
01602
01603
01604 CmiAssert(sizeof(off_t)==8);
01605 int totalAtoms = namdMyNode->molecule->numAtoms;
01606
01607 for(int i=0; i<parN; i++){
01608 veldcdX[i] = vecs[i].x;
01609 veldcdY[i] = vecs[i].y;
01610 veldcdZ[i] = vecs[i].z;
01611 }
01612
01613 write_dcdstep_par_slave(veldcdFileID, fID, tID, totalAtoms, veldcdX, veldcdY, veldcdZ);
01614
01615
01616
01617 int atomsRemains = (totalAtoms-1)-(tID+1)+1;
01618 off_t offset = ((off_t)atomsRemains)*sizeof(float)+1*sizeof(int);
01619 seek_dcdfile(veldcdFileID, offset, SEEK_CUR);
01620
01621 #else
01622
01623 NAMD_write(veldcdFileID, (char *)×tep, sizeof(int));
01624
01625 NAMD_write(veldcdFileID, (char *)vecs, sizeof(Vector)*parN);
01626 #endif
01627 }
01628
01629 void ParOutput::output_restart_velocities_master(int timestep, int n){
01630 #if OUTPUT_SINGLE_FILE
01631 char timestepstr[20];
01632
01633 int baselen = strlen(namdMyNode->simParams->restartFilename);
01634 char *restart_name = new char[baselen+26];
01635
01636 strcpy(restart_name, namdMyNode->simParams->restartFilename);
01637 if ( namdMyNode->simParams->restartSave ) {
01638 sprintf(timestepstr,".%d",timestep);
01639 strcat(restart_name, timestepstr);
01640 }
01641 strcat(restart_name, ".vel");
01642 #else
01643 char *restart_name = NULL;
01644 if ( namdMyNode->simParams->restartSave )
01645 restart_name = buildFileName(velType);
01646 else
01647 restart_name = buildFileName(velType,timestep);
01648 #endif
01649
01650 NAMD_backup_file(restart_name,".old");
01651
01652
01653 write_binary_file_master(restart_name, n);
01654
01655 delete [] restart_name;
01656 }
01657
01658 void ParOutput::output_restart_velocities_slave(int timestep, int fID, int tID, Vector *vecs, int64 offset){
01659 #if OUTPUT_SINGLE_FILE
01660 char timestepstr[20];
01661
01662 int baselen = strlen(namdMyNode->simParams->restartFilename);
01663 char *restart_name = new char[baselen+26];
01664
01665 strcpy(restart_name, namdMyNode->simParams->restartFilename);
01666 if ( namdMyNode->simParams->restartSave ) {
01667 sprintf(timestepstr,".%d",timestep);
01668 strcat(restart_name, timestepstr);
01669 }
01670 strcat(restart_name, ".vel");
01671 #else
01672 char *restart_name = NULL;
01673 if ( namdMyNode->simParams->restartSave )
01674 restart_name = buildFileName(velType);
01675 else
01676 restart_name = buildFileName(velType,timestep);
01677
01678 NAMD_backup_file(restart_name,".old");
01679 #endif
01680
01681
01682 write_binary_file_slave(restart_name, fID, tID, vecs, offset);
01683
01684 delete [] restart_name;
01685 }
01686
01687 void ParOutput::output_final_velocities_master(int n){
01688 #if OUTPUT_SINGLE_FILE
01689 char *output_name = new char[strlen(namdMyNode->simParams->outputFilename)+8];
01690
01691 strcpy(output_name, namdMyNode->simParams->outputFilename);
01692 strcat(output_name, ".vel");
01693 #else
01694 char *output_name = buildFileName(velType);
01695 #endif
01696
01697 NAMD_backup_file(output_name);
01698
01699
01700 write_binary_file_master(output_name, n);
01701 }
01702
01703 void ParOutput::output_final_velocities_slave(int fID, int tID, Vector *vecs, int64 offset){
01704 #if OUTPUT_SINGLE_FILE
01705 char *output_name = new char[strlen(namdMyNode->simParams->outputFilename)+8];
01706
01707 strcpy(output_name, namdMyNode->simParams->outputFilename);
01708 strcat(output_name, ".vel");
01709 #else
01710 char *output_name = buildFileName(velType);
01711 NAMD_backup_file(output_name);
01712 #endif
01713
01714
01715 write_binary_file_slave(output_name, fID, tID, vecs, offset);
01716
01717 delete [] output_name;
01718 }
01719
01720 void ParOutput::write_binary_file_master(char *fname, int n){
01721 char errmsg[256];
01722 int fd;
01723 int32 n32 = n;
01724
01725 fd = NAMD_open(fname);
01726
01727 sprintf(errmsg, "Error on write to binary file %s", fname);
01728
01729 #if !OUTPUT_SINGLE_FILE
01730
01731 int32 tmpInt = OUTPUT_MAGIC_NUMBER;
01732 float tmpFlt = OUTPUT_FILE_VERSION;
01733 NAMD_write(fd, (char *) &tmpInt, sizeof(int32), errmsg);
01734 NAMD_write(fd, (char *) &tmpFlt, sizeof(float), errmsg);
01735 tmpInt = namdMyNode->simParams->numoutputprocs;
01736 NAMD_write(fd, (char *) &tmpInt, sizeof(int32), errmsg);
01737 #endif
01738
01739
01740 NAMD_write(fd, (char *) &n32, sizeof(int32), errmsg);
01741
01742 NAMD_close(fd, fname);
01743 }
01744
01745 void ParOutput::write_binary_file_slave(char *fname, int fID, int tID, Vector *vecs, int64 offset){
01746 char errmsg[256];
01747
01748 #if OUTPUT_SINGLE_FILE
01749
01750 FILE *ofp = fopen(fname, "rb+");
01751 if ( ! ofp ) {
01752 sprintf(errmsg, "Error on opening binary file %s", fname);
01753 NAMD_err(errmsg);
01754 }
01755
01756
01757 #ifdef WIN32
01758 if ( _fseeki64(ofp, offset, SEEK_SET) )
01759 #else
01760 if ( fseeko(ofp, offset, SEEK_SET) )
01761 #endif
01762 {
01763 sprintf(errmsg, "Error on seeking binary file %s", fname);
01764 NAMD_err(errmsg);
01765 }
01766 #else
01767
01768 FILE *ofp = fopen(fname, "wb+");
01769 if ( ! ofp ) {
01770 sprintf(errmsg, "Error on opening binary file %s", fname);
01771 NAMD_err(errmsg);
01772 }
01773
01774
01775 int32 tmpInt = OUTPUT_MAGIC_NUMBER;
01776 float tmpFlt = OUTPUT_FILE_VERSION;
01777 fwrite(&tmpInt, sizeof(int32), 1, ofp);
01778 fwrite(&tmpFlt, sizeof(float), 1, ofp);
01779 fwrite(&outputID, sizeof(int), 1, ofp);
01780 fwrite(&fID, sizeof(int), 1, ofp);
01781 fwrite(&tID, sizeof(int), 1, ofp);
01782 #endif
01783
01784 int parN = tID-fID+1;
01785 if ( fwrite(vecs, sizeof(Vector), parN, ofp) != parN ) {
01786 sprintf(errmsg, "Error on writing to binary file %s", fname);
01787 NAMD_err(errmsg);
01788 }
01789
01790 if ( fclose(ofp) ) {
01791 sprintf(errmsg, "Error on closing binary file %s", fname);
01792 NAMD_err(errmsg);
01793 }
01794 }
01796
01797
01799 void ParOutput::forceMaster(int timestep, int n){
01800 SimParameters *simParams = Node::Object()->simParameters;
01801
01802 if ( timestep >= 0 ) {
01803
01804
01805 if ( simParams->forceDcdFrequency &&
01806 ((timestep % simParams->forceDcdFrequency) == 0) )
01807 {
01808 output_forcedcdfile_master(timestep, n);
01809 }
01810
01811 }
01812
01813
01814 if (timestep == FORCE_OUTPUT)
01815 {
01816 int realstep = simParams->firstTimestep;
01817 iout << "WRITING FORCES TO OUTPUT FILE AT STEP "
01818 << realstep << "\n" << endi;
01819 fflush(stdout);
01820 output_forces_master(n);
01821 }
01822
01823
01824 }
01825
01826
01827 void ParOutput::forceSlave(int timestep, int fID, int tID, Vector *vecs){
01828 SimParameters *simParams = Node::Object()->simParameters;
01829
01830 if ( timestep >= 0 ) {
01831
01832
01833 if ( simParams->forceDcdFrequency &&
01834 ((timestep % simParams->forceDcdFrequency) == 0) )
01835 {
01836 output_forcedcdfile_slave(timestep, fID, tID, vecs);
01837 }
01838
01839 }
01840
01841
01842 if (timestep == FORCE_OUTPUT)
01843 {
01844 int64 offset = sizeof(int)+sizeof(Vector)*((int64)fID);
01845 output_forces_slave(fID, tID, vecs, offset);
01846 }
01847
01848
01849 }
01850
01851 void ParOutput::output_forcedcdfile_master(int timestep, int n){
01852 int ret_code;
01853 SimParameters *simParams = Node::Object()->simParameters;
01854
01855
01856
01857 if ( timestep == END_OF_RUN ) {
01858 if ( ! forcedcdFirst ) {
01859 iout << "CLOSING FORCE DCD FILE\n" << endi;
01860 close_dcd_write(forcedcdFileID);
01861 } else {
01862 iout << "FORCE DCD FILE WAS NOT CREATED\n" << endi;
01863 }
01864 return;
01865 }
01866
01867 if (forcedcdFirst)
01868 {
01869
01870 iout << "OPENING FORCE DCD FILE\n" << endi;
01871
01872 #if OUTPUT_SINGLE_FILE
01873 char *forcedcdFilename = simParams->forceDcdFilename;
01874 #else
01875 char *forcedcdFilename = buildFileName(forcedcdType);
01876 #endif
01877
01878 forcedcdFileID=open_dcd_write(forcedcdFilename);
01879
01880 if (forcedcdFileID == DCD_FILEEXISTS)
01881 {
01882 char err_msg[257];
01883 sprintf(err_msg, "Force DCD file %s already exists!",forcedcdFilename);
01884 NAMD_err(err_msg);
01885 }
01886 else if (forcedcdFileID < 0)
01887 {
01888 char err_msg[257];
01889 sprintf(err_msg, "Couldn't open force DCD file %s",forcedcdFilename);
01890 NAMD_err(err_msg);
01891 }
01892
01893 #if !OUTPUT_SINGLE_FILE
01894
01895 int32 tmpInt = OUTPUT_MAGIC_NUMBER;
01896 float tmpFlt = OUTPUT_FILE_VERSION;
01897 NAMD_write(forcedcdFileID, (char *) &tmpInt, sizeof(int32));
01898 NAMD_write(forcedcdFileID, (char *) &tmpFlt, sizeof(float));
01899 tmpInt = simParams->numoutputprocs;
01900 NAMD_write(forcedcdFileID, (char *) &tmpInt, sizeof(int32));
01901 #endif
01902
01903 int NSAVC, NFILE, NPRIV, NSTEP;
01904 NSAVC = simParams->forceDcdFrequency;
01905 NPRIV = timestep;
01906 NSTEP = NPRIV - NSAVC;
01907 NFILE = 0;
01908
01909
01910 const int with_unitcell = 0;
01911 ret_code = write_dcdheader(forcedcdFileID,
01912 forcedcdFilename,
01913 n, NFILE, NPRIV, NSAVC, NSTEP,
01914 simParams->dt/TIMEFACTOR, with_unitcell);
01915
01916
01917 if (ret_code<0)
01918 {
01919 NAMD_err("Writing of force DCD header failed!!");
01920 }
01921
01922 #if !OUTPUT_SINGLE_FILE
01923
01924 delete [] forcedcdFilename;
01925 #endif
01926
01927 forcedcdFirst = FALSE;
01928 }
01929
01930
01931 iout << "WRITING FORCES TO DCD FILE AT STEP "
01932 << timestep << "\n" << endi;
01933 fflush(stdout);
01934
01935
01936
01937
01938
01939 #if OUTPUT_SINGLE_FILE
01940
01941 int totalAtoms = namdMyNode->molecule->numAtoms;
01942 write_dcdstep_par_XYZUnits(forcedcdFileID, totalAtoms);
01943 #endif
01944
01945
01946 update_dcdstep_par_header(forcedcdFileID);
01947
01948 }
01949
01950 void ParOutput::output_forcedcdfile_slave(int timestep, int fID, int tID, Vector *vecs){
01951 int ret_code;
01952 SimParameters *simParams = Node::Object()->simParameters;
01953
01954
01955
01956 if ( timestep == END_OF_RUN ) {
01957 if ( ! forcedcdFirst ) {
01958 close_dcd_write(forcedcdFileID);
01959 }
01960 #if OUTPUT_SINGLE_FILE
01961 delete [] forcedcdX;
01962 delete [] forcedcdY;
01963 delete [] forcedcdZ;
01964 #endif
01965 return;
01966 }
01967
01968 int parN = tID-fID+1;
01969
01970 if (forcedcdFirst)
01971 {
01972
01973 #if OUTPUT_SINGLE_FILE
01974 char *forcedcdFilename = namdMyNode->simParams->forceDcdFilename;
01975 #else
01976 char *forcedcdFilename = buildFileName(forcedcdType);
01977 #endif
01978 forcedcdFileID=open_dcd_write_par_slave(forcedcdFilename);
01979 if(forcedcdFileID < 0)
01980 {
01981 char err_msg[257];
01982 sprintf(err_msg, "Couldn't open force DCD file %s",forcedcdFilename);
01983 NAMD_err(err_msg);
01984 }
01985 #if OUTPUT_SINGLE_FILE
01986
01987
01988
01989
01990 forcedcdX = new float[parN];
01991 forcedcdY = new float[parN];
01992 forcedcdZ = new float[parN];
01993
01994
01995 int skipbytes = get_dcdheader_size();
01996 seek_dcdfile(forcedcdFileID, skipbytes, SEEK_SET);
01997 #endif
01998
01999 #if !OUTPUT_SINGLE_FILE
02000 delete [] forcedcdFilename;
02001
02002 int32 tmpInt = OUTPUT_MAGIC_NUMBER;
02003 float tmpFlt = OUTPUT_FILE_VERSION;
02004 NAMD_write(forcedcdFileID, (char *) &tmpInt, sizeof(int32));
02005 NAMD_write(forcedcdFileID, (char *) &tmpFlt, sizeof(float));
02006 NAMD_write(forcedcdFileID, (char *) &outputID, sizeof(int));
02007 NAMD_write(forcedcdFileID, (char *) &fID, sizeof(int));
02008 NAMD_write(forcedcdFileID, (char *) &tID, sizeof(int));
02009 #endif
02010
02011 forcedcdFirst = FALSE;
02012 }
02013
02014 #if OUTPUT_SINGLE_FILE
02015
02016
02017
02018 CmiAssert(sizeof(off_t)==8);
02019 int totalAtoms = namdMyNode->molecule->numAtoms;
02020
02021 for(int i=0; i<parN; i++){
02022 forcedcdX[i] = vecs[i].x;
02023 forcedcdY[i] = vecs[i].y;
02024 forcedcdZ[i] = vecs[i].z;
02025 }
02026
02027 write_dcdstep_par_slave(forcedcdFileID, fID, tID, totalAtoms, forcedcdX, forcedcdY, forcedcdZ);
02028
02029
02030 int atomsRemains = (totalAtoms-1)-(tID+1)+1;
02031 off_t offset = ((off_t)atomsRemains)*sizeof(float)+1*sizeof(int);
02032 seek_dcdfile(forcedcdFileID, offset, SEEK_CUR);
02033 #else
02034
02035 NAMD_write(forcedcdFileID, (char *)×tep, sizeof(int));
02036
02037 NAMD_write(forcedcdFileID, (char *)vecs, sizeof(Vector)*parN);
02038 #endif
02039 }
02040
02041 void ParOutput::output_forces_master(int n){
02042 #if OUTPUT_SINGLE_FILE
02043 char *output_name = new char[strlen(namdMyNode->simParams->outputFilename)+8];
02044
02045 strcpy(output_name, namdMyNode->simParams->outputFilename);
02046 strcat(output_name, ".force");
02047 #else
02048 char *output_name = buildFileName(forceType);
02049 #endif
02050
02051 NAMD_backup_file(output_name);
02052
02053
02054 write_binary_file_master(output_name, n);
02055 }
02056
02057 void ParOutput::output_forces_slave(int fID, int tID, Vector *vecs, int64 offset){
02058 #if OUTPUT_SINGLE_FILE
02059 char *output_name = new char[strlen(namdMyNode->simParams->outputFilename)+8];
02060
02061 strcpy(output_name, namdMyNode->simParams->outputFilename);
02062 strcat(output_name, ".force");
02063 #else
02064 char *output_name = buildFileName(forceType);
02065 NAMD_backup_file(output_name);
02066 #endif
02067
02068
02069 write_binary_file_slave(output_name, fID, tID, vecs, offset);
02070
02071 delete [] output_name;
02072 }
02074
02075
02077 void ParOutput::coordinateMaster(int timestep, int n, Lattice &lat){
02078 SimParameters *simParams = Node::Object()->simParameters;
02079
02080 if ( timestep >= 0 ) {
02081
02082 if ( simParams->dcdFrequency &&
02083 ((timestep % simParams->dcdFrequency) == 0) )
02084 {
02085 output_dcdfile_master(timestep, n,
02086 simParams->dcdUnitCell ? &lat : NULL);
02087 }
02088
02089
02090 if ( simParams->restartFrequency &&
02091 ((timestep % simParams->restartFrequency) == 0) )
02092 {
02093 iout << "WRITING COORDINATES TO RESTART FILE AT STEP "
02094 << timestep << "\n" << endi;
02095 output_restart_coordinates_master(timestep, n);
02096 iout << "FINISHED WRITING RESTART COORDINATES\n" <<endi;
02097 fflush(stdout);
02098 }
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111 }
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123 if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
02124 {
02125 int realstep = ( timestep == FILE_OUTPUT ?
02126 simParams->firstTimestep : simParams->N );
02127 iout << "WRITING COORDINATES TO OUTPUT FILE AT STEP "
02128 << realstep << "\n" << endi;
02129 fflush(stdout);
02130 output_final_coordinates_master(n);
02131 }
02132
02133
02134 if (timestep == END_OF_RUN)
02135 {
02136 if (simParams->dcdFrequency) output_dcdfile_master(END_OF_RUN,0,NULL);
02137 }
02138 }
02139
02140 void ParOutput::coordinateSlave(int timestep, int fID, int tID, Vector *vecs, FloatVector *fvecs){
02141 SimParameters *simParams = Node::Object()->simParameters;
02142
02143 if ( timestep >= 0 ) {
02144
02145 if ( simParams->dcdFrequency &&
02146 ((timestep % simParams->dcdFrequency) == 0) )
02147 {
02148 output_dcdfile_slave(timestep, fID, tID, fvecs);
02149 }
02150
02151
02152 if ( simParams->restartFrequency &&
02153 ((timestep % simParams->restartFrequency) == 0) )
02154 {
02155 int64 offset = sizeof(int)+sizeof(Vector)*((int64)fID);
02156 output_restart_coordinates_slave(timestep, fID, tID, vecs, offset);
02157 }
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170 }
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182 if (timestep == FILE_OUTPUT || timestep == END_OF_RUN)
02183 {
02184 int64 offset = sizeof(int)+sizeof(Vector)*((int64)fID);
02185 output_final_coordinates_slave(fID, tID, vecs, offset);
02186 }
02187
02188
02189 if (timestep == END_OF_RUN)
02190 {
02191 if (simParams->dcdFrequency) output_dcdfile_slave(END_OF_RUN,0,0,NULL);
02192 }
02193 }
02194
02195 void ParOutput::output_dcdfile_master(int timestep, int n, const Lattice *lattice){
02196 int ret_code;
02197 SimParameters *simParams = namdMyNode->simParams;
02198
02199
02200
02201 if ( timestep == END_OF_RUN ) {
02202 if ( ! dcdFirst ) {
02203 iout << "CLOSING COORDINATE DCD FILE\n" << endi;
02204 close_dcd_write(dcdFileID);
02205 } else {
02206 iout << "COORDINATE DCD FILE WAS NOT CREATED\n" << endi;
02207 }
02208 return;
02209 }
02210
02211 if (dcdFirst)
02212 {
02213
02214 iout << "OPENING COORDINATE DCD FILE\n" << endi;
02215
02216 #if OUTPUT_SINGLE_FILE
02217 char *dcdFilename = simParams->dcdFilename;
02218 #else
02219 char *dcdFilename = buildFileName(dcdType);
02220 #endif
02221
02222
02223 dcdFileID=open_dcd_write(dcdFilename);
02224
02225 if (dcdFileID == DCD_FILEEXISTS)
02226 {
02227 char err_msg[257];
02228 sprintf(err_msg, "DCD file %s already exists!!",dcdFilename);
02229 NAMD_err(err_msg);
02230 }
02231 else if (dcdFileID < 0)
02232 {
02233 char err_msg[257];
02234 sprintf(err_msg, "Couldn't open DCD file %s",dcdFilename);
02235 NAMD_err(err_msg);
02236 }
02237
02238 #if !OUTPUT_SINGLE_FILE
02239
02240 int32 tmpInt = OUTPUT_MAGIC_NUMBER;
02241 float tmpFlt = OUTPUT_FILE_VERSION;
02242 NAMD_write(dcdFileID, (char *) &tmpInt, sizeof(int32));
02243 NAMD_write(dcdFileID, (char *) &tmpFlt, sizeof(float));
02244 tmpInt = simParams->numoutputprocs;
02245 NAMD_write(dcdFileID, (char *) &tmpInt, sizeof(int32));
02246 #endif
02247
02248 int NSAVC, NFILE, NPRIV, NSTEP;
02249 NSAVC = simParams->dcdFrequency;
02250 NPRIV = timestep;
02251 NSTEP = NPRIV - NSAVC;
02252 NFILE = 0;
02253
02254
02255 ret_code = write_dcdheader(dcdFileID,
02256 dcdFilename,
02257 n, NFILE, NPRIV, NSAVC, NSTEP,
02258 simParams->dt/TIMEFACTOR, lattice != NULL);
02259
02260
02261 if (ret_code<0)
02262 {
02263 NAMD_err("Writing of DCD header failed!!");
02264 }
02265
02266 #if !OUTPUT_SINGLE_FILE
02267
02268 delete [] dcdFilename;
02269 #endif
02270
02271 dcdFirst = FALSE;
02272 }
02273
02274
02275 iout << "WRITING COORDINATES TO DCD FILE AT STEP "
02276 << timestep << "\n" << endi;
02277 fflush(stdout);
02278
02279
02280
02281
02282
02283
02284
02285 if (lattice) {
02286 double unitcell[6];
02287 lattice_to_unitcell(lattice,unitcell);
02288 write_dcdstep_par_cell(dcdFileID, unitcell);
02289 }
02290
02291 #if OUTPUT_SINGLE_FILE
02292
02293 int totalAtoms = namdMyNode->molecule->numAtoms;
02294 write_dcdstep_par_XYZUnits(dcdFileID, totalAtoms);
02295 #endif
02296
02297
02298 update_dcdstep_par_header(dcdFileID);
02299 }
02300 void ParOutput::output_dcdfile_slave(int timestep, int fID, int tID, FloatVector *fvecs){
02301 int ret_code;
02302 SimParameters *simParams = Node::Object()->simParameters;
02303
02304
02305
02306 if ( timestep == END_OF_RUN ) {
02307 if ( ! dcdFirst ) {
02308 close_dcd_write(dcdFileID);
02309 }
02310 #if OUTPUT_SINGLE_FILE
02311 delete [] dcdX;
02312 delete [] dcdY;
02313 delete [] dcdZ;
02314 #endif
02315 return;
02316 }
02317
02318 int parN = tID-fID+1;
02319
02320 if (dcdFirst)
02321 {
02322
02323 #if OUTPUT_SINGLE_FILE
02324 char *dcdFilename = simParams->dcdFilename;
02325 #else
02326 char *dcdFilename = buildFileName(dcdType);
02327 #endif
02328 dcdFileID=open_dcd_write_par_slave(dcdFilename);
02329 if(dcdFileID < 0)
02330 {
02331 char err_msg[257];
02332 sprintf(err_msg, "Couldn't open DCD file %s", dcdFilename);
02333 NAMD_err(err_msg);
02334 }
02335
02336 #if OUTPUT_SINGLE_FILE
02337 dcdX = new float[parN];
02338 dcdY = new float[parN];
02339 dcdZ = new float[parN];
02340
02341
02342 int skipbytes = get_dcdheader_size();
02343 if(simParams->dcdUnitCell) {
02344 skipbytes += sizeof(int)*2 + 6*sizeof(double);
02345 }
02346 seek_dcdfile(dcdFileID, skipbytes, SEEK_SET);
02347 #endif
02348
02349 #if !OUTPUT_SINGLE_FILE
02350 delete [] dcdFilename;
02351
02352
02353 int32 tmpInt = OUTPUT_MAGIC_NUMBER;
02354 float tmpFlt = OUTPUT_FILE_VERSION;
02355 NAMD_write(dcdFileID, (char *) &tmpInt, sizeof(int32));
02356 NAMD_write(dcdFileID, (char *) &tmpFlt, sizeof(float));
02357 NAMD_write(dcdFileID, (char *) &outputID, sizeof(int));
02358 NAMD_write(dcdFileID, (char *) &fID, sizeof(int));
02359 NAMD_write(dcdFileID, (char *) &tID, sizeof(int));
02360 #endif
02361 dcdFirst = FALSE;
02362 }
02363
02364 #if OUTPUT_SINGLE_FILE
02365
02366
02367
02368 CmiAssert(sizeof(off_t)==8);
02369 int totalAtoms = namdMyNode->molecule->numAtoms;
02370
02371 for(int i=0; i<parN; i++){
02372 dcdX[i] = fvecs[i].x;
02373 dcdY[i] = fvecs[i].y;
02374 dcdZ[i] = fvecs[i].z;
02375 }
02376
02377 write_dcdstep_par_slave(dcdFileID, fID, tID, totalAtoms, dcdX, dcdY, dcdZ);
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389 int atomsRemains = (totalAtoms-1)-(tID+1)+1;
02390 off_t offset = ((off_t)atomsRemains)*sizeof(float)+1*sizeof(int);
02391
02392 if(simParams->dcdUnitCell) {
02393 offset += sizeof(int)*2 + 6*sizeof(double);
02394 }
02395 seek_dcdfile(dcdFileID, offset, SEEK_CUR);
02396 #else
02397
02398 NAMD_write(dcdFileID, (char *)×tep, sizeof(int));
02399
02400 NAMD_write(dcdFileID, (char *)fvecs, sizeof(FloatVector)*parN);
02401 #endif
02402 }
02403
02404 void ParOutput::output_restart_coordinates_master(int timestep, int n){
02405 #if OUTPUT_SINGLE_FILE
02406 char timestepstr[20];
02407
02408 int baselen = strlen(namdMyNode->simParams->restartFilename);
02409 char *restart_name = new char[baselen+26];
02410
02411 strcpy(restart_name, namdMyNode->simParams->restartFilename);
02412 if ( namdMyNode->simParams->restartSave ) {
02413 sprintf(timestepstr,".%d",timestep);
02414 strcat(restart_name, timestepstr);
02415 }
02416 strcat(restart_name, ".coor");
02417 #else
02418 char *restart_name = NULL;
02419 if ( namdMyNode->simParams->restartSave )
02420 restart_name = buildFileName(coorType);
02421 else
02422 restart_name = buildFileName(coorType,timestep);
02423 #endif
02424
02425 NAMD_backup_file(restart_name,".old");
02426
02427
02428 write_binary_file_master(restart_name, n);
02429
02430 delete [] restart_name;
02431 }
02432 void ParOutput::output_restart_coordinates_slave(int timestep, int fID, int tID, Vector *vecs, int64 offset){
02433 #if OUTPUT_SINGLE_FILE
02434 char timestepstr[20];
02435
02436 int baselen = strlen(namdMyNode->simParams->restartFilename);
02437 char *restart_name = new char[baselen+26];
02438
02439 strcpy(restart_name, namdMyNode->simParams->restartFilename);
02440 if ( namdMyNode->simParams->restartSave ) {
02441 sprintf(timestepstr,".%d",timestep);
02442 strcat(restart_name, timestepstr);
02443 }
02444 strcat(restart_name, ".coor");
02445 #else
02446 char *restart_name = NULL;
02447 if ( namdMyNode->simParams->restartSave )
02448 restart_name = buildFileName(coorType);
02449 else
02450 restart_name = buildFileName(coorType,timestep);
02451
02452 NAMD_backup_file(restart_name,".old");
02453 #endif
02454
02455
02456 write_binary_file_slave(restart_name, fID, tID, vecs, offset);
02457
02458 delete [] restart_name;
02459 }
02460
02461 void ParOutput::output_final_coordinates_master(int n){
02462 #if OUTPUT_SINGLE_FILE
02463 char *output_name = new char[strlen(namdMyNode->simParams->outputFilename)+8];
02464
02465
02466 strcpy(output_name, namdMyNode->simParams->outputFilename);
02467 strcat(output_name, ".coor");
02468 #else
02469 char *output_name = buildFileName(coorType);
02470 #endif
02471
02472 NAMD_backup_file(output_name);
02473
02474
02475 write_binary_file_master(output_name, n);
02476
02477 delete [] output_name;
02478 }
02479 void ParOutput::output_final_coordinates_slave(int fID, int tID, Vector *vecs, int64 offset){
02480 #if OUTPUT_SINGLE_FILE
02481 char *output_name = new char[strlen(namdMyNode->simParams->outputFilename)+8];
02482
02483
02484 strcpy(output_name, namdMyNode->simParams->outputFilename);
02485 strcat(output_name, ".coor");
02486 #else
02487 char *output_name = buildFileName(coorType);
02488 NAMD_backup_file(output_name);
02489 #endif
02490
02491
02492 write_binary_file_slave(output_name, fID, tID, vecs, offset);
02493
02494 delete [] output_name;
02495 }
02497
02499 #if !OUTPUT_SINGLE_FILE
02500 char *ParOutput::buildFileName(OUTPUTFILETYPE type, int timestep){
02501 char *filename = NULL;
02502 const char *typeName = NULL;
02503 switch(type) {
02504 case dcdType:
02505 typeName = "dcd";
02506 break;
02507 case forcedcdType:
02508 typeName = "forcedcd";
02509 break;
02510 case veldcdType:
02511 typeName = "veldcd";
02512 break;
02513 case coorType:
02514 typeName = "coor";
02515 break;
02516 case forceType:
02517 typeName = "force";
02518 break;
02519 case velType:
02520 typeName = "vel";
02521 break;
02522 default:
02523 typeName = "invalid";
02524 break;
02525 }
02526 int baselen = strlen(namdMyNode->simParams->outputFilename);
02527 filename = new char[baselen+32];
02528 memset(filename, 0, baselen+32);
02529
02530 #if 0
02531 strcpy(filename, namdMyNode->simParams->outputFilename);
02532
02533
02534 if(access(filename, F_OK)!=0) {
02535 int ret = MKDIR(filename);
02536 if(ret!=0) {
02537 char errmsg[512];
02538 sprintf(errmsg, "Error in creating top-level directory %s!", filename);
02539 NAMD_err(errmsg);
02540 }
02541 }
02542
02543 strcat(filename, PATHSEPSTR);
02544 strcat(filename, typeName);
02545
02546
02547 if(access(filename, F_OK)!=0) {
02548 int ret = MKDIR(filename);
02549 if(ret!=0) {
02550 char errmsg[512];
02551 sprintf(errmsg, "Error in creating middle-level directory %s!", filename);
02552 NAMD_err(errmsg);
02553 }
02554 }
02555 #else
02556 sprintf(filename, "%s%s%s", namdMyNode->simParams->outputFilename, PATHSEPSTR, typeName);
02557 #endif
02558
02559 char tmpstr[20];
02560 if(outputID == -1) {
02561
02562 if(timestep!=-9999) {
02563
02564 sprintf(tmpstr, "%smeta.%d", PATHSEPSTR, timestep);
02565 }else{
02566 sprintf(tmpstr, "%smeta", PATHSEPSTR);
02567 }
02568 }else{
02569
02570 sprintf(tmpstr, "%s%d", PATHSEPSTR, outputID);
02571 strcat(filename, tmpstr);
02572 #if 0
02573 if(access(filename, F_OK)!=0) {
02574 int ret = MKDIR(filename);
02575 if(ret!=0) {
02576 char errmsg[512];
02577 sprintf(errmsg, "Error in creating last-level directory %s!", filename);
02578 NAMD_err(errmsg);
02579 }
02580 }
02581 #endif
02582 if(timestep!=-9999) {
02583
02584 sprintf(tmpstr, "%s%s_%d.%d", PATHSEPSTR,typeName,outputID,timestep);
02585 }else{
02586 sprintf(tmpstr,"%s%s_%d", PATHSEPSTR,typeName,outputID);
02587 }
02588 }
02589
02590 strcat(filename, tmpstr);
02591 return filename;
02592 }
02593 #endif
02595 #endif