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