Beispiel #1
0
void read_trn(const char *fn, int *step, real *t, real *lambda,
              rvec *box, int *natoms, rvec *x, rvec *v, rvec *f)
{
    t_fileio *fio;

    fio = open_trn(fn, "r");
    (void) do_trn(fio, TRUE, step, t, lambda, box, natoms, x, v, f);
    close_trn(fio);
}
Beispiel #2
0
void write_trn(const char *fn, int step, real t, real lambda,
               rvec *box, int natoms, rvec *x, rvec *v, rvec *f)
{
    t_fileio *fio;

    fio = open_trn(fn, "w");
    do_trn(fio, FALSE, &step, &t, &lambda, box, &natoms, x, v, f);
    close_trn(fio);
}
Beispiel #3
0
void read_trnheader(char *fn,t_trnheader *trn)
{
  int  fp;
  bool bOK;
  
  fp = open_trn(fn,"r");
  if (!do_trnheader(fp,TRUE,trn,&bOK))
    gmx_fatal(FARGS,"Empty file %s",fn);
  close_trn(fp);
}
Beispiel #4
0
void read_trnheader(const char *fn,t_trnheader *trn)
{
  t_fileio *fio;
  gmx_bool bOK;
  
  fio = open_trn(fn,"r");
  if (!do_trnheader(fio,TRUE,trn,&bOK))
    gmx_fatal(FARGS,"Empty file %s",fn);
  close_trn(fio);
}
static void list_trn(char *fn)
{
  int         fpread,fpwrite,nframe,indent;
  char        buf[256];
  rvec        *x,*v,*f;
  matrix      box;
  t_trnheader trn;
  bool        bOK;

  fpread  = open_trn(fn,"r"); 
  fpwrite = open_tpx(NULL,"w");
  gmx_fio_setdebug(fpwrite,TRUE);
  
  nframe = 0;
  while (fread_trnheader(fpread,&trn,&bOK)) {
    snew(x,trn.natoms);
    snew(v,trn.natoms);
    snew(f,trn.natoms);
    if (fread_htrn(fpread,&trn,
		   trn.box_size ? box : NULL,
		   trn.x_size   ? x : NULL,
		   trn.v_size   ? v : NULL,
		   trn.f_size   ? f : NULL)) {
      sprintf(buf,"%s frame %d",fn,nframe);
      indent=0;
      indent=pr_title(stdout,indent,buf);
      pr_indent(stdout,indent);
      fprintf(stdout,"natoms=%10d  step=%10d  time=%12.7e  lambda=%10g\n",
	      trn.natoms,trn.step,trn.t,trn.lambda);
      if (trn.box_size)
	pr_rvecs(stdout,indent,"box",box,DIM);
      if (trn.x_size)
	pr_rvecs(stdout,indent,"x",x,trn.natoms);
      if (trn.v_size)
	pr_rvecs(stdout,indent,"v",v,trn.natoms);
      if (trn.f_size)
	pr_rvecs(stdout,indent,"f",f,trn.natoms);
    } 
    else
      fprintf(stderr,"\nWARNING: Incomplete frame: nr %d, t=%g\n",
	      nframe,trn.t);
    
    sfree(x);
    sfree(v);
    sfree(f);
    nframe++;
  }
  if (!bOK)
    fprintf(stderr,"\nWARNING: Incomplete frame header: nr %d, t=%g\n",
	    nframe,trn.t);
  close_tpx(fpwrite);
  close_trn(fpread);
}
Beispiel #6
0
static void dump_dih_trn(int nframes, int nangles, real **dih, const char *fn,
                         real *time)
{
    int       i, j, k, l, m, na;
    t_fileio *trn;
    rvec     *x;
    matrix    box = {{2, 0, 0}, {0, 2, 0}, {0, 0, 2}};

    na = (nangles*2);
    if ((na % 3) != 0)
    {
        na = 1+na/3;
    }
    else
    {
        na = na/3;
    }
    printf("There are %d dihedrals. Will fill %d atom positions with cos/sin\n",
           nangles, na);
    snew(x, na);
    trn = open_trn(fn, "w");
    for (i = 0; (i < nframes); i++)
    {
        k = l = 0;
        for (j = 0; (j < nangles); j++)
        {
            for (m = 0; (m < 2); m++)
            {
                x[k][l] = (m == 0) ? cos(dih[j][i]) : sin(dih[j][i]);
                l++;
                if (l == DIM)
                {
                    l = 0;
                    k++;
                }
            }
        }
        fwrite_trn(trn, i, time[i], 0, box, na, x, NULL, NULL);
    }
    close_trn(trn);
    sfree(x);
}
Beispiel #7
0
int cmain (int argc, char *argv[])
{
    const char       *desc[] = {
        "tpbconv can edit run input files in four ways.[PAR]",
        "[BB]1.[bb] by modifying the number of steps in a run input file",
        "with options [TT]-extend[tt], [TT]-until[tt] or [TT]-nsteps[tt]",
        "(nsteps=-1 means unlimited number of steps)[PAR]",
        "[BB]2.[bb] (OBSOLETE) by creating a run input file",
        "for a continuation run when your simulation has crashed due to e.g.",
        "a full disk, or by making a continuation run input file.",
        "This option is obsolete, since mdrun now writes and reads",
        "checkpoint files.",
        "[BB]Note[bb] that a frame with coordinates and velocities is needed.",
        "When pressure and/or Nose-Hoover temperature coupling is used",
        "an energy file can be supplied to get an exact continuation",
        "of the original run.[PAR]",
        "[BB]3.[bb] by creating a [TT].tpx[tt] file for a subset of your original",
        "tpx file, which is useful when you want to remove the solvent from",
        "your [TT].tpx[tt] file, or when you want to make e.g. a pure C[GRK]alpha[grk] [TT].tpx[tt] file.",
        "Note that you may need to use [TT]-nsteps -1[tt] (or similar) to get",
        "this to work.",
        "[BB]WARNING: this [TT].tpx[tt] file is not fully functional[bb].[PAR]",
        "[BB]4.[bb] by setting the charges of a specified group",
        "to zero. This is useful when doing free energy estimates",
        "using the LIE (Linear Interaction Energy) method."
    };

    const char       *top_fn, *frame_fn;
    t_fileio         *fp;
    ener_file_t       fp_ener = NULL;
    t_trnheader       head;
    int               i;
    gmx_large_int_t   nsteps_req, run_step, frame;
    double            run_t, state_t;
    gmx_bool          bOK, bNsteps, bExtend, bUntil, bTime, bTraj;
    gmx_bool          bFrame, bUse, bSel, bNeedEner, bReadEner, bScanEner, bFepState;
    gmx_mtop_t        mtop;
    t_atoms           atoms;
    t_inputrec       *ir, *irnew = NULL;
    t_gromppopts     *gopts;
    t_state           state;
    rvec             *newx = NULL, *newv = NULL, *tmpx, *tmpv;
    matrix            newbox;
    int               gnx;
    char             *grpname;
    atom_id          *index = NULL;
    int               nre;
    gmx_enxnm_t      *enm     = NULL;
    t_enxframe       *fr_ener = NULL;
    char              buf[200], buf2[200];
    output_env_t      oenv;
    t_filenm          fnm[] = {
        { efTPX, NULL,  NULL,    ffREAD  },
        { efTRN, "-f",  NULL,    ffOPTRD },
        { efEDR, "-e",  NULL,    ffOPTRD },
        { efNDX, NULL,  NULL,    ffOPTRD },
        { efTPX, "-o",  "tpxout", ffWRITE }
    };
#define NFILE asize(fnm)

    /* Command line options */
    static int      nsteps_req_int = 0;
    static real     start_t        = -1.0, extend_t = 0.0, until_t = 0.0;
    static int      init_fep_state = 0;
    static gmx_bool bContinuation  = TRUE, bZeroQ = FALSE, bVel = TRUE;
    static t_pargs  pa[]           = {
        { "-extend",        FALSE, etREAL, {&extend_t},
          "Extend runtime by this amount (ps)" },
        { "-until",         FALSE, etREAL, {&until_t},
          "Extend runtime until this ending time (ps)" },
        { "-nsteps",        FALSE, etINT,  {&nsteps_req_int},
          "Change the number of steps" },
        { "-time",          FALSE, etREAL, {&start_t},
          "Continue from frame at this time (ps) instead of the last frame" },
        { "-zeroq",         FALSE, etBOOL, {&bZeroQ},
          "Set the charges of a group (from the index) to zero" },
        { "-vel",           FALSE, etBOOL, {&bVel},
          "Require velocities from trajectory" },
        { "-cont",          FALSE, etBOOL, {&bContinuation},
          "For exact continuation, the constraints should not be applied before the first step" },
        { "-init_fep_state", FALSE, etINT, {&init_fep_state},
          "fep state to initialize from" },
    };
    int             nerror = 0;

    CopyRight(stderr, argv[0]);

    /* Parse the command line */
    parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa,
                      asize(desc), desc, 0, NULL, &oenv);

    /* Convert int to gmx_large_int_t */
    nsteps_req = nsteps_req_int;
    bNsteps    = opt2parg_bSet("-nsteps", asize(pa), pa);
    bExtend    = opt2parg_bSet("-extend", asize(pa), pa);
    bUntil     = opt2parg_bSet("-until", asize(pa), pa);
    bFepState  = opt2parg_bSet("-init_fep_state", asize(pa), pa);
    bTime      = opt2parg_bSet("-time", asize(pa), pa);
    bTraj      = (opt2bSet("-f", NFILE, fnm) || bTime);

    top_fn = ftp2fn(efTPX, NFILE, fnm);
    fprintf(stderr, "Reading toplogy and stuff from %s\n", top_fn);

    snew(ir, 1);
    read_tpx_state(top_fn, ir, &state, NULL, &mtop);
    run_step = ir->init_step;
    run_t    = ir->init_step*ir->delta_t + ir->init_t;

    if (!EI_STATE_VELOCITY(ir->eI))
    {
        bVel = FALSE;
    }

    if (bTraj)
    {
        fprintf(stderr, "\n"
                "NOTE: Reading the state from trajectory is an obsolete feature of tpbconv.\n"
                "      Continuation should be done by loading a checkpoint file with mdrun -cpi\n"
                "      This guarantees that all state variables are transferred.\n"
                "      tpbconv is now only useful for increasing nsteps,\n"
                "      but even that can often be avoided by using mdrun -maxh\n"
                "\n");

        if (ir->bContinuation != bContinuation)
        {
            fprintf(stderr, "Modifying ir->bContinuation to %s\n",
                    bool_names[bContinuation]);
        }
        ir->bContinuation = bContinuation;


        bNeedEner = (ir->epc == epcPARRINELLORAHMAN || ir->etc == etcNOSEHOOVER);
        bReadEner = (bNeedEner && ftp2bSet(efEDR, NFILE, fnm));
        bScanEner = (bReadEner && !bTime);

        if (ir->epc != epcNO || EI_SD(ir->eI) || ir->eI == eiBD)
        {
            fprintf(stderr, "NOTE: The simulation uses pressure coupling and/or stochastic dynamics.\n"
                    "tpbconv can not provide binary identical continuation.\n"
                    "If you want that, supply a checkpoint file to mdrun\n\n");
        }

        if (EI_SD(ir->eI) || ir->eI == eiBD)
        {
            fprintf(stderr, "\nChanging ld-seed from %d ", ir->ld_seed);
            ir->ld_seed = make_seed();
            fprintf(stderr, "to %d\n\n", ir->ld_seed);
        }

        frame_fn = ftp2fn(efTRN, NFILE, fnm);

        if (fn2ftp(frame_fn) == efCPT)
        {
            int sim_part;

            fprintf(stderr,
                    "\nREADING STATE FROM CHECKPOINT %s...\n\n",
                    frame_fn);

            read_checkpoint_state(frame_fn, &sim_part,
                                  &run_step, &run_t, &state);
        }
        else
        {
            fprintf(stderr,
                    "\nREADING COORDS, VELS AND BOX FROM TRAJECTORY %s...\n\n",
                    frame_fn);

            fp = open_trn(frame_fn, "r");
            if (bScanEner)
            {
                fp_ener = open_enx(ftp2fn(efEDR, NFILE, fnm), "r");
                do_enxnms(fp_ener, &nre, &enm);
                snew(fr_ener, 1);
                fr_ener->t = -1e-12;
            }

            /* Now scan until the last set of x and v (step == 0)
             * or the ones at step step.
             */
            bFrame = TRUE;
            frame  = 0;
            while (bFrame)
            {
                bFrame = fread_trnheader(fp, &head, &bOK);
                if (bOK && frame == 0)
                {
                    if (mtop.natoms != head.natoms)
                    {
                        gmx_fatal(FARGS, "Number of atoms in Topology (%d) "
                                  "is not the same as in Trajectory (%d)\n",
                                  mtop.natoms, head.natoms);
                    }
                    snew(newx, head.natoms);
                    snew(newv, head.natoms);
                }
                bFrame = bFrame && bOK;
                if (bFrame)
                {
                    bOK = fread_htrn(fp, &head, newbox, newx, newv, NULL);
                }
                bFrame = bFrame && bOK;
                bUse   = FALSE;
                if (bFrame &&
                    (head.x_size) && (head.v_size || !bVel))
                {
                    bUse = TRUE;
                    if (bScanEner)
                    {
                        /* Read until the energy time is >= the trajectory time */
                        while (fr_ener->t < head.t && do_enx(fp_ener, fr_ener))
                        {
                            ;
                        }
                        bUse = (fr_ener->t == head.t);
                    }
                    if (bUse)
                    {
                        tmpx                  = newx;
                        newx                  = state.x;
                        state.x               = tmpx;
                        tmpv                  = newv;
                        newv                  = state.v;
                        state.v               = tmpv;
                        run_t                 = head.t;
                        run_step              = head.step;
                        state.fep_state       = head.fep_state;
                        state.lambda[efptFEP] = head.lambda;
                        copy_mat(newbox, state.box);
                    }
                }
                if (bFrame || !bOK)
                {
                    sprintf(buf, "\r%s %s frame %s%s: step %s%s time %s",
                            "%s", "%s", "%6", gmx_large_int_fmt, "%6", gmx_large_int_fmt, " %8.3f");
                    fprintf(stderr, buf,
                            bUse ? "Read   " : "Skipped", ftp2ext(fn2ftp(frame_fn)),
                            frame, head.step, head.t);
                    frame++;
                    if (bTime && (head.t >= start_t))
                    {
                        bFrame = FALSE;
                    }
                }
            }
            if (bScanEner)
            {
                close_enx(fp_ener);
                free_enxframe(fr_ener);
                free_enxnms(nre, enm);
            }
            close_trn(fp);
            fprintf(stderr, "\n");

            if (!bOK)
            {
                fprintf(stderr, "%s frame %s (step %s, time %g) is incomplete\n",
                        ftp2ext(fn2ftp(frame_fn)), gmx_step_str(frame-1, buf2),
                        gmx_step_str(head.step, buf), head.t);
            }
            fprintf(stderr, "\nUsing frame of step %s time %g\n",
                    gmx_step_str(run_step, buf), run_t);

            if (bNeedEner)
            {
                if (bReadEner)
                {
                    get_enx_state(ftp2fn(efEDR, NFILE, fnm), run_t, &mtop.groups, ir, &state);
                }
                else
                {
                    fprintf(stderr, "\nWARNING: The simulation uses %s temperature and/or %s pressure coupling,\n"
                            "         the continuation will only be exact when an energy file is supplied\n\n",
                            ETCOUPLTYPE(etcNOSEHOOVER),
                            EPCOUPLTYPE(epcPARRINELLORAHMAN));
                }
            }
            if (bFepState)
            {
                ir->fepvals->init_fep_state = init_fep_state;
            }
        }
    }

    if (bNsteps)
    {
        fprintf(stderr, "Setting nsteps to %s\n", gmx_step_str(nsteps_req, buf));
        ir->nsteps = nsteps_req;
    }
    else
    {
        /* Determine total number of steps remaining */
        if (bExtend)
        {
            ir->nsteps = ir->nsteps - (run_step - ir->init_step) + (gmx_large_int_t)(extend_t/ir->delta_t + 0.5);
            printf("Extending remaining runtime of by %g ps (now %s steps)\n",
                   extend_t, gmx_step_str(ir->nsteps, buf));
        }
        else if (bUntil)
        {
            printf("nsteps = %s, run_step = %s, current_t = %g, until = %g\n",
                   gmx_step_str(ir->nsteps, buf),
                   gmx_step_str(run_step, buf2),
                   run_t, until_t);
            ir->nsteps = (gmx_large_int_t)((until_t - run_t)/ir->delta_t + 0.5);
            printf("Extending remaining runtime until %g ps (now %s steps)\n",
                   until_t, gmx_step_str(ir->nsteps, buf));
        }
        else
        {
            ir->nsteps -= run_step - ir->init_step;
            /* Print message */
            printf("%s steps (%g ps) remaining from first run.\n",
                   gmx_step_str(ir->nsteps, buf), ir->nsteps*ir->delta_t);
        }
    }

    if (bNsteps || bZeroQ || (ir->nsteps > 0))
    {
        ir->init_step = run_step;

        if (ftp2bSet(efNDX, NFILE, fnm) ||
            !(bNsteps || bExtend || bUntil || bTraj))
        {
            atoms = gmx_mtop_global_atoms(&mtop);
            get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), 1,
                      &gnx, &index, &grpname);
            if (!bZeroQ)
            {
                bSel = (gnx != state.natoms);
                for (i = 0; ((i < gnx) && (!bSel)); i++)
                {
                    bSel = (i != index[i]);
                }
            }
            else
            {
                bSel = FALSE;
            }
            if (bSel)
            {
                fprintf(stderr, "Will write subset %s of original tpx containing %d "
                        "atoms\n", grpname, gnx);
                reduce_topology_x(gnx, index, &mtop, state.x, state.v);
                state.natoms = gnx;
            }
            else if (bZeroQ)
            {
                zeroq(gnx, index, &mtop);
                fprintf(stderr, "Zero-ing charges for group %s\n", grpname);
            }
            else
            {
                fprintf(stderr, "Will write full tpx file (no selection)\n");
            }
        }

        state_t = ir->init_t + ir->init_step*ir->delta_t;
        sprintf(buf,   "Writing statusfile with starting step %s%s and length %s%s steps...\n", "%10", gmx_large_int_fmt, "%10", gmx_large_int_fmt);
        fprintf(stderr, buf, ir->init_step, ir->nsteps);
        fprintf(stderr, "                                 time %10.3f and length %10.3f ps\n",
                state_t, ir->nsteps*ir->delta_t);
        write_tpx_state(opt2fn("-o", NFILE, fnm), ir, &state, &mtop);
    }
    else
    {
        printf("You've simulated long enough. Not writing tpr file\n");
    }
    thanx(stderr);

    return 0;
}
Beispiel #8
0
static void list_trn(char *fn)
{
  static real mass[5] = { 15.9994, 1.008, 1.008, 0.0, 0.0 };
  int         i,j=0,m,fpread,fpwrite,nframe;
  rvec        *x,*v,*f,fmol[2],xcm[2],torque[j],dx;
  real        mmm,len;
  matrix      box;
  t_trnheader trn;
  gmx_bool        bOK;

  printf("Going to open %s\n",fn);
  fpread  = open_trn(fn,"r"); 
  fpwrite = open_tpx(NULL,"w");
  gmx_fio_setdebug(fpwrite,TRUE);
  
  mmm=mass[0]+2*mass[1];
  for(i=0; (i<5); i++) 
    mass[i] /= mmm;
  
  nframe = 0;
  while (fread_trnheader(fpread,&trn,&bOK)) {
    snew(x,trn.natoms);
    snew(v,trn.natoms);
    snew(f,trn.natoms);
    if (fread_htrn(fpread,&trn,
		   trn.box_size ? box : NULL,
		   trn.x_size   ? x : NULL,
		   trn.v_size   ? v : NULL,
		   trn.f_size   ? f : NULL)) {
		   
      if (trn.x_size && trn.f_size) {
	printf("There are %d atoms\n",trn.natoms);
	for(j=0; (j<2); j++) {
	  clear_rvec(xcm[j]);
	  clear_rvec(fmol[j]);
	  clear_rvec(torque[j]);
	  for(i=5*j; (i<5*j+5); i++) {
	    rvec_inc(fmol[j],f[i]);
	    for(m=0; (m<DIM); m++)
	      xcm[j][m] += mass[i%5]*x[i][m];
	  }
	  for(i=5*j; (i<5*j+5); i++) {
	    rvec_dec(x[i],xcm[j]);
	    cprod(x[i],f[i],dx);
	    rvec_inc(torque[j],dx);
	    rvec_inc(x[i],xcm[j]);
	  }
	}
	pr_rvecs(stdout,0,"FMOL  ",fmol,2);
	pr_rvecs(stdout,0,"TORQUE",torque,2);
	printf("Distance matrix Water1-Water2\n%5s","");
	for(j=0; (j<5); j++) 
	  printf("  %10s",nm[j]);
	printf("\n");
	for(j=0; (j<5); j++) {
	  printf("%5s",nm[j]);
	  for(i=5; (i<10); i++) {
	    rvec_sub(x[i],x[j],dx);
	    len = sqrt(iprod(dx,dx));
	    printf("  %10.7f",len);
	  }
	  printf("\n");
	}
      }
    }
    sfree(x);
    sfree(v);
    sfree(f);
    nframe++;
  }
  if (!bOK)
    fprintf(stderr,"\nWARNING: Incomplete frame header: nr %d, t=%g\n",
	    nframe,trn.t);
  close_tpx(fpwrite);
  close_trn(fpread);
}
Beispiel #9
0
void read_eigenvectors(char *file,int *natoms,bool *bFit,
                       rvec **xref,bool *bDMR,
                       rvec **xav,bool *bDMA,
                       int *nvec, int **eignr, 
                       rvec ***eigvec,real **eigval)
{
  t_trnheader head;
  int    status,i,snew_size;
  rvec   *x;
  matrix box;
  bool   bOK;

  *bDMR=FALSE;

  /* read (reference (t=-1) and) average (t=0) structure */
  status=open_trn(file,"r");
  fread_trnheader(status,&head,&bOK);
  *natoms=head.natoms;
  snew(*xav,*natoms);
  fread_htrn(status,&head,box,*xav,NULL,NULL);

  if ((head.t>=-1.1) && (head.t<=-0.9)) 
  {
      snew(*xref,*natoms);
      for(i=0; i<*natoms; i++)
          copy_rvec((*xav)[i],(*xref)[i]);
      *bDMR = (head.lambda > 0.5);
      *bFit = (head.lambda > -0.5);
      if (*bFit)
      {
          fprintf(stderr,"Read %smass weighted reference structure with %d atoms from %s\n", *bDMR ? "" : "non ",*natoms,file);
      }
      else 
      {
          fprintf(stderr,"Eigenvectors in %s were determined without fitting\n",file);
          sfree(*xref);
          *xref=NULL;
      }
      fread_trnheader(status,&head,&bOK);
      fread_htrn(status,&head,box,*xav,NULL,NULL);
  }
  else
  {
      *bFit=TRUE;
      *xref=NULL;
  }
  *bDMA = (head.lambda > 0.5);
  if ((head.t<=-0.01) || (head.t>=0.01))
  {
      fprintf(stderr,"WARNING: %s does not start with t=0, which should be the "
              "average structure. This might not be a eigenvector file. "
              "Some things might go wrong.\n",
              file);
  }
  else
  {
      fprintf(stderr,
              "Read %smass weighted average/minimum structure with %d atoms from %s\n",
              *bDMA ? "" : "non ",*natoms,file);
  }
  
  snew(x,*natoms);
  snew_size=10;
  snew(*eignr,snew_size);
  snew(*eigval,snew_size);
  snew(*eigvec,snew_size);
	
  *nvec=0;
  while (fread_trnheader(status,&head,&bOK)) 
  {
      fread_htrn(status,&head,box,x,NULL,NULL);
      if (*nvec >= snew_size) 
      {
          snew_size+=10;
          srenew(*eignr,snew_size);
          srenew(*eigval,snew_size);
          srenew(*eigvec,snew_size);
      }
      i=head.step;
      (*eigval)[*nvec]=head.t;
      (*eignr)[*nvec]=i-1;
      snew((*eigvec)[*nvec],*natoms);
      for(i=0; i<*natoms; i++)
      {
          copy_rvec(x[i],(*eigvec)[*nvec][i]);
      }
      (*nvec)++;
  }
  sfree(x);
  fprintf(stderr,"Read %d eigenvectors (for %d atoms)\n\n",*nvec,*natoms);
}
Beispiel #10
0
gmx_mdoutf_t init_mdoutf(FILE *fplog, int nfile, const t_filenm fnm[],
                         int mdrun_flags, const t_commrec *cr,
                         const t_inputrec *ir, gmx_mtop_t *top_global,
                         const output_env_t oenv)
{
    gmx_mdoutf_t  of;
    char          filemode[3];
    gmx_bool      bAppendFiles, bCiteTng = FALSE;
    int           i;

    snew(of, 1);

    of->fp_trn       = NULL;
    of->fp_ene       = NULL;
    of->fp_xtc       = NULL;
    of->tng          = NULL;
    of->tng_low_prec = NULL;
    of->fp_dhdl      = NULL;
    of->fp_field     = NULL;

    of->eIntegrator             = ir->eI;
    of->bExpanded               = ir->bExpanded;
    of->elamstats               = ir->expandedvals->elamstats;
    of->simulation_part         = ir->simulation_part;
    of->x_compression_precision = ir->x_compression_precision;

    if (MASTER(cr))
    {
        bAppendFiles = (mdrun_flags & MD_APPENDFILES);

        of->bKeepAndNumCPT = (mdrun_flags & MD_KEEPANDNUMCPT);

        sprintf(filemode, bAppendFiles ? "a+" : "w+");

        if ((EI_DYNAMICS(ir->eI) || EI_ENERGY_MINIMIZATION(ir->eI))
#ifndef GMX_FAHCORE
            &&
            !(EI_DYNAMICS(ir->eI) &&
              ir->nstxout == 0 &&
              ir->nstvout == 0 &&
              ir->nstfout == 0)
#endif
            )
        {
            const char *filename;
            filename = ftp2fn(efTRN, nfile, fnm);
            switch (fn2ftp(filename))
            {
                case efTRR:
                case efTRN:
                    of->fp_trn = open_trn(filename, filemode);
                    break;
                case efTNG:
                    gmx_tng_open(filename, filemode[0], &of->tng);
                    if (filemode[0] == 'w')
                    {
                        gmx_tng_prepare_md_writing(of->tng, top_global, ir);
                    }
                    bCiteTng = TRUE;
                    break;
                default:
                    gmx_incons("Invalid full precision file format");
            }
        }
        if (EI_DYNAMICS(ir->eI) &&
            ir->nstxout_compressed > 0)
        {
            const char *filename;
            filename = ftp2fn(efCOMPRESSED, nfile, fnm);
            switch (fn2ftp(filename))
            {
                case efXTC:
                    of->fp_xtc                  = open_xtc(filename, filemode);
                    break;
                case efTNG:
                    gmx_tng_open(filename, filemode[0], &of->tng_low_prec);
                    if (filemode[0] == 'w')
                    {
                        gmx_tng_prepare_low_prec_writing(of->tng_low_prec, top_global, ir);
                    }
                    bCiteTng = TRUE;
                    break;
                default:
                    gmx_incons("Invalid reduced precision file format");
            }
        }
        if (EI_DYNAMICS(ir->eI) || EI_ENERGY_MINIMIZATION(ir->eI))
        {
            of->fp_ene = open_enx(ftp2fn(efEDR, nfile, fnm), filemode);
        }
        of->fn_cpt = opt2fn("-cpo", nfile, fnm);

        if ((ir->efep != efepNO || ir->bSimTemp) && ir->fepvals->nstdhdl > 0 &&
            (ir->fepvals->separate_dhdl_file == esepdhdlfileYES ) &&
            EI_DYNAMICS(ir->eI))
        {
            if (bAppendFiles)
            {
                of->fp_dhdl = gmx_fio_fopen(opt2fn("-dhdl", nfile, fnm), filemode);
            }
            else
            {
                of->fp_dhdl = open_dhdl(opt2fn("-dhdl", nfile, fnm), ir, oenv);
            }
        }

        if (opt2bSet("-field", nfile, fnm) &&
            (ir->ex[XX].n || ir->ex[YY].n || ir->ex[ZZ].n))
        {
            if (bAppendFiles)
            {
                of->fp_dhdl = gmx_fio_fopen(opt2fn("-field", nfile, fnm),
                                            filemode);
            }
            else
            {
                of->fp_field = xvgropen(opt2fn("-field", nfile, fnm),
                                        "Applied electric field", "Time (ps)",
                                        "E (V/nm)", oenv);
            }
        }

        /* Set up atom counts so they can be passed to actual
           trajectory-writing routines later. Also, XTC writing needs
           to know what (and how many) atoms might be in the XTC
           groups, and how to look up later which ones they are. */
        of->natoms_global       = top_global->natoms;
        of->groups              = &top_global->groups;
        of->natoms_x_compressed = 0;
        for (i = 0; (i < top_global->natoms); i++)
        {
            if (ggrpnr(of->groups, egcCompressedX, i) == 0)
            {
                of->natoms_x_compressed++;
            }
        }
    }

    if (bCiteTng)
    {
        please_cite(fplog, "Lundborg2014");
    }

    return of;
}
void init_md(FILE *fplog,
			 t_commrec *cr,t_inputrec *ir,real *t,real *t0,
			 real *lambda,real *lam0,
			 t_nrnb *nrnb,gmx_mtop_t *mtop,
			 gmx_stochd_t *sd,
			 int nfile,t_filenm fnm[],
			 int *fp_trn,int *fp_xtc,int *fp_ene,char **fn_cpt,
			 FILE **fp_dgdl,FILE **fp_field,
			 t_mdebin **mdebin,
			 tensor force_vir,tensor shake_vir,rvec mu_tot,
			 bool *bNEMD,bool *bSimAnn,t_vcm **vcm, unsigned long Flags)
{
  int  i,j,n;
  real tmpt,mod;
  char filemode[2];

  sprintf(filemode, (Flags & MD_APPENDFILES) ? "a" : "w");
	
  /* Initial values */
  *t = *t0       = ir->init_t;
  if (ir->efep != efepNO) {
    *lam0 = ir->init_lambda;
    *lambda = *lam0 + ir->init_step*ir->delta_lambda;
  }
  else {
    *lambda = *lam0   = 0.0;
  } 
 
  *bSimAnn=FALSE;
  for(i=0;i<ir->opts.ngtc;i++) {
    /* set bSimAnn if any group is being annealed */
    if(ir->opts.annealing[i]!=eannNO)
      *bSimAnn = TRUE;
  }
  if (*bSimAnn) {
    update_annealing_target_temp(&(ir->opts),ir->init_t);
  }

  *bNEMD = (ir->opts.ngacc > 1) || (norm(ir->opts.acc[0]) > 0);
  
  if (sd && (ir->eI == eiBD || EI_SD(ir->eI) || ir->etc == etcVRESCALE)) {
    *sd = init_stochd(fplog,ir);
  }

  if (vcm) {
    *vcm = init_vcm(fplog,&mtop->groups,ir);
  }
   
  if (EI_DYNAMICS(ir->eI) && !(Flags & MD_APPENDFILES)) {
    if (ir->etc == etcBERENDSEN) {
      please_cite(fplog,"Berendsen84a");
    }
    if (ir->etc == etcVRESCALE) {
      please_cite(fplog,"Bussi2007a");
    }
  }
 
  init_nrnb(nrnb);

  if (nfile != -1)
  {
	  *fp_trn = -1;
	  *fp_ene = -1;
	  *fp_xtc = -1;
	  
	  if (MASTER(cr)) 
	  {
		  *fp_trn = open_trn(ftp2fn(efTRN,nfile,fnm), filemode);
		  if (ir->nstxtcout > 0)
		  {
			  *fp_xtc = open_xtc(ftp2fn(efXTC,nfile,fnm), filemode);
		  }
		  *fp_ene = open_enx(ftp2fn(efENX,nfile,fnm), filemode);
		  *fn_cpt = opt2fn("-cpo",nfile,fnm);
		  
		  if ((fp_dgdl != NULL) && ir->efep!=efepNO)
		  {
			  if(Flags & MD_APPENDFILES)
			  {
				  *fp_dgdl= gmx_fio_fopen(opt2fn("-dgdl",nfile,fnm),filemode);
			  }
			  else
			  {
				  *fp_dgdl = xvgropen(opt2fn("-dgdl",nfile,fnm),
									  "dG/d\\8l\\4","Time (ps)",
									  "dG/d\\8l\\4 (kJ mol\\S-1\\N [\\8l\\4]\\S-1\\N)");
			  }
		  }
		  
		  if ((fp_field != NULL) && (ir->ex[XX].n || ir->ex[YY].n ||ir->ex[ZZ].n))
		  {
			  if(Flags & MD_APPENDFILES)
			  {
				  *fp_field = gmx_fio_fopen(opt2fn("-field",nfile,fnm),filemode);
			  }
			  else
			  {				  
				  *fp_field = xvgropen(opt2fn("-field",nfile,fnm),
									   "Applied electric field","Time (ps)",
									   "E (V/nm)");
			  }
		  }
	  }
	  *mdebin = init_mdebin( (Flags & MD_APPENDFILES) ? -1 : *fp_ene,mtop,ir);
  }

  /* Initiate variables */  
  clear_mat(force_vir);
  clear_mat(shake_vir);
  clear_rvec(mu_tot);

  debug_gmx();
}