int write_traj(FILE *log,t_commrec *cr, char *traj,t_nsborder *nsb, int step,real t,real lambda,t_nrnb nrnb[], int natoms,rvec *xx,rvec *vv,rvec *ff,matrix box) { static int fp=-1; if ((fp == -1) && MASTER(cr)) { #ifdef DEBUG fprintf(log,"Going to open trajectory file: %s\n",traj); #endif fp = open_trn(traj,"w"); } #define MX(xvf) moveit(log,cr->left,cr->right,#xvf,xvf,nsb) if (cr->nnodes > 1) { MX(xx); MX(vv); MX(ff); } if ((xx || vv || ff) && MASTER(cr)) { fwrite_trn(fp,step,t,lambda,box,natoms,xx,vv,ff); gmx_fio_flush(fp); } return fp; }
int write_xtc(int fp, int natoms,int step,real time, matrix box,rvec *x,real prec) { int magic_number = XTC_MAGIC; XDR *xd; bool bDum; int bOK; xd = gmx_fio_getxdr(fp); /* write magic number and xtc identidier */ if (xtc_header(xd,&magic_number,&natoms,&step,&time,FALSE,&bDum) == 0) { return 0; } /* write data */ bOK = xtc_coord(xd,&natoms,box,x,&prec,FALSE); /* bOK will be 1 if writing went well */ if(bOK) { if(gmx_fio_flush(fp) !=0) { bOK = 0; } } return bOK; /* 0 if bad, 1 if writing went well */ }
int gmx_fio_get_output_file_positions(gmx_file_position_t **p_outputfiles, int *p_nfiles) { int i,nfiles,rc,nalloc; int pos_hi,pos_lo; long pos; gmx_file_position_t * outputfiles; char buf[STRLEN]; nfiles = 0; nalloc = 100; snew(outputfiles,nalloc); for(i=0; i<nFIO; i++) { /* Skip the checkpoint files themselves, since they could be open when we call this routine... */ if(FIO[i].bOpen && !FIO[i].bRead && !FIO[i].bStdio && FIO[i].iFTP!=efCPT) { /* This is an output file currently open for writing, add it */ if(nfiles == nalloc) { nalloc += 100; srenew(outputfiles,nalloc); } strncpy(outputfiles[nfiles].filename,FIO[i].fn,STRLEN-1); /* Flush the file, so we are sure it is written */ if (gmx_fio_flush(i) != 0) { sprintf(buf,"Cannot write file '%s'; maybe you are out of disk space or quota?",FIO[i].fn); gmx_file(buf); } /* We cannot count on XDR being able to write 64-bit integers, so separate into high/low 32-bit values. * In case the filesystem has 128-bit offsets we only care about the first 64 bits - we'll have to fix * this when exabyte-size output files are common... */ #ifdef HAVE_FSEEKO outputfiles[nfiles].offset = ftello(FIO[i].fp); #else outputfiles[nfiles].offset = ftell(FIO[i].fp); #endif nfiles++; } } *p_nfiles = nfiles; *p_outputfiles = outputfiles; return 0; }
int write_xtc(t_fileio *fio, int natoms, int64_t step, real time, const rvec *box, const rvec *x, real prec) { int magic_number = XTC_MAGIC; XDR *xd; gmx_bool bDum; int bOK; if (!fio) { /* This means the fio object is not being used, e.g. because we are actually writing TNG output. We still have to return a pseudo-success value, to keep some callers happy. */ return 1; } xd = gmx_fio_getxdr(fio); /* write magic number and xtc identidier */ if (xtc_header(xd, &magic_number, &natoms, &step, &time, FALSE, &bDum) == 0) { return 0; } /* write data */ bOK = xtc_coord(xd, &natoms, const_cast<rvec *>(box), const_cast<rvec *>(x), &prec, FALSE); /* bOK will be 1 if writing went well */ if (bOK) { if (gmx_fio_flush(fio) != 0) { bOK = 0; } } return bOK; /* 0 if bad, 1 if writing went well */ }
void mdoutf_write_to_trajectory_files(FILE *fplog, t_commrec *cr, gmx_mdoutf_t of, int mdof_flags, gmx_mtop_t *top_global, gmx_int64_t step, double t, t_state *state_local, t_state *state_global, rvec *f_local, rvec *f_global) { rvec *local_v; rvec *global_v; /* MRS -- defining these variables is to manage the difference * between half step and full step velocities, but there must be a better way . . . */ local_v = state_local->v; global_v = state_global->v; if (DOMAINDECOMP(cr)) { if (mdof_flags & MDOF_CPT) { dd_collect_state(cr->dd, state_local, state_global); } else { if (mdof_flags & (MDOF_X | MDOF_X_COMPRESSED)) { dd_collect_vec(cr->dd, state_local, state_local->x, state_global->x); } if (mdof_flags & MDOF_V) { dd_collect_vec(cr->dd, state_local, local_v, global_v); } } if (mdof_flags & MDOF_F) { dd_collect_vec(cr->dd, state_local, f_local, f_global); } } else { if (mdof_flags & MDOF_CPT) { /* All pointers in state_local are equal to state_global, * but we need to copy the non-pointer entries. */ state_global->lambda = state_local->lambda; state_global->veta = state_local->veta; state_global->vol0 = state_local->vol0; copy_mat(state_local->box, state_global->box); copy_mat(state_local->boxv, state_global->boxv); copy_mat(state_local->svir_prev, state_global->svir_prev); copy_mat(state_local->fvir_prev, state_global->fvir_prev); copy_mat(state_local->pres_prev, state_global->pres_prev); } } if (MASTER(cr)) { if (mdof_flags & MDOF_CPT) { fflush_tng(of->tng); fflush_tng(of->tng_low_prec); write_checkpoint(of->fn_cpt, of->bKeepAndNumCPT, fplog, cr, of->eIntegrator, of->simulation_part, of->bExpanded, of->elamstats, step, t, state_global); } if (mdof_flags & (MDOF_X | MDOF_V | MDOF_F)) { if (of->fp_trn) { gmx_trr_write_frame(of->fp_trn, step, t, state_local->lambda[efptFEP], state_local->box, top_global->natoms, (mdof_flags & MDOF_X) ? state_global->x : NULL, (mdof_flags & MDOF_V) ? global_v : NULL, (mdof_flags & MDOF_F) ? f_global : NULL); if (gmx_fio_flush(of->fp_trn) != 0) { gmx_file("Cannot write trajectory; maybe you are out of disk space?"); } } gmx_fwrite_tng(of->tng, FALSE, step, t, state_local->lambda[efptFEP], state_local->box, top_global->natoms, (mdof_flags & MDOF_X) ? state_global->x : NULL, (mdof_flags & MDOF_V) ? global_v : NULL, (mdof_flags & MDOF_F) ? f_global : NULL); } if (mdof_flags & MDOF_X_COMPRESSED) { rvec *xxtc = NULL; if (of->natoms_x_compressed == of->natoms_global) { /* We are writing the positions of all of the atoms to the compressed output */ xxtc = state_global->x; } else { /* We are writing the positions of only a subset of the atoms to the compressed output, so we have to make a copy of the subset of coordinates. */ int i, j; snew(xxtc, of->natoms_x_compressed); for (i = 0, j = 0; (i < of->natoms_global); i++) { if (ggrpnr(of->groups, egcCompressedX, i) == 0) { copy_rvec(state_global->x[i], xxtc[j++]); } } } if (write_xtc(of->fp_xtc, of->natoms_x_compressed, step, t, state_local->box, xxtc, of->x_compression_precision) == 0) { gmx_fatal(FARGS, "XTC error - maybe you are out of disk space?"); } gmx_fwrite_tng(of->tng_low_prec, TRUE, step, t, state_local->lambda[efptFEP], state_local->box, of->natoms_x_compressed, xxtc, NULL, NULL); if (of->natoms_x_compressed != of->natoms_global) { sfree(xxtc); } } } }
gmx_bool do_enx(ener_file_t ef,t_enxframe *fr) { int file_version=-1; int i,b; gmx_bool bRead,bOK,bOK1,bSane; real tmp1,tmp2,rdum; char buf[22]; /*int d_size;*/ bOK = TRUE; bRead = gmx_fio_getread(ef->fio); if (!bRead) { fr->e_size = fr->nre*sizeof(fr->ener[0].e)*4; /*d_size = fr->ndisre*(sizeof(real)*2);*/ } gmx_fio_checktype(ef->fio); if (!do_eheader(ef,&file_version,fr,-1,NULL,&bOK)) { if (bRead) { fprintf(stderr,"\rLast energy frame read %d time %8.3f ", ef->framenr-1,ef->frametime); if (!bOK) { fprintf(stderr, "\nWARNING: Incomplete energy frame: nr %d time %8.3f\n", ef->framenr,fr->t); } } else { gmx_file("Cannot write energy file header; maybe you are out of quota?"); } return FALSE; } if (bRead) { if ((ef->framenr < 20 || ef->framenr % 10 == 0) && (ef->framenr < 200 || ef->framenr % 100 == 0) && (ef->framenr < 2000 || ef->framenr % 1000 == 0)) { fprintf(stderr,"\rReading energy frame %6d time %8.3f ", ef->framenr,fr->t); } ef->framenr++; ef->frametime = fr->t; } /* Check sanity of this header */ bSane = fr->nre > 0 ; for(b=0; b<fr->nblock; b++) { bSane = bSane || (fr->block[b].nsub > 0); } if (!((fr->step >= 0) && bSane)) { fprintf(stderr,"\nWARNING: there may be something wrong with energy file %s\n", gmx_fio_getname(ef->fio)); fprintf(stderr,"Found: step=%s, nre=%d, nblock=%d, time=%g.\n" "Trying to skip frame expect a crash though\n", gmx_step_str(fr->step,buf),fr->nre,fr->nblock,fr->t); } if (bRead && fr->nre > fr->e_alloc) { srenew(fr->ener,fr->nre); for(i=fr->e_alloc; (i<fr->nre); i++) { fr->ener[i].e = 0; fr->ener[i].eav = 0; fr->ener[i].esum = 0; } fr->e_alloc = fr->nre; } for(i=0; i<fr->nre; i++) { bOK = bOK && gmx_fio_do_real(ef->fio, fr->ener[i].e); /* Do not store sums of length 1, * since this does not add information. */ if (file_version == 1 || (bRead && fr->nsum > 0) || fr->nsum > 1) { tmp1 = fr->ener[i].eav; bOK = bOK && gmx_fio_do_real(ef->fio, tmp1); if (bRead) fr->ener[i].eav = tmp1; /* This is to save only in single precision (unless compiled in DP) */ tmp2 = fr->ener[i].esum; bOK = bOK && gmx_fio_do_real(ef->fio, tmp2); if (bRead) fr->ener[i].esum = tmp2; if (file_version == 1) { /* Old, unused real */ rdum = 0; bOK = bOK && gmx_fio_do_real(ef->fio, rdum); } } } /* Here we can not check for file_version==1, since one could have * continued an old format simulation with a new one with mdrun -append. */ if (bRead && ef->eo.bOldFileOpen) { /* Convert old full simulation sums to sums between energy frames */ convert_full_sums(&(ef->eo),fr); } /* read the blocks */ for(b=0; b<fr->nblock; b++) { /* now read the subblocks. */ int nsub=fr->block[b].nsub; /* shortcut */ int i; for(i=0;i<nsub;i++) { t_enxsubblock *sub=&(fr->block[b].sub[i]); /* shortcut */ if (bRead) { enxsubblock_alloc(sub); } /* read/write data */ bOK1=TRUE; switch (sub->type) { case xdr_datatype_float: bOK1=gmx_fio_ndo_float(ef->fio, sub->fval, sub->nr); break; case xdr_datatype_double: bOK1=gmx_fio_ndo_double(ef->fio, sub->dval, sub->nr); break; case xdr_datatype_int: bOK1=gmx_fio_ndo_int(ef->fio, sub->ival, sub->nr); break; case xdr_datatype_large_int: bOK1=gmx_fio_ndo_gmx_large_int(ef->fio, sub->lval, sub->nr); break; case xdr_datatype_char: bOK1=gmx_fio_ndo_uchar(ef->fio, sub->cval, sub->nr); break; case xdr_datatype_string: bOK1=gmx_fio_ndo_string(ef->fio, sub->sval, sub->nr); break; default: gmx_incons("Reading unknown block data type: this file is corrupted or from the future"); } bOK = bOK && bOK1; } } if(!bRead) { if( gmx_fio_flush(ef->fio) != 0) { gmx_file("Cannot write energy file; maybe you are out of quota?"); } } if (!bOK) { if (bRead) { fprintf(stderr,"\nLast energy frame read %d", ef->framenr-1); fprintf(stderr,"\nWARNING: Incomplete energy frame: nr %d time %8.3f\n", ef->framenr,fr->t); } else { gmx_fatal(FARGS,"could not write energies"); } return FALSE; } return TRUE; }
bool do_enx(int fp,t_enxframe *fr) { int file_version=-1; int i,block; bool bRead,bOK,bOK1,bSane; real tmp1,tmp2,rdum; char buf[22]; bOK = TRUE; bRead = gmx_fio_getread(fp); if (!bRead) { fr->e_size = fr->nre*sizeof(fr->ener[0].e)*4; fr->d_size = fr->ndisre*(sizeof(fr->disre_rm3tav[0]) + sizeof(fr->disre_rt[0])); } gmx_fio_select(fp); if (!do_eheader(fp,&file_version,fr,FALSE,&bOK)) { if (bRead) { fprintf(stderr,"\rLast energy frame read %d time %8.3f ", framenr-1,frametime); if (!bOK) { fprintf(stderr, "\nWARNING: Incomplete energy frame: nr %d time %8.3f\n", framenr,fr->t); } } else { gmx_file("Cannot write energy file header; maybe you are out of quota?"); } return FALSE; } if (bRead) { if ((framenr < 20 || framenr % 10 == 0) && (framenr < 200 || framenr % 100 == 0) && (framenr < 2000 || framenr % 1000 == 0)) { fprintf(stderr,"\rReading energy frame %6d time %8.3f ", framenr,fr->t); } framenr++; frametime = fr->t; } /* Check sanity of this header */ bSane = (fr->nre > 0 || fr->ndisre > 0); for(block=0; block<fr->nblock; block++) { bSane = bSane || (fr->nr[block] > 0); } if (!((fr->step >= 0) && bSane)) { fprintf(stderr,"\nWARNING: there may be something wrong with energy file %s\n", gmx_fio_getname(fp)); fprintf(stderr,"Found: step=%s, nre=%d, ndisre=%d, nblock=%d, time=%g.\n" "Trying to skip frame expect a crash though\n", gmx_step_str(fr->step,buf),fr->nre,fr->ndisre,fr->nblock,fr->t); } if (bRead && fr->nre > fr->e_alloc) { srenew(fr->ener,fr->nre); for(i=fr->e_alloc; (i<fr->nre); i++) { fr->ener[i].e = 0; fr->ener[i].eav = 0; fr->ener[i].esum = 0; } fr->e_alloc = fr->nre; } for(i=0; i<fr->nre; i++) { bOK = bOK && do_real(fr->ener[i].e); /* Do not store sums of length 1, * since this does not add information. */ if (file_version == 1 || (bRead && fr->nsum > 0) || fr->nsum > 1) { tmp1 = fr->ener[i].eav; bOK = bOK && do_real(tmp1); if (bRead) fr->ener[i].eav = tmp1; /* This is to save only in single precision (unless compiled in DP) */ tmp2 = fr->ener[i].esum; bOK = bOK && do_real(tmp2); if (bRead) fr->ener[i].esum = tmp2; if (file_version == 1) { /* Old, unused real */ rdum = 0; bOK = bOK && do_real(rdum); } } } /* Here we can not check for file_version==1, since one could have * continued an old format simulation with a new one with mdrun -append. */ if (bRead && fp < ener_old_nalloc && ener_old[fp].bOldFileOpen) { /* Convert old full simulation sums to sums between energy frames */ convert_full_sums(&ener_old[fp],fr); } if (fr->ndisre) { if (bRead && fr->ndisre>fr->d_alloc) { srenew(fr->disre_rm3tav,fr->ndisre); srenew(fr->disre_rt,fr->ndisre); fr->d_alloc = fr->ndisre; } ndo_real(fr->disre_rm3tav,fr->ndisre,bOK1); bOK = bOK && bOK1; ndo_real(fr->disre_rt,fr->ndisre,bOK1); bOK = bOK && bOK1; } for(block=0; block<fr->nblock; block++) { if (bRead && fr->nr[block]>fr->b_alloc[block]) { srenew(fr->block[block],fr->nr[block]); fr->b_alloc[block] = fr->nr[block]; } ndo_real(fr->block[block],fr->nr[block],bOK1); bOK = bOK && bOK1; } if(!bRead) { if( gmx_fio_flush(fp) != 0) { gmx_file("Cannot write energy file; maybe you are out of quota?"); } } if (!bOK) { if (bRead) { fprintf(stderr,"\nLast energy frame read %d", framenr-1); fprintf(stderr,"\nWARNING: Incomplete energy frame: nr %d time %8.3f\n", framenr,fr->t); } else { gmx_fatal(FARGS,"could not write energies"); } return FALSE; } return TRUE; }
bool do_enx(int fp,t_enxframe *fr) { int i,block; bool bRead,bOK,bOK1,bSane; real tmp1,tmp2; bOK = TRUE; bRead = gmx_fio_getread(fp); if (!bRead) { fr->e_size = fr->nre*sizeof(fr->ener[0].e)*4; fr->d_size = fr->ndisre*(sizeof(fr->disre_rm3tav[0]) + sizeof(fr->disre_rt[0])); } gmx_fio_select(fp); if (!do_eheader(fp,fr,&bOK)) { if (bRead) { fprintf(stderr,"\rLast energy frame read %d time %8.3f ", framenr-1,frametime); if (!bOK) fprintf(stderr, "\nWARNING: Incomplete energy frame: nr %d time %8.3f\n", framenr,fr->t); } else { gmx_file("Cannot write energy file header; maybe you are out of quota?"); } return FALSE; } if (bRead) { if ((framenr < 20 || framenr % 10 == 0) && (framenr < 200 || framenr % 100 == 0) && (framenr < 2000 || framenr % 1000 == 0)) fprintf(stderr,"\rReading energy frame %6d time %8.3f ", framenr,fr->t); framenr++; frametime = fr->t; } /* Check sanity of this header */ bSane = (fr->nre > 0 || fr->ndisre > 0); for(block=0; block<fr->nblock; block++) bSane = bSane || (fr->nr[block] > 0); if (!((fr->step >= 0) && bSane)) { fprintf(stderr,"\nWARNING: there may be something wrong with energy file %s\n", gmx_fio_getname(fp)); fprintf(stderr,"Found: step=%d, nre=%d, ndisre=%d, nblock=%d, time=%g.\n" "Trying to skip frame expect a crash though\n", fr->step,fr->nre,fr->ndisre,fr->nblock,fr->t); } if (bRead && fr->nre>fr->e_alloc) { srenew(fr->ener,fr->nre); for(i=fr->e_alloc; (i<fr->nre); i++) { fr->ener[i].e = fr->ener[i].eav = fr->ener[i].esum = fr->ener[i].e2sum = 0; } fr->e_alloc = fr->nre; } for(i=0; i<fr->nre; i++) { bOK = bOK && do_real(fr->ener[i].e); tmp1 = fr->ener[i].eav; bOK = bOK && do_real(tmp1); if (bRead) fr->ener[i].eav = tmp1; /* This is to save only in single precision (unless compiled in DP) */ tmp2 = fr->ener[i].esum; bOK = bOK && do_real(tmp2); if (bRead) fr->ener[i].esum = tmp2; bOK = bOK && do_real(fr->ener[i].e2sum); } if (fr->ndisre) { if (bRead && fr->ndisre>fr->d_alloc) { srenew(fr->disre_rm3tav,fr->ndisre); srenew(fr->disre_rt,fr->ndisre); fr->d_alloc = fr->ndisre; } ndo_real(fr->disre_rm3tav,fr->ndisre,bOK1); bOK = bOK && bOK1; ndo_real(fr->disre_rt,fr->ndisre,bOK1); bOK = bOK && bOK1; } for(block=0; block<fr->nblock; block++) { if (bRead && fr->nr[block]>fr->b_alloc[block]) { srenew(fr->block[block],fr->nr[block]); fr->b_alloc[block] = fr->nr[block]; } ndo_real(fr->block[block],fr->nr[block],bOK1); bOK = bOK && bOK1; } if(!bRead) { if( gmx_fio_flush(fp) != 0) { gmx_file("Cannot write energy file; maybe you are out of quota?"); } } if (!bOK) { if (bRead) { fprintf(stderr,"\nLast energy frame read %d", framenr-1); fprintf(stderr,"\nWARNING: Incomplete energy frame: nr %d time %8.3f\n", framenr,fr->t); } else gmx_fatal(FARGS,"could not write energies"); return FALSE; } return TRUE; }