/* Read in the tpr file and save information we need later in info */
static void read_tpr_file(const char *fn_sim_tpr, t_inputinfo *info, t_state *state, gmx_mtop_t *mtop, t_inputrec *ir, real user_beta, real fracself)
{
    read_tpx_state(fn_sim_tpr,ir,state,NULL,mtop);

    /* The values of the original tpr input file are save in the first 
     * place [0] of the arrays */
    info->orig_sim_steps = ir->nsteps;
    info->pme_order[0]   = ir->pme_order;
    info->rcoulomb[0]    = ir->rcoulomb;
    info->rvdw[0]        = ir->rvdw;        
    info->nkx[0]         = ir->nkx;
    info->nky[0]         = ir->nky;
    info->nkz[0]         = ir->nkz;
    info->ewald_rtol[0]  = ir->ewald_rtol;
    info->fracself       = fracself;
    if (user_beta > 0)
        info->ewald_beta[0] = user_beta;
    else
        info->ewald_beta[0]  = calc_ewaldcoeff(info->rcoulomb[0],info->ewald_rtol[0]);

    /* Check if PME was chosen */
    if (EEL_PME(ir->coulombtype) == FALSE)
        gmx_fatal(FARGS, "Can only do optimizations for simulations with PME");
    
    /* Check if rcoulomb == rlist, which is necessary for PME */
    if (!(ir->rcoulomb == ir->rlist))
        gmx_fatal(FARGS, "PME requires rcoulomb (%f) to be equal to rlist (%f).", ir->rcoulomb, ir->rlist);
}
Ejemplo n.º 2
0
static void comp_tpx(const char *fn1, const char *fn2,
                     gmx_bool bRMSD, real ftol, real abstol)
{
    const char    *ff[2];
    gmx::MDModules mdModules[2];
    t_inputrec    *ir[2] = { mdModules[0].inputrec(), mdModules[1].inputrec() };
    t_state        state[2];
    gmx_mtop_t     mtop[2];
    t_topology     top[2];
    int            i;

    ff[0] = fn1;
    ff[1] = fn2;
    for (i = 0; i < (fn2 ? 2 : 1); i++)
    {
        read_tpx_state(ff[i], ir[i], &state[i], &(mtop[i]));
    }
    if (fn2)
    {
        cmp_inputrec(stdout, ir[0], ir[1], ftol, abstol);
        /* Convert gmx_mtop_t to t_topology.
         * We should implement direct mtop comparison,
         * but it might be useful to keep t_topology comparison as an option.
         */
        top[0] = gmx_mtop_t_to_t_topology(&mtop[0], false);
        top[1] = gmx_mtop_t_to_t_topology(&mtop[1], false);
        cmp_top(stdout, &top[0], &top[1], ftol, abstol);
        cmp_groups(stdout, &mtop[0].groups, &mtop[1].groups,
                   mtop[0].natoms, mtop[1].natoms);
        comp_state(&state[0], &state[1], bRMSD, ftol, abstol);
    }
    else
    {
        if (ir[0]->efep == efepNO)
        {
            fprintf(stdout, "inputrec->efep = %s\n", efep_names[ir[0]->efep]);
        }
        else
        {
            if (ir[0]->bPull)
            {
                comp_pull_AB(stdout, ir[0]->pull, ftol, abstol);
            }
            /* Convert gmx_mtop_t to t_topology.
             * We should implement direct mtop comparison,
             * but it might be useful to keep t_topology comparison as an option.
             */
            top[0] = gmx_mtop_t_to_t_topology(&mtop[0], true);
            cmp_top(stdout, &top[0], NULL, ftol, abstol);
        }
    }
}
Ejemplo n.º 3
0
void init_single(FILE *fplog,t_inputrec *inputrec,
		 char *tpxfile,gmx_mtop_t *mtop, 
                 t_state *state)
{
  int         step;
  real        t;
  
  read_tpx_state(tpxfile,&step,&t,inputrec,state,NULL,mtop);
  set_state_entries(state,inputrec,1);

  if (fplog)
    pr_inputrec(fplog,0,"Input Parameters",inputrec,FALSE);
}
Ejemplo n.º 4
0
static void tpx2methods(const char *tpx, const char *tex)
{
    FILE         *fp;
    t_inputrec    ir;
    t_state       state;
    gmx_mtop_t    mtop;

    read_tpx_state(tpx, &ir, &state, &mtop);
    fp = gmx_fio_fopen(tex, "w");
    fprintf(fp, "\\section{Methods}\n");
    tpx2system(fp, &mtop);
    tpx2params(fp, &ir);
    gmx_fio_fclose(fp);
}
Ejemplo n.º 5
0
void init_parallel(FILE *log,char *tpxfile,t_commrec *cr,
		   t_inputrec *inputrec,gmx_mtop_t *mtop,
		   t_state *state,
		   int list)
{
  int  step;
  real t;
  char buf[256];
  
  if (MASTER(cr)) {
    init_inputrec(inputrec);
    read_tpx_state(tpxfile,&step,&t,inputrec,state,NULL,mtop);
    /* When we will be doing domain decomposition with separate PME nodes
     * the rng entries will be too large, we correct for this later.
     */
    set_state_entries(state,inputrec,cr->nnodes);
  }
  bcast_ir_mtop(cr,inputrec,mtop);

  if (inputrec->eI == eiBD || EI_SD(inputrec->eI)) {
    /* Make sure the random seeds are different on each node */
    inputrec->ld_seed += cr->nodeid;
  }
  
  /* Printing */
  if (list!=0 && log!=NULL) 
  {
	  if (list&LIST_INPUTREC)
		  pr_inputrec(log,0,"parameters of the run",inputrec,FALSE);
	  if (list&LIST_X)
		  pr_rvecs(log,0,"box",state->box,DIM);
	  if (list&LIST_X)
		  pr_rvecs(log,0,"box_rel",state->box_rel,DIM);
	  if (list&LIST_V)
		  pr_rvecs(log,0,"boxv",state->boxv,DIM);
	  if (list&LIST_X)
		  pr_rvecs(log,0,int_title("x",0,buf,255),state->x,state->natoms);
	  if (list&LIST_V)
		  pr_rvecs(log,0,int_title("v",0,buf,255),state->v,state->natoms);
	  if (list&LIST_TOP)
		  pr_mtop(log,0,int_title("topology",cr->nodeid,buf,255),mtop,TRUE);
	  fflush(log);
  }
}
Ejemplo n.º 6
0
static void list_tpx(const char *fn, gmx_bool bShowNumbers, const char *mdpfn,
                     gmx_bool bSysTop)
{
    FILE         *gp;
    int           fp, indent, i, j, **gcount, atot;
    t_state       state;
    rvec         *f = NULL;
    t_inputrec    ir;
    t_tpxheader   tpx;
    gmx_mtop_t    mtop;
    gmx_groups_t *groups;
    t_topology    top;

    read_tpxheader(fn, &tpx, TRUE, NULL, NULL);

    read_tpx_state(fn,
                   tpx.bIr  ? &ir : NULL,
                   &state, tpx.bF ? f : NULL,
                   tpx.bTop ? &mtop : NULL);

    if (mdpfn && tpx.bIr)
    {
        gp = gmx_fio_fopen(mdpfn, "w");
        pr_inputrec(gp, 0, NULL, &(ir), TRUE);
        gmx_fio_fclose(gp);
    }

    if (!mdpfn)
    {
        if (bSysTop)
        {
            top = gmx_mtop_t_to_t_topology(&mtop);
        }

        if (available(stdout, &tpx, 0, fn))
        {
            indent = 0;
            indent = pr_title(stdout, indent, fn);
            pr_inputrec(stdout, 0, "inputrec", tpx.bIr ? &(ir) : NULL, FALSE);

            indent = 0;
            pr_header(stdout, indent, "header", &(tpx));

            if (!bSysTop)
            {
                pr_mtop(stdout, indent, "topology", &(mtop), bShowNumbers);
            }
            else
            {
                pr_top(stdout, indent, "topology", &(top), bShowNumbers);
            }

            pr_rvecs(stdout, indent, "box", tpx.bBox ? state.box : NULL, DIM);
            pr_rvecs(stdout, indent, "box_rel", tpx.bBox ? state.box_rel : NULL, DIM);
            pr_rvecs(stdout, indent, "boxv", tpx.bBox ? state.boxv : NULL, DIM);
            pr_rvecs(stdout, indent, "pres_prev", tpx.bBox ? state.pres_prev : NULL, DIM);
            pr_rvecs(stdout, indent, "svir_prev", tpx.bBox ? state.svir_prev : NULL, DIM);
            pr_rvecs(stdout, indent, "fvir_prev", tpx.bBox ? state.fvir_prev : NULL, DIM);
            /* leave nosehoover_xi in for now to match the tpr version */
            pr_doubles(stdout, indent, "nosehoover_xi", state.nosehoover_xi, state.ngtc);
            /*pr_doubles(stdout,indent,"nosehoover_vxi",state.nosehoover_vxi,state.ngtc);*/
            /*pr_doubles(stdout,indent,"therm_integral",state.therm_integral,state.ngtc);*/
            pr_rvecs(stdout, indent, "x", tpx.bX ? state.x : NULL, state.natoms);
            pr_rvecs(stdout, indent, "v", tpx.bV ? state.v : NULL, state.natoms);
            if (tpx.bF)
            {
                pr_rvecs(stdout, indent, "f", f, state.natoms);
            }
        }

        groups = &mtop.groups;

        snew(gcount, egcNR);
        for (i = 0; (i < egcNR); i++)
        {
            snew(gcount[i], groups->grps[i].nr);
        }

        for (i = 0; (i < mtop.natoms); i++)
        {
            for (j = 0; (j < egcNR); j++)
            {
                gcount[j][ggrpnr(groups, j, i)]++;
            }
        }
        printf("Group statistics\n");
        for (i = 0; (i < egcNR); i++)
        {
            atot = 0;
            printf("%-12s: ", gtypes[i]);
            for (j = 0; (j < groups->grps[i].nr); j++)
            {
                printf("  %5d", gcount[i][j]);
                atot += gcount[i][j];
            }
            printf("  (total %d atoms)\n", atot);
            sfree(gcount[i]);
        }
        sfree(gcount);
    }
    done_state(&state);
    sfree(f);
}
Ejemplo n.º 7
0
void chk_trj(const output_env_t oenv, const char *fn, const char *tpr, real tol)
{
    t_trxframe       fr;
    t_count          count;
    t_fr_time        first, last;
    int              j = -1, new_natoms, natoms;
    real             rdum, tt, old_t1, old_t2, prec;
    gmx_bool         bShowTimestep = TRUE, bOK, newline = FALSE;
    t_trxstatus     *status;
    gmx_mtop_t       mtop;
    gmx_localtop_t  *top = NULL;
    t_state          state;
    t_inputrec       ir;

    if (tpr)
    {
        read_tpx_state(tpr, &ir, &state, NULL, &mtop);
        top = gmx_mtop_generate_local_top(&mtop, &ir);
    }
    new_natoms = -1;
    natoms     = -1;

    printf("Checking file %s\n", fn);

    j      =  0;
    old_t2 = -2.0;
    old_t1 = -1.0;

    count.bStep   = 0;
    count.bTime   = 0;
    count.bLambda = 0;
    count.bX      = 0;
    count.bV      = 0;
    count.bF      = 0;
    count.bBox    = 0;

    first.bStep   = 0;
    first.bTime   = 0;
    first.bLambda = 0;
    first.bX      = 0;
    first.bV      = 0;
    first.bF      = 0;
    first.bBox    = 0;

    last.bStep   = 0;
    last.bTime   = 0;
    last.bLambda = 0;
    last.bX      = 0;
    last.bV      = 0;
    last.bF      = 0;
    last.bBox    = 0;

    read_first_frame(oenv, &status, fn, &fr, TRX_READ_X | TRX_READ_V | TRX_READ_F);

    do
    {
        if (j == 0)
        {
            fprintf(stderr, "\n# Atoms  %d\n", fr.natoms);
            if (fr.bPrec)
            {
                fprintf(stderr, "Precision %g (nm)\n", 1/fr.prec);
            }
        }
        newline = TRUE;
        if ((natoms > 0) && (new_natoms != natoms))
        {
            fprintf(stderr, "\nNumber of atoms at t=%g don't match (%d, %d)\n",
                    old_t1, natoms, new_natoms);
            newline = FALSE;
        }
        if (j >= 2)
        {
            if (fabs((fr.time-old_t1)-(old_t1-old_t2)) >
                0.1*(fabs(fr.time-old_t1)+fabs(old_t1-old_t2)) )
            {
                bShowTimestep = FALSE;
                fprintf(stderr, "%sTimesteps at t=%g don't match (%g, %g)\n",
                        newline ? "\n" : "", old_t1, old_t1-old_t2, fr.time-old_t1);
            }
        }
        natoms = new_natoms;
        if (tpr)
        {
            chk_bonds(&top->idef, ir.ePBC, fr.x, fr.box, tol);
        }
        if (fr.bX)
        {
            chk_coords(j, natoms, fr.x, fr.box, 1e5, tol);
        }
        if (fr.bV)
        {
            chk_vels(j, natoms, fr.v);
        }
        if (fr.bF)
        {
            chk_forces(j, natoms, fr.f);
        }

        old_t2 = old_t1;
        old_t1 = fr.time;
        j++;
        new_natoms = fr.natoms;
#define INC(s, n, f, l, item) if (s.item != 0) { if (n.item == 0) { first.item = fr.time; } last.item = fr.time; n.item++; \
}
        INC(fr, count, first, last, bStep);
        INC(fr, count, first, last, bTime);
        INC(fr, count, first, last, bLambda);
        INC(fr, count, first, last, bX);
        INC(fr, count, first, last, bV);
        INC(fr, count, first, last, bF);
        INC(fr, count, first, last, bBox);
#undef INC
    }
    while (read_next_frame(oenv, status, &fr));

    fprintf(stderr, "\n");

    close_trj(status);

    fprintf(stderr, "\nItem        #frames");
    if (bShowTimestep)
    {
        fprintf(stderr, " Timestep (ps)");
    }
    fprintf(stderr, "\n");
#define PRINTITEM(label, item) fprintf(stderr, "%-10s  %6d", label, count.item); if ((bShowTimestep) && (count.item > 1)) {fprintf(stderr, "    %g\n", (last.item-first.item)/(count.item-1)); }else fprintf(stderr, "\n")
    PRINTITEM ( "Step",       bStep );
    PRINTITEM ( "Time",       bTime );
    PRINTITEM ( "Lambda",     bLambda );
    PRINTITEM ( "Coords",     bX );
    PRINTITEM ( "Velocities", bV );
    PRINTITEM ( "Forces",     bF );
    PRINTITEM ( "Box",        bBox );
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
int mdrunner(gmx_hw_opt_t *hw_opt,
             FILE *fplog, t_commrec *cr, int nfile,
             const t_filenm fnm[], const output_env_t oenv, gmx_bool bVerbose,
             gmx_bool bCompact, int nstglobalcomm,
             ivec ddxyz, int dd_node_order, real rdd, real rconstr,
             const char *dddlb_opt, real dlb_scale,
             const char *ddcsx, const char *ddcsy, const char *ddcsz,
             const char *nbpu_opt, int nstlist_cmdline,
             gmx_int64_t nsteps_cmdline, int nstepout, int resetstep,
             int gmx_unused nmultisim, int repl_ex_nst, int repl_ex_nex,
             int repl_ex_seed, real pforce, real cpt_period, real max_hours,
             int imdport, unsigned long Flags)
{
    gmx_bool                  bForceUseGPU, bTryUseGPU, bRerunMD;
    t_inputrec               *inputrec;
    t_state                  *state = NULL;
    matrix                    box;
    gmx_ddbox_t               ddbox = {0};
    int                       npme_major, npme_minor;
    t_nrnb                   *nrnb;
    gmx_mtop_t               *mtop          = NULL;
    t_mdatoms                *mdatoms       = NULL;
    t_forcerec               *fr            = NULL;
    t_fcdata                 *fcd           = NULL;
    real                      ewaldcoeff_q  = 0;
    real                      ewaldcoeff_lj = 0;
    struct gmx_pme_t        **pmedata       = NULL;
    gmx_vsite_t              *vsite         = NULL;
    gmx_constr_t              constr;
    int                       nChargePerturbed = -1, nTypePerturbed = 0, status;
    gmx_wallcycle_t           wcycle;
    gmx_bool                  bReadEkin;
    gmx_walltime_accounting_t walltime_accounting = NULL;
    int                       rc;
    gmx_int64_t               reset_counters;
    gmx_edsam_t               ed           = NULL;
    int                       nthreads_pme = 1;
    int                       nthreads_pp  = 1;
    gmx_membed_t              membed       = NULL;
    gmx_hw_info_t            *hwinfo       = NULL;
    /* The master rank decides early on bUseGPU and broadcasts this later */
    gmx_bool                  bUseGPU      = FALSE;

    /* CAUTION: threads may be started later on in this function, so
       cr doesn't reflect the final parallel state right now */
    snew(inputrec, 1);
    snew(mtop, 1);

    if (Flags & MD_APPENDFILES)
    {
        fplog = NULL;
    }

    bRerunMD     = (Flags & MD_RERUN);
    bForceUseGPU = (strncmp(nbpu_opt, "gpu", 3) == 0);
    bTryUseGPU   = (strncmp(nbpu_opt, "auto", 4) == 0) || bForceUseGPU;

    /* Detect hardware, gather information. This is an operation that is
     * global for this process (MPI rank). */
    hwinfo = gmx_detect_hardware(fplog, cr, bTryUseGPU);

    gmx_print_detected_hardware(fplog, cr, hwinfo);

    if (fplog != NULL)
    {
        /* Print references after all software/hardware printing */
        please_cite(fplog, "Abraham2015");
        please_cite(fplog, "Pall2015");
        please_cite(fplog, "Pronk2013");
        please_cite(fplog, "Hess2008b");
        please_cite(fplog, "Spoel2005a");
        please_cite(fplog, "Lindahl2001a");
        please_cite(fplog, "Berendsen95a");
    }

    snew(state, 1);
    if (SIMMASTER(cr))
    {
        /* Read (nearly) all data required for the simulation */
        read_tpx_state(ftp2fn(efTPR, nfile, fnm), inputrec, state, NULL, mtop);

        if (inputrec->cutoff_scheme == ecutsVERLET)
        {
            /* Here the master rank decides if all ranks will use GPUs */
            bUseGPU = (hwinfo->gpu_info.n_dev_compatible > 0 ||
                       getenv("GMX_EMULATE_GPU") != NULL);

            /* TODO add GPU kernels for this and replace this check by:
             * (bUseGPU && (ir->vdwtype == evdwPME &&
             *               ir->ljpme_combination_rule == eljpmeLB))
             * update the message text and the content of nbnxn_acceleration_supported.
             */
            if (bUseGPU &&
                !nbnxn_gpu_acceleration_supported(fplog, cr, inputrec, bRerunMD))
            {
                /* Fallback message printed by nbnxn_acceleration_supported */
                if (bForceUseGPU)
                {
                    gmx_fatal(FARGS, "GPU acceleration requested, but not supported with the given input settings");
                }
                bUseGPU = FALSE;
            }

            prepare_verlet_scheme(fplog, cr,
                                  inputrec, nstlist_cmdline, mtop, state->box,
                                  bUseGPU);
        }
        else
        {
            if (nstlist_cmdline > 0)
            {
                gmx_fatal(FARGS, "Can not set nstlist with the group cut-off scheme");
            }

            if (hwinfo->gpu_info.n_dev_compatible > 0)
            {
                md_print_warn(cr, fplog,
                              "NOTE: GPU(s) found, but the current simulation can not use GPUs\n"
                              "      To use a GPU, set the mdp option: cutoff-scheme = Verlet\n");
            }

            if (bForceUseGPU)
            {
                gmx_fatal(FARGS, "GPU requested, but can't be used without cutoff-scheme=Verlet");
            }

#ifdef GMX_TARGET_BGQ
            md_print_warn(cr, fplog,
                          "NOTE: There is no SIMD implementation of the group scheme kernels on\n"
                          "      BlueGene/Q. You will observe better performance from using the\n"
                          "      Verlet cut-off scheme.\n");
#endif
        }

        if (inputrec->eI == eiSD2)
        {
            md_print_warn(cr, fplog, "The stochastic dynamics integrator %s is deprecated, since\n"
                          "it is slower than integrator %s and is slightly less accurate\n"
                          "with constraints. Use the %s integrator.",
                          ei_names[inputrec->eI], ei_names[eiSD1], ei_names[eiSD1]);
        }
    }

    /* Check and update the hardware options for internal consistency */
    check_and_update_hw_opt_1(hw_opt, cr);

    /* Early check for externally set process affinity. */
    gmx_check_thread_affinity_set(fplog, cr,
                                  hw_opt, hwinfo->nthreads_hw_avail, FALSE);

#ifdef GMX_THREAD_MPI
    if (SIMMASTER(cr))
    {
        if (cr->npmenodes > 0 && hw_opt->nthreads_tmpi <= 0)
        {
            gmx_fatal(FARGS, "You need to explicitly specify the number of MPI threads (-ntmpi) when using separate PME ranks");
        }

        /* Since the master knows the cut-off scheme, update hw_opt for this.
         * This is done later for normal MPI and also once more with tMPI
         * for all tMPI ranks.
         */
        check_and_update_hw_opt_2(hw_opt, inputrec->cutoff_scheme);

        /* NOW the threads will be started: */
        hw_opt->nthreads_tmpi = get_nthreads_mpi(hwinfo,
                                                 hw_opt,
                                                 inputrec, mtop,
                                                 cr, fplog, bUseGPU);

        if (hw_opt->nthreads_tmpi > 1)
        {
            t_commrec *cr_old       = cr;
            /* now start the threads. */
            cr = mdrunner_start_threads(hw_opt, fplog, cr_old, nfile, fnm,
                                        oenv, bVerbose, bCompact, nstglobalcomm,
                                        ddxyz, dd_node_order, rdd, rconstr,
                                        dddlb_opt, dlb_scale, ddcsx, ddcsy, ddcsz,
                                        nbpu_opt, nstlist_cmdline,
                                        nsteps_cmdline, nstepout, resetstep, nmultisim,
                                        repl_ex_nst, repl_ex_nex, repl_ex_seed, pforce,
                                        cpt_period, max_hours,
                                        Flags);
            /* the main thread continues here with a new cr. We don't deallocate
               the old cr because other threads may still be reading it. */
            if (cr == NULL)
            {
                gmx_comm("Failed to spawn threads");
            }
        }
    }
#endif
    /* END OF CAUTION: cr is now reliable */

    /* g_membed initialisation *
     * Because we change the mtop, init_membed is called before the init_parallel *
     * (in case we ever want to make it run in parallel) */
    if (opt2bSet("-membed", nfile, fnm))
    {
        if (MASTER(cr))
        {
            fprintf(stderr, "Initializing membed");
        }
        membed = init_membed(fplog, nfile, fnm, mtop, inputrec, state, cr, &cpt_period);
    }

    if (PAR(cr))
    {
        /* now broadcast everything to the non-master nodes/threads: */
        init_parallel(cr, inputrec, mtop);

        /* The master rank decided on the use of GPUs,
         * broadcast this information to all ranks.
         */
        gmx_bcast_sim(sizeof(bUseGPU), &bUseGPU, cr);
    }

    if (fplog != NULL)
    {
        pr_inputrec(fplog, 0, "Input Parameters", inputrec, FALSE);
        fprintf(fplog, "\n");
    }

    /* now make sure the state is initialized and propagated */
    set_state_entries(state, inputrec);

    /* A parallel command line option consistency check that we can
       only do after any threads have started. */
    if (!PAR(cr) &&
        (ddxyz[XX] > 1 || ddxyz[YY] > 1 || ddxyz[ZZ] > 1 || cr->npmenodes > 0))
    {
        gmx_fatal(FARGS,
                  "The -dd or -npme option request a parallel simulation, "
#ifndef GMX_MPI
                  "but %s was compiled without threads or MPI enabled"
#else
#ifdef GMX_THREAD_MPI
                  "but the number of threads (option -nt) is 1"
#else
                  "but %s was not started through mpirun/mpiexec or only one rank was requested through mpirun/mpiexec"
#endif
#endif
                  , output_env_get_program_display_name(oenv)
                  );
    }

    if (bRerunMD &&
        (EI_ENERGY_MINIMIZATION(inputrec->eI) || eiNM == inputrec->eI))
    {
        gmx_fatal(FARGS, "The .mdp file specified an energy mininization or normal mode algorithm, and these are not compatible with mdrun -rerun");
    }

    if (can_use_allvsall(inputrec, TRUE, cr, fplog) && DOMAINDECOMP(cr))
    {
        gmx_fatal(FARGS, "All-vs-all loops do not work with domain decomposition, use a single MPI rank");
    }

    if (!(EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype)))
    {
        if (cr->npmenodes > 0)
        {
            gmx_fatal_collective(FARGS, cr, NULL,
                                 "PME-only ranks are requested, but the system does not use PME for electrostatics or LJ");
        }

        cr->npmenodes = 0;
    }

    if (bUseGPU && cr->npmenodes < 0)
    {
        /* With GPUs we don't automatically use PME-only ranks. PME ranks can
         * improve performance with many threads per GPU, since our OpenMP
         * scaling is bad, but it's difficult to automate the setup.
         */
        cr->npmenodes = 0;
    }

#ifdef GMX_FAHCORE
    if (MASTER(cr))
    {
        fcRegisterSteps(inputrec->nsteps, inputrec->init_step);
    }
#endif

    /* NMR restraints must be initialized before load_checkpoint,
     * since with time averaging the history is added to t_state.
     * For proper consistency check we therefore need to extend
     * t_state here.
     * So the PME-only nodes (if present) will also initialize
     * the distance restraints.
     */
    snew(fcd, 1);

    /* This needs to be called before read_checkpoint to extend the state */
    init_disres(fplog, mtop, inputrec, cr, fcd, state, repl_ex_nst > 0);

    init_orires(fplog, mtop, state->x, inputrec, cr, &(fcd->orires),
                state);

    if (DEFORM(*inputrec))
    {
        /* Store the deform reference box before reading the checkpoint */
        if (SIMMASTER(cr))
        {
            copy_mat(state->box, box);
        }
        if (PAR(cr))
        {
            gmx_bcast(sizeof(box), box, cr);
        }
        /* Because we do not have the update struct available yet
         * in which the reference values should be stored,
         * we store them temporarily in static variables.
         * This should be thread safe, since they are only written once
         * and with identical values.
         */
        tMPI_Thread_mutex_lock(&deform_init_box_mutex);
        deform_init_init_step_tpx = inputrec->init_step;
        copy_mat(box, deform_init_box_tpx);
        tMPI_Thread_mutex_unlock(&deform_init_box_mutex);
    }

    if (opt2bSet("-cpi", nfile, fnm))
    {
        /* Check if checkpoint file exists before doing continuation.
         * This way we can use identical input options for the first and subsequent runs...
         */
        if (gmx_fexist_master(opt2fn_master("-cpi", nfile, fnm, cr), cr) )
        {
            load_checkpoint(opt2fn_master("-cpi", nfile, fnm, cr), &fplog,
                            cr, ddxyz,
                            inputrec, state, &bReadEkin,
                            (Flags & MD_APPENDFILES),
                            (Flags & MD_APPENDFILESSET));

            if (bReadEkin)
            {
                Flags |= MD_READ_EKIN;
            }
        }
    }

    if (MASTER(cr) && (Flags & MD_APPENDFILES))
    {
        gmx_log_open(ftp2fn(efLOG, nfile, fnm), cr,
                     Flags, &fplog);
    }

    /* override nsteps with value from cmdline */
    override_nsteps_cmdline(fplog, nsteps_cmdline, inputrec, cr);

    if (SIMMASTER(cr))
    {
        copy_mat(state->box, box);
    }

    if (PAR(cr))
    {
        gmx_bcast(sizeof(box), box, cr);
    }

    /* Essential dynamics */
    if (opt2bSet("-ei", nfile, fnm))
    {
        /* Open input and output files, allocate space for ED data structure */
        ed = ed_open(mtop->natoms, &state->edsamstate, nfile, fnm, Flags, oenv, cr);
    }

    if (PAR(cr) && !(EI_TPI(inputrec->eI) ||
                     inputrec->eI == eiNM))
    {
        cr->dd = init_domain_decomposition(fplog, cr, Flags, ddxyz, rdd, rconstr,
                                           dddlb_opt, dlb_scale,
                                           ddcsx, ddcsy, ddcsz,
                                           mtop, inputrec,
                                           box, state->x,
                                           &ddbox, &npme_major, &npme_minor);

        make_dd_communicators(fplog, cr, dd_node_order);

        /* Set overallocation to avoid frequent reallocation of arrays */
        set_over_alloc_dd(TRUE);
    }
    else
    {
        /* PME, if used, is done on all nodes with 1D decomposition */
        cr->npmenodes = 0;
        cr->duty      = (DUTY_PP | DUTY_PME);
        npme_major    = 1;
        npme_minor    = 1;

        if (inputrec->ePBC == epbcSCREW)
        {
            gmx_fatal(FARGS,
                      "pbc=%s is only implemented with domain decomposition",
                      epbc_names[inputrec->ePBC]);
        }
    }

    if (PAR(cr))
    {
        /* After possible communicator splitting in make_dd_communicators.
         * we can set up the intra/inter node communication.
         */
        gmx_setup_nodecomm(fplog, cr);
    }

    /* Initialize per-physical-node MPI process/thread ID and counters. */
    gmx_init_intranode_counters(cr);
#ifdef GMX_MPI
    if (MULTISIM(cr))
    {
        md_print_info(cr, fplog,
                      "This is simulation %d out of %d running as a composite GROMACS\n"
                      "multi-simulation job. Setup for this simulation:\n\n",
                      cr->ms->sim, cr->ms->nsim);
    }
    md_print_info(cr, fplog, "Using %d MPI %s\n",
                  cr->nnodes,
#ifdef GMX_THREAD_MPI
                  cr->nnodes == 1 ? "thread" : "threads"
#else
                  cr->nnodes == 1 ? "process" : "processes"
#endif
                  );
    fflush(stderr);
#endif

    /* Check and update hw_opt for the cut-off scheme */
    check_and_update_hw_opt_2(hw_opt, inputrec->cutoff_scheme);

    /* Check and update hw_opt for the number of MPI ranks */
    check_and_update_hw_opt_3(hw_opt);

    gmx_omp_nthreads_init(fplog, cr,
                          hwinfo->nthreads_hw_avail,
                          hw_opt->nthreads_omp,
                          hw_opt->nthreads_omp_pme,
                          (cr->duty & DUTY_PP) == 0,
                          inputrec->cutoff_scheme == ecutsVERLET);

#ifndef NDEBUG
    if (integrator[inputrec->eI].func != do_tpi &&
        inputrec->cutoff_scheme == ecutsVERLET)
    {
        gmx_feenableexcept();
    }
#endif

    if (bUseGPU)
    {
        /* Select GPU id's to use */
        gmx_select_gpu_ids(fplog, cr, &hwinfo->gpu_info, bForceUseGPU,
                           &hw_opt->gpu_opt);
    }
    else
    {
        /* Ignore (potentially) manually selected GPUs */
        hw_opt->gpu_opt.n_dev_use = 0;
    }

    /* check consistency across ranks of things like SIMD
     * support and number of GPUs selected */
    gmx_check_hw_runconf_consistency(fplog, hwinfo, cr, hw_opt, bUseGPU);

    /* Now that we know the setup is consistent, check for efficiency */
    check_resource_division_efficiency(hwinfo, hw_opt, Flags & MD_NTOMPSET,
                                       cr, fplog);

    if (DOMAINDECOMP(cr))
    {
        /* When we share GPUs over ranks, we need to know this for the DLB */
        dd_setup_dlb_resource_sharing(cr, hwinfo, hw_opt);
    }

    /* getting number of PP/PME threads
       PME: env variable should be read only on one node to make sure it is
       identical everywhere;
     */
    /* TODO nthreads_pp is only used for pinning threads.
     * This is a temporary solution until we have a hw topology library.
     */
    nthreads_pp  = gmx_omp_nthreads_get(emntNonbonded);
    nthreads_pme = gmx_omp_nthreads_get(emntPME);

    wcycle = wallcycle_init(fplog, resetstep, cr, nthreads_pp, nthreads_pme);

    if (PAR(cr))
    {
        /* Master synchronizes its value of reset_counters with all nodes
         * including PME only nodes */
        reset_counters = wcycle_get_reset_counters(wcycle);
        gmx_bcast_sim(sizeof(reset_counters), &reset_counters, cr);
        wcycle_set_reset_counters(wcycle, reset_counters);
    }

    snew(nrnb, 1);
    if (cr->duty & DUTY_PP)
    {
        bcast_state(cr, state);

        /* Initiate forcerecord */
        fr          = mk_forcerec();
        fr->hwinfo  = hwinfo;
        fr->gpu_opt = &hw_opt->gpu_opt;
        init_forcerec(fplog, oenv, fr, fcd, inputrec, mtop, cr, box,
                      opt2fn("-table", nfile, fnm),
                      opt2fn("-tabletf", nfile, fnm),
                      opt2fn("-tablep", nfile, fnm),
                      opt2fn("-tableb", nfile, fnm),
                      nbpu_opt,
                      FALSE,
                      pforce);

        /* version for PCA_NOT_READ_NODE (see md.c) */
        /*init_forcerec(fplog,fr,fcd,inputrec,mtop,cr,box,FALSE,
           "nofile","nofile","nofile","nofile",FALSE,pforce);
         */

        /* Initialize QM-MM */
        if (fr->bQMMM)
        {
            init_QMMMrec(cr, mtop, inputrec, fr);
        }

        /* Initialize the mdatoms structure.
         * mdatoms is not filled with atom data,
         * as this can not be done now with domain decomposition.
         */
        mdatoms = init_mdatoms(fplog, mtop, inputrec->efep != efepNO);

        /* Initialize the virtual site communication */
        vsite = init_vsite(mtop, cr, FALSE);

        calc_shifts(box, fr->shift_vec);

        /* With periodic molecules the charge groups should be whole at start up
         * and the virtual sites should not be far from their proper positions.
         */
        if (!inputrec->bContinuation && MASTER(cr) &&
            !(inputrec->ePBC != epbcNONE && inputrec->bPeriodicMols))
        {
            /* Make molecules whole at start of run */
            if (fr->ePBC != epbcNONE)
            {
                do_pbc_first_mtop(fplog, inputrec->ePBC, box, mtop, state->x);
            }
            if (vsite)
            {
                /* Correct initial vsite positions are required
                 * for the initial distribution in the domain decomposition
                 * and for the initial shell prediction.
                 */
                construct_vsites_mtop(vsite, mtop, state->x);
            }
        }

        if (EEL_PME(fr->eeltype) || EVDW_PME(fr->vdwtype))
        {
            ewaldcoeff_q  = fr->ewaldcoeff_q;
            ewaldcoeff_lj = fr->ewaldcoeff_lj;
            pmedata       = &fr->pmedata;
        }
        else
        {
            pmedata = NULL;
        }
    }
    else
    {
        /* This is a PME only node */

        /* We don't need the state */
        done_state(state);

        ewaldcoeff_q  = calc_ewaldcoeff_q(inputrec->rcoulomb, inputrec->ewald_rtol);
        ewaldcoeff_lj = calc_ewaldcoeff_lj(inputrec->rvdw, inputrec->ewald_rtol_lj);
        snew(pmedata, 1);
    }

    if (hw_opt->thread_affinity != threadaffOFF)
    {
        /* Before setting affinity, check whether the affinity has changed
         * - which indicates that probably the OpenMP library has changed it
         * since we first checked).
         */
        gmx_check_thread_affinity_set(fplog, cr,
                                      hw_opt, hwinfo->nthreads_hw_avail, TRUE);

        /* Set the CPU affinity */
        gmx_set_thread_affinity(fplog, cr, hw_opt, hwinfo);
    }

    /* Initiate PME if necessary,
     * either on all nodes or on dedicated PME nodes only. */
    if (EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype))
    {
        if (mdatoms)
        {
            nChargePerturbed = mdatoms->nChargePerturbed;
            if (EVDW_PME(inputrec->vdwtype))
            {
                nTypePerturbed   = mdatoms->nTypePerturbed;
            }
        }
        if (cr->npmenodes > 0)
        {
            /* The PME only nodes need to know nChargePerturbed(FEP on Q) and nTypePerturbed(FEP on LJ)*/
            gmx_bcast_sim(sizeof(nChargePerturbed), &nChargePerturbed, cr);
            gmx_bcast_sim(sizeof(nTypePerturbed), &nTypePerturbed, cr);
        }

        if (cr->duty & DUTY_PME)
        {
            status = gmx_pme_init(pmedata, cr, npme_major, npme_minor, inputrec,
                                  mtop ? mtop->natoms : 0, nChargePerturbed, nTypePerturbed,
                                  (Flags & MD_REPRODUCIBLE), nthreads_pme);
            if (status != 0)
            {
                gmx_fatal(FARGS, "Error %d initializing PME", status);
            }
        }
    }


    if (integrator[inputrec->eI].func == do_md)
    {
        /* Turn on signal handling on all nodes */
        /*
         * (A user signal from the PME nodes (if any)
         * is communicated to the PP nodes.
         */
        signal_handler_install();
    }

    if (cr->duty & DUTY_PP)
    {
        /* Assumes uniform use of the number of OpenMP threads */
        walltime_accounting = walltime_accounting_init(gmx_omp_nthreads_get(emntDefault));

        if (inputrec->bPull)
        {
            /* Initialize pull code */
            inputrec->pull_work =
                init_pull(fplog, inputrec->pull, inputrec, nfile, fnm,
                          mtop, cr, oenv, inputrec->fepvals->init_lambda,
                          EI_DYNAMICS(inputrec->eI) && MASTER(cr), Flags);
        }

        if (inputrec->bRot)
        {
            /* Initialize enforced rotation code */
            init_rot(fplog, inputrec, nfile, fnm, cr, state->x, box, mtop, oenv,
                     bVerbose, Flags);
        }

        if (inputrec->eSwapCoords != eswapNO)
        {
            /* Initialize ion swapping code */
            init_swapcoords(fplog, bVerbose, inputrec, opt2fn_master("-swap", nfile, fnm, cr),
                            mtop, state->x, state->box, &state->swapstate, cr, oenv, Flags);
        }

        constr = init_constraints(fplog, mtop, inputrec, ed, state, cr);

        if (DOMAINDECOMP(cr))
        {
            GMX_RELEASE_ASSERT(fr, "fr was NULL while cr->duty was DUTY_PP");
            dd_init_bondeds(fplog, cr->dd, mtop, vsite, inputrec,
                            Flags & MD_DDBONDCHECK, fr->cginfo_mb);

            set_dd_parameters(fplog, cr->dd, dlb_scale, inputrec, &ddbox);

            setup_dd_grid(fplog, cr->dd);
        }

        /* Now do whatever the user wants us to do (how flexible...) */
        integrator[inputrec->eI].func(fplog, cr, nfile, fnm,
                                      oenv, bVerbose, bCompact,
                                      nstglobalcomm,
                                      vsite, constr,
                                      nstepout, inputrec, mtop,
                                      fcd, state,
                                      mdatoms, nrnb, wcycle, ed, fr,
                                      repl_ex_nst, repl_ex_nex, repl_ex_seed,
                                      membed,
                                      cpt_period, max_hours,
                                      imdport,
                                      Flags,
                                      walltime_accounting);

        if (inputrec->bPull)
        {
            finish_pull(inputrec->pull_work);
        }

        if (inputrec->bRot)
        {
            finish_rot(inputrec->rot);
        }

    }
    else
    {
        GMX_RELEASE_ASSERT(pmedata, "pmedata was NULL while cr->duty was not DUTY_PP");
        /* do PME only */
        walltime_accounting = walltime_accounting_init(gmx_omp_nthreads_get(emntPME));
        gmx_pmeonly(*pmedata, cr, nrnb, wcycle, walltime_accounting, ewaldcoeff_q, ewaldcoeff_lj, inputrec);
    }

    wallcycle_stop(wcycle, ewcRUN);

    /* Finish up, write some stuff
     * if rerunMD, don't write last frame again
     */
    finish_run(fplog, cr,
               inputrec, nrnb, wcycle, walltime_accounting,
               fr ? fr->nbv : NULL,
               EI_DYNAMICS(inputrec->eI) && !MULTISIM(cr));


    /* Free GPU memory and context */
    free_gpu_resources(fr, cr, &hwinfo->gpu_info, fr ? fr->gpu_opt : NULL);

    if (opt2bSet("-membed", nfile, fnm))
    {
        sfree(membed);
    }

    gmx_hardware_info_free(hwinfo);

    /* Does what it says */
    print_date_and_time(fplog, cr->nodeid, "Finished mdrun", gmx_gettime());
    walltime_accounting_destroy(walltime_accounting);

    /* PLUMED */
    if(plumedswitch){
      plumed_finalize(plumedmain);
    }
    /* END PLUMED */

    /* Close logfile already here if we were appending to it */
    if (MASTER(cr) && (Flags & MD_APPENDFILES))
    {
        gmx_log_close(fplog);
    }

    rc = (int)gmx_get_stop_condition();

    done_ed(&ed);

#ifdef GMX_THREAD_MPI
    /* we need to join all threads. The sub-threads join when they
       exit this function, but the master thread needs to be told to
       wait for that. */
    if (PAR(cr) && MASTER(cr))
    {
        tMPI_Finalize();
    }
#endif

    return rc;
}
Ejemplo n.º 10
0
Archivo: test.c Proyecto: badi/guamps
// works
void test1() {
  const char 
    *intopol  = "../topol.tpr",
    *incpt    = "../state0.cpt",
    *outtopol = "../new.tpr";
  const unsigned int seed = 42;

  // read the header
  t_tpxheader header;
  int version, generation;
  read_tpxheader(intopol, &header, FALSE, &version, &generation);

  // decide if forces can be read from tpr
  rvec *forces;

  if (header.bF) {
    snew(forces, 1);
  } else {
    forces = NULL;
  }

  // read the topology file
  t_inputrec ir;
  t_state topol_state;
  gmx_mtop_t mtop;

  init_inputrec(&ir);
  init_state(&topol_state, -1, -1, -1, -1);
  init_mtop(&mtop);

  read_tpx_state(intopol,
		 &ir, &topol_state, forces,
		 &mtop);

  // read the checkpoint
  int sim_part;
  gmx_large_int_t step;
  double time;
  t_state cpt_state;
  t_commrec comm;

  init_state(&cpt_state, -1, -1, -1, -1);

  printf("Opening %s for reading\n", incpt);
  read_checkpoint_state(incpt, &sim_part, &step, &time, &cpt_state);


  printf("ld_rng  = %d\n", (int) cpt_state.ld_rng);
  printf("ld_rngi = %d\n"  , (int) cpt_state.ld_rngi);


  // update the state to be written
  /* gmx_rng_t rng = gmx_rng_init(seed); */
  /* unsigned int rng_state, rng_index; */
  /* gmx_rng_get_state(rng, &rng_state, &rng_index); */

  ir.ld_seed = 42;
  ir.init_t = time;
  ir.init_step = step;
  ir.init_lambda = cpt_state.lambda;
  

  /* // write the new tpr */
  /* write_tpx_state(outtopol, */
  /* 		  &ir, &cpt_state, &mtop); */

}
Ejemplo n.º 11
0
int gmx_convert_tpr(int argc, char *argv[])
{
    const char       *desc[] = {
        "[THISMODULE] can edit run input files in three 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] by creating a [REF].tpx[ref] file for a subset of your original",
        "tpx file, which is useful when you want to remove the solvent from",
        "your [REF].tpx[ref] file, or when you want to make e.g. a pure C[GRK]alpha[grk] [REF].tpx[ref] file.",
        "Note that you may need to use [TT]-nsteps -1[tt] (or similar) to get",
        "this to work.",
        "[BB]WARNING: this [REF].tpx[ref] file is not fully functional[bb].[PAR]",
        "[BB]3.[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;
    int               i;
    gmx_int64_t       nsteps_req, run_step;
    double            run_t, state_t;
    gmx_bool          bSel;
    gmx_bool          bNsteps, bExtend, bUntil;
    gmx_mtop_t        mtop;
    t_atoms           atoms;
    t_inputrec       *ir;
    t_state           state;
    int               gnx;
    char             *grpname;
    int              *index = NULL;
    char              buf[200], buf2[200];
    gmx_output_env_t *oenv;
    t_filenm          fnm[] = {
        { efTPR, NULL,  NULL,    ffREAD  },
        { efNDX, NULL,  NULL,    ffOPTRD },
        { efTPR, "-o",  "tprout", ffWRITE }
    };
#define NFILE asize(fnm)

    /* Command line options */
    static int      nsteps_req_int = 0;
    static real     extend_t       = 0.0, until_t = 0.0;
    static gmx_bool bZeroQ         = FALSE;
    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" },
        { "-zeroq",         FALSE, etBOOL, {&bZeroQ},
          "Set the charges of a group (from the index) to zero" }
    };

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

    /* Convert int to gmx_int64_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);

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

    gmx::MDModules mdModules;
    ir = mdModules.inputrec();
    read_tpx_state(top_fn, ir, &state, &mtop);
    run_step = ir->init_step;
    run_t    = ir->init_step*ir->delta_t + ir->init_t;

    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_int64_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_int64_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))
        {
            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, as_rvec_array(state.x.data()), as_rvec_array(state.v.data()));
                state.natoms = gnx;
            }
            else if (bZeroQ)
            {
                zeroq(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_PRId64, "%10", GMX_PRId64);
        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");
    }

    return 0;
}