コード例 #1
0
int gmx_pme_error(int argc,char *argv[])
{
    const char *desc[] = {
            "[TT]g_pme_error[tt] estimates the error of the electrostatic forces",
            "if using the sPME algorithm. The flag [TT]-tune[tt] will determine",
            "the splitting parameter such that the error is equally",
            "distributed over the real and reciprocal space part.",
            "The part of the error that stems from self interaction of the particles "
            "is computationally demanding. However, a good a approximation is to",
            "just use a fraction of the particles for this term which can be",
            "indicated by the flag [TT]-self[tt].[PAR]",
    };

    real        fs=0.0;             /* 0 indicates: not set by the user */
    real        user_beta=-1.0;
    real        fracself=1.0;
    t_inputinfo info;
    t_state     state;     /* The state from the tpr input file */
    gmx_mtop_t  mtop;      /* The topology from the tpr input file */
    t_inputrec  *ir=NULL;  /* The inputrec from the tpr file */
    FILE        *fp=NULL;
    t_commrec   *cr;
    unsigned long PCA_Flags;
    gmx_bool        bTUNE=FALSE;
    gmx_bool    bVerbose=FALSE;
    int         seed=0;


    static t_filenm fnm[] = {
      { efTPX, "-s",     NULL,    ffREAD },
      { efOUT, "-o",    "error",  ffWRITE },
      { efTPX, "-so",   "tuned",  ffOPTWR }
    };

    output_env_t oenv=NULL;

    t_pargs pa[] = {
        { "-beta",     FALSE, etREAL, {&user_beta},
            "If positive, overwrite ewald_beta from [TT].tpr[tt] file with this value" },
        { "-tune",     FALSE, etBOOL, {&bTUNE},
            "Tune the splitting parameter such that the error is equally distributed between real and reciprocal space" },
        { "-self",     FALSE, etREAL, {&fracself},
            "If between 0.0 and 1.0, determine self interaction error from just this fraction of the charged particles" },
        { "-seed",     FALSE, etINT,  {&seed},
          "Random number seed used for Monte Carlo algorithm when [TT]-self[tt] is set to a value between 0.0 and 1.0" },
        { "-v",        FALSE, etBOOL, {&bVerbose},
            "Be loud and noisy" }
    };

    
#define NFILE asize(fnm)
    
    cr = init_par(&argc,&argv);
    
#ifdef GMX_LIB_MPI
    MPI_Barrier(MPI_COMM_WORLD);
#endif

    if (MASTER(cr))
      CopyRight(stderr,argv[0]);
    
    PCA_Flags = PCA_NOEXIT_ON_ARGS;
    PCA_Flags |= (MASTER(cr) ? 0 : PCA_QUIET);
    
    parse_common_args(&argc,argv,PCA_Flags,
                      NFILE,fnm,asize(pa),pa,asize(desc),desc,
                      0,NULL,&oenv);        

    if (!bTUNE)
        bTUNE = opt2bSet("-so",NFILE,fnm);

    info.n_entries = 1;
    
    /* Allocate memory for the inputinfo struct: */
    create_info(&info);
    info.fourier_sp[0] = fs;
    
    /* Read in the tpr file and open logfile for reading */
    if (MASTER(cr))
    {
        snew(ir,1);
        read_tpr_file(opt2fn("-s",NFILE,fnm), &info, &state, &mtop, ir, user_beta,fracself);

        fp=fopen(opt2fn("-o",NFILE,fnm),"w");
    }
    
    /* Check consistency if the user provided fourierspacing */
    if (fs > 0 && MASTER(cr))
    {
        /* Recalculate the grid dimensions using fourierspacing from user input */
        info.nkx[0] = 0;
        info.nky[0] = 0;
        info.nkz[0] = 0;
        calc_grid(stdout,state.box,info.fourier_sp[0],&(info.nkx[0]),&(info.nky[0]),&(info.nkz[0]));
        if ( (ir->nkx != info.nkx[0]) || (ir->nky != info.nky[0]) || (ir->nkz != info.nkz[0]) )
            gmx_fatal(FARGS, "Wrong fourierspacing %f nm, input file grid = %d x %d x %d, computed grid = %d x %d x %d", 
                      fs,ir->nkx,ir->nky,ir->nkz,info.nkx[0],info.nky[0],info.nkz[0]);
    }
    
    /* Estimate (S)PME force error */

    /* Determine the volume of the simulation box */
    if (MASTER(cr))
    {
        info.volume = det(state.box);
        calc_recipbox(state.box,info.recipbox);
        info.natoms = mtop.natoms;
        info.bTUNE  = bTUNE;
    }   

    if (PAR(cr))
        bcast_info(&info, cr);
    
    /* Get an error estimate of the input tpr file and do some tuning if requested */
    estimate_PME_error(&info, &state, &mtop, fp, bVerbose, seed, cr);
    
    if (MASTER(cr))
    {
        /* Write out optimized tpr file if requested */
        if ( opt2bSet("-so",NFILE,fnm) || bTUNE )
        {
            ir->ewald_rtol=info.ewald_rtol[0];
            write_tpx_state(opt2fn("-so",NFILE,fnm),ir,&state,&mtop);
        }
        please_cite(fp,"Wang2010");
        fclose(fp);
    }
    
    if (gmx_parallel_env_initialized())
    {
        gmx_finalize();
    }
    
    return 0;
}
コード例 #2
0
ファイル: tpbconv.c プロジェクト: yhalcyon/Gromacs
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;
}
コード例 #3
0
int main (int argc, char *argv[])
{
  static const char *desc[] = {
    "The gromacs preprocessor",
    "reads a molecular topology file, checks the validity of the",
    "file, expands the topology from a molecular description to an atomic",
    "description. The topology file contains information about",
    "molecule types and the number of molecules, the preprocessor",
    "copies each molecule as needed. ",
    "There is no limitation on the number of molecule types. ",
    "Bonds and bond-angles can be converted into constraints, separately",
    "for hydrogens and heavy atoms.",
    "Then a coordinate file is read and velocities can be generated",
    "from a Maxwellian distribution if requested.",
    "grompp also reads parameters for the mdrun ",
    "(eg. number of MD steps, time step, cut-off), and others such as",
    "NEMD parameters, which are corrected so that the net acceleration",
    "is zero.",
    "Eventually a binary file is produced that can serve as the sole input",
    "file for the MD program.[PAR]",
    
    "grompp uses the atom names from the topology file. The atom names",
    "in the coordinate file (option [TT]-c[tt]) are only read to generate",
    "warnings when they do not match the atom names in the topology.",
    "Note that the atom names are irrelevant for the simulation as",
    "only the atom types are used for generating interaction parameters.[PAR]",

    "grompp calls a preprocessor to resolve includes, macros ",
    "etcetera. By default we use the cpp in your path. To specify a "
    "different macro-preprocessor (e.g. m4) or alternative location",

    "you can put a line in your parameter file specifying the path",
    "to that program. Specifying [TT]-pp[tt] will get the pre-processed",
    "topology file written out.[PAR]",
    
    "If your system does not have a c-preprocessor, you can still",
    "use grompp, but you do not have access to the features ",
    "from the cpp. Command line options to the c-preprocessor can be given",
    "in the [TT].mdp[tt] file. See your local manual (man cpp).[PAR]",
    
    "When using position restraints a file with restraint coordinates",
    "can be supplied with [TT]-r[tt], otherwise restraining will be done",
    "with respect to the conformation from the [TT]-c[tt] option.",
    "For free energy calculation the the coordinates for the B topology",
    "can be supplied with [TT]-rb[tt], otherwise they will be equal to",
    "those of the A topology.[PAR]",
    
    "Starting coordinates can be read from trajectory with [TT]-t[tt].",
    "The last frame with coordinates and velocities will be read,",
    "unless the [TT]-time[tt] option is used.",
    "Note that these velocities will not be used when [TT]gen_vel = yes[tt]",
    "in your [TT].mdp[tt] file. An energy file can be supplied with",
    "[TT]-e[tt] to have exact restarts when using pressure and/or",
    "Nose-Hoover temperature coupling. For an exact restart do not forget",
    "to turn off velocity generation and turn on unconstrained starting",
    "when constraints are present in the system.",
    "If you want to continue a crashed run, it is",
    "easier to use [TT]tpbconv[tt].[PAR]",

    "Using the [TT]-morse[tt] option grompp can convert the harmonic bonds",
    "in your topology to morse potentials. This makes it possible to break",
    "bonds. For this option to work you need an extra file in your $GMXLIB",
    "with dissociation energy. Use the -debug option to get more information",
    "on the workings of this option (look for MORSE in the grompp.log file",
    "using less or something like that).[PAR]",
    
    "By default all bonded interactions which have constant energy due to",
    "virtual site constructions will be removed. If this constant energy is",
    "not zero, this will result in a shift in the total energy. All bonded",
    "interactions can be kept by turning off [TT]-rmvsbds[tt]. Additionally,",
    "all constraints for distances which will be constant anyway because",
    "of virtual site constructions will be removed. If any constraints remain",
    "which involve virtual sites, a fatal error will result.[PAR]"
    
    "To verify your run input file, please make notice of all warnings",
    "on the screen, and correct where necessary. Do also look at the contents",
    "of the [TT]mdout.mdp[tt] file, this contains comment lines, as well as",
    "the input that [TT]grompp[tt] has read. If in doubt you can start grompp",
    "with the [TT]-debug[tt] option which will give you more information",
    "in a file called grompp.log (along with real debug info). Finally, you",
    "can see the contents of the run input file with the [TT]gmxdump[tt]",
    "program."
  };
  t_gromppopts *opts;
  gmx_mtop_t   *sys;
  int          nmi;
  t_molinfo    *mi;
  gpp_atomtype_t atype;
  t_inputrec   *ir;
  int          natoms,nvsite,comb,mt;
  t_params     *plist;
  t_state      state;
  matrix       box;
  real         max_spacing,fudgeQQ;
  double       reppow;
  char         fn[STRLEN],fnB[STRLEN],*mdparin;
  int          nerror,ntype;
  bool         bNeedVel,bGenVel;
  bool         have_radius,have_vol,have_surftens,have_gb_radius,have_S_hct;
  bool         have_atomnumber;
  int		   n12,n13,n14;
  t_params     *gb_plist = NULL;
  gmx_genborn_t *born = NULL;

  t_filenm fnm[] = {
    { efMDP, NULL,  NULL,        ffOPTRD },
    { efMDP, "-po", "mdout",     ffWRITE },
    { efSTX, "-c",  NULL,        ffREAD  },
    { efSTX, "-r",  NULL,        ffOPTRD },
    { efSTX, "-rb", NULL,        ffOPTRD },
    { efNDX, NULL,  NULL,        ffOPTRD },
    { efTOP, NULL,  NULL,        ffREAD  },
    { efTOP, "-pp", "processed", ffOPTWR },
    { efTPX, "-o",  NULL,        ffWRITE },
    { efTRN, "-t",  NULL,        ffOPTRD },
    { efEDR, "-e",  NULL,        ffOPTRD }
  };
#define NFILE asize(fnm)

  /* Command line options */
  static bool bVerbose=TRUE,bRenum=TRUE;
  static bool bRmVSBds=TRUE,bZero=FALSE;
  static int  i,maxwarn=0;
  static real fr_time=-1;
  t_pargs pa[] = {
    { "-v",       FALSE, etBOOL, {&bVerbose},
      "Be loud and noisy" },
    { "-time",    FALSE, etREAL, {&fr_time},
      "Take frame at or first after this time." },
    { "-rmvsbds",FALSE, etBOOL, {&bRmVSBds},
      "Remove constant bonded interactions with virtual sites" },
    { "-maxwarn", FALSE, etINT,  {&maxwarn},
      "Number of allowed warnings during input processing" },
    { "-zero",    FALSE, etBOOL, {&bZero},
      "Set parameters for bonded interactions without defaults to zero instead of generating an error" },
    { "-renum",   FALSE, etBOOL, {&bRenum},
      "Renumber atomtypes and minimize number of atomtypes" }
  };
  
  CopyRight(stdout,argv[0]);
  
  /* Initiate some variables */
  nerror=0;
  snew(ir,1);
  snew(opts,1);
  init_ir(ir,opts);
  
  /* Parse the command line */
  parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa,
		    asize(desc),desc,0,NULL);
  
  init_warning(maxwarn);
  
  /* PARAMETER file processing */
  mdparin = opt2fn("-f",NFILE,fnm);
  set_warning_line(mdparin,-1);    
  get_ir(mdparin,opt2fn("-po",NFILE,fnm),ir,opts,&nerror);
  
  if (bVerbose) 
    fprintf(stderr,"checking input for internal consistency...\n");
  check_ir(mdparin,ir,opts,&nerror);

  if (ir->ld_seed == -1) {
    ir->ld_seed = make_seed();
    fprintf(stderr,"Setting the LD random seed to %d\n",ir->ld_seed);
  }

  bNeedVel = EI_STATE_VELOCITY(ir->eI);
  bGenVel  = (bNeedVel && opts->bGenVel);

  snew(plist,F_NRE);
  init_plist(plist);
  snew(sys,1);
  atype = init_atomtype();
  if (debug)
    pr_symtab(debug,0,"Just opened",&sys->symtab);
    
  strcpy(fn,ftp2fn(efTOP,NFILE,fnm));
  if (!gmx_fexist(fn)) 
    gmx_fatal(FARGS,"%s does not exist",fn);
  new_status(fn,opt2fn_null("-pp",NFILE,fnm),opt2fn("-c",NFILE,fnm),
	     opts,ir,bZero,bGenVel,bVerbose,&state,
	     atype,sys,&nmi,&mi,plist,&comb,&reppow,&fudgeQQ,
	     opts->bMorse,
	     &nerror);
  
  if (debug)
    pr_symtab(debug,0,"After new_status",&sys->symtab);
  
  if (count_constraints(sys,mi) && (ir->eConstrAlg == econtSHAKE)) {
    if (ir->eI == eiCG || ir->eI == eiLBFGS) {
      fprintf(stderr,
	      "ERROR: Can not do %s with %s, use %s\n",
	      EI(ir->eI),econstr_names[econtSHAKE],econstr_names[econtLINCS]);
      nerror++;
    }
    if (ir->bPeriodicMols) {
      fprintf(stderr,
	      "ERROR: can not do periodic molecules with %s, use %s\n",
	      econstr_names[econtSHAKE],econstr_names[econtLINCS]);
      nerror++;
    }
  }

  /* If we are doing GBSA, check that we got the parameters we need                                                            
   * This checking is to see if there are GBSA paratmeters for all                                                             
   * atoms in the force field. To go around this for testing purposes                                                          
   * comment out the nerror++ counter temporarliy                                                                              
   */
  have_radius=have_vol=have_surftens=have_gb_radius=have_S_hct=TRUE;
  for(i=0;i<get_atomtype_ntypes(atype);i++) {
    have_radius=have_radius       && (get_atomtype_radius(i,atype) > 0);
    have_vol=have_vol             && (get_atomtype_vol(i,atype) > 0);
    have_surftens=have_surftens   && (get_atomtype_surftens(i,atype) > 0);
    have_gb_radius=have_gb_radius && (get_atomtype_gb_radius(i,atype) > 0);
    have_S_hct=have_S_hct         && (get_atomtype_S_hct(i,atype) > 0);
  }
  if(!have_radius && ir->implicit_solvent==eisGBSA) {
    fprintf(stderr,"Can't do GB electrostatics; the forcefield is missing values for\n"
	    "atomtype radii, or they might be zero\n.");
    /* nerror++; */
  }
  /*
  if(!have_surftens && ir->implicit_solvent!=eisNO) {
    fprintf(stderr,"Can't do implicit solvent; the forcefield is missing values\n"
	    " for atomtype surface tension\n.");
    nerror++;                                                                                                                
  }
  */
  
  /* If we are doing QM/MM, check that we got the atom numbers */
  have_atomnumber = TRUE;
  for (i=0; i<get_atomtype_ntypes(atype); i++) {
    have_atomnumber = have_atomnumber && (get_atomtype_atomnumber(i,atype) >= 0);
  }
  if (!have_atomnumber && ir->bQMMM)
  {
    fprintf(stderr,"\n"
            "It appears as if you are trying to run a QM/MM calculation, but the force\n"
            "field you are using does not contain atom numbers fields. This is an\n"
            "optional field (introduced in Gromacs 3.3) for general runs, but mandatory\n"
            "for QM/MM. The good news is that it is easy to add - put the atom number as\n"
            "an integer just before the mass column in ffXXXnb.itp.\n"
            "NB: United atoms have the same atom numbers as normal ones.\n\n"); 
    nerror++;
  }

  if (nerror) {
    print_warn_num(FALSE);
    
    gmx_fatal(FARGS,"There were %d error(s) processing your input",nerror);
  }
  if (opt2bSet("-r",NFILE,fnm))
    sprintf(fn,"%s",opt2fn("-r",NFILE,fnm));
  else
    sprintf(fn,"%s",opt2fn("-c",NFILE,fnm));
  if (opt2bSet("-rb",NFILE,fnm))
    sprintf(fnB,"%s",opt2fn("-rb",NFILE,fnm));
  else
    strcpy(fnB,fn);

  if (nint_ftype(sys,mi,F_POSRES) > 0) {
    if (bVerbose) {
      fprintf(stderr,"Reading position restraint coords from %s",fn);
      if (strcmp(fn,fnB) == 0) {
	fprintf(stderr,"\n");
      } else {
	fprintf(stderr," and %s\n",fnB);
	if (ir->efep != efepNO && ir->n_flambda > 0) {
	  fprintf(stderr,"ERROR: can not change the position restraint reference coordinates with lambda togther with foreign lambda calculation.\n");
	  nerror++;
	}
      }
    }
    gen_posres(sys,mi,fn,fnB,
	       ir->refcoord_scaling,ir->ePBC,
	       ir->posres_com,ir->posres_comB);
  }
		
  nvsite = 0;
  /* set parameters for virtual site construction (not for vsiten) */
  for(mt=0; mt<sys->nmoltype; mt++) {
    nvsite +=
      set_vsites(bVerbose, &sys->moltype[mt].atoms, atype, mi[mt].plist);
  }
  /* now throw away all obsolete bonds, angles and dihedrals: */
  /* note: constraints are ALWAYS removed */
  if (nvsite) {
    for(mt=0; mt<sys->nmoltype; mt++) {
      clean_vsite_bondeds(mi[mt].plist,sys->moltype[mt].atoms.nr,bRmVSBds);
    }
  }
  
	/* If we are using CMAP, setup the pre-interpolation grid */
	if(plist->ncmap>0)
	{
		init_cmap_grid(&sys->cmap_grid, plist->nc, plist->grid_spacing);
		setup_cmap(plist->grid_spacing, plist->nc, plist->cmap,&sys->cmap_grid);
	}
	
  set_wall_atomtype(atype,opts,ir);
  if (bRenum) {
    renum_atype(plist, sys, ir->wall_atomtype, atype, bVerbose);
    ntype = get_atomtype_ntypes(atype);
  }
  
	/* PELA: Copy the atomtype data to the topology atomtype list */
	copy_atomtype_atomtypes(atype,&(sys->atomtypes));

	if (debug)
    pr_symtab(debug,0,"After renum_atype",&sys->symtab);

  if (bVerbose) 
    fprintf(stderr,"converting bonded parameters...\n");
	
  ntype = get_atomtype_ntypes(atype);
  convert_params(ntype, plist, mi, comb, reppow, fudgeQQ, sys);
  	
	if(ir->implicit_solvent)
	{
		printf("Constructing Generalized Born topology...\n");

		/* Check for -normvsbds switch to grompp, necessary for gb together with vsites */
		if(bRmVSBds && nvsite)
		{
			fprintf(stderr, "ERROR: Must use -normvsbds switch to grompp when doing Generalized Born\n"
					"together with virtual sites\n");
			nerror++;
		}
		
		if (nerror)
		{
			print_warn_num(FALSE);
			gmx_fatal(FARGS,"There were %d error(s) processing your input",nerror);
		}
		
		generate_gb_topology(sys,mi);
	}
	
  if (debug)
    pr_symtab(debug,0,"After convert_params",&sys->symtab);

  /* set ptype to VSite for virtual sites */
  for(mt=0; mt<sys->nmoltype; mt++) {
    set_vsites_ptype(FALSE,&sys->moltype[mt]);
  }
  if (debug) {
    pr_symtab(debug,0,"After virtual sites",&sys->symtab);
  }
  /* Check velocity for virtual sites and shells */
  if (bGenVel) {
    check_vel(sys,state.v);
  }
    
  /* check masses */
  check_mol(sys);
  
  for(i=0; i<sys->nmoltype; i++) {
    check_cg_sizes(ftp2fn(efTOP,NFILE,fnm),&sys->moltype[i].cgs);
  }

  check_warning_error(FARGS);
	
  if (bVerbose) 
    fprintf(stderr,"initialising group options...\n");
  do_index(mdparin,ftp2fn_null(efNDX,NFILE,fnm),
	   sys,bVerbose,ir,
	   bGenVel ? state.v : NULL);
	
  /* Init the temperature coupling state */
  init_gtc_state(&state,ir->opts.ngtc);

  if (bVerbose)
    fprintf(stderr,"Checking consistency between energy and charge groups...\n");
  check_eg_vs_cg(sys);
  
  if (debug)
    pr_symtab(debug,0,"After index",&sys->symtab);
  triple_check(mdparin,ir,sys,&nerror);
  close_symtab(&sys->symtab);
  if (debug)
    pr_symtab(debug,0,"After close",&sys->symtab);

  /* make exclusions between QM atoms */
  if (ir->bQMMM) {
    generate_qmexcl(sys,ir);
  }

  if (ftp2bSet(efTRN,NFILE,fnm)) {
    if (bVerbose)
      fprintf(stderr,"getting data from old trajectory ...\n");
    cont_status(ftp2fn(efTRN,NFILE,fnm),ftp2fn_null(efEDR,NFILE,fnm),
		bNeedVel,bGenVel,fr_time,ir,&state,sys);
  }

  if (ir->ePBC==epbcXY && ir->nwall!=2)
    clear_rvec(state.box[ZZ]);
  
  if (EEL_FULL(ir->coulombtype)) {
    /* Calculate the optimal grid dimensions */
    copy_mat(state.box,box);
    if (ir->ePBC==epbcXY && ir->nwall==2)
      svmul(ir->wall_ewald_zfac,box[ZZ],box[ZZ]);
    max_spacing = calc_grid(stdout,box,opts->fourierspacing,
			    &(ir->nkx),&(ir->nky),&(ir->nkz),1);
    if ((ir->coulombtype == eelPPPM) && (max_spacing > 0.1)) {
      set_warning_line(mdparin,-1);
      sprintf(warn_buf,"Grid spacing larger then 0.1 while using PPPM.");
      warning_note(NULL);
    }
  }

  if (ir->ePull != epullNO)
    set_pull_init(ir,sys,state.x,state.box,opts->pull_start);

  /*  reset_multinr(sys); */
  
  if (EEL_PME(ir->coulombtype)) {
    float ratio = pme_load_estimate(sys,ir,state.box);
    fprintf(stderr,"Estimate for the relative computational load of the PME mesh part: %.2f\n",ratio);
    if (ratio > 0.5)
      warning_note("The optimal PME mesh load for parallel simulations is below 0.5\n"
		   "and for highly parallel simulations between 0.25 and 0.33,\n"
		   "for higher performance, increase the cut-off and the PME grid spacing");
  }

  {
    double cio = compute_io(ir,sys->natoms,&sys->groups,F_NRE,1);
    sprintf(warn_buf,"This run will generate roughly %.0f Mb of data",cio);
    if (cio > 2000) {
      set_warning_line(mdparin,-1);
      warning_note(NULL);
    } else {
      printf("%s\n",warn_buf);
    }
  }
	
  if (bVerbose) 
    fprintf(stderr,"writing run input file...\n");

  print_warn_num(TRUE);
  state.lambda = ir->init_lambda;
  write_tpx_state(ftp2fn(efTPX,NFILE,fnm),ir,&state,sys);
  
  thanx(stderr);
  
  return 0;
}
コード例 #4
0
ファイル: gmx_pme_error.c プロジェクト: andersx/gmx-debug
int gmx_pme_error(int argc,char *argv[])
{
    const char *desc[] = {
            "g_pme_error estimates the error of the electrostatic forces",
            "if using the SPME algorithm. The flag [TT]-tune[tt] will determine",
            "the splitting parameter such that the error is equally",
            "distributed over the real and reciprocal space part.",
            "As a part of the error stems from self interaction of the particles "
            "and is computationally very demanding a good a approximation is possible",
            "if just a fraction of the particles is used to calculate the average",
            "of this error by using the flag [TT]-self[tt].[PAR]",
    };

    int        repeats=2;
    real       fs=0.0;             /* 0 indicates: not set by the user */

    real        user_beta=-1.0;
    real        fracself=-1.0;
    
    
    t_perf      **perfdata;
    t_inputinfo info;
    t_state     state;     /* The state from the tpr input file */
    gmx_mtop_t  mtop;      /* The topology from the tpr input file */
    t_inputrec  *ir=NULL;  /* The inputrec from the tpr file */
    FILE        *fp=NULL;
    t_commrec   *cr;
    unsigned long PCA_Flags;
    gmx_bool        bTUNE=FALSE;


    static t_filenm fnm[] = {
      /* g_tune_pme */
      { efTPX, "-s",     NULL,    ffREAD },
      { efOUT, "-o",    "error",  ffWRITE },
      { efTPX, "-so",   "tuned",  ffOPTWR }
    };


    output_env_t oenv=NULL;

    t_pargs pa[] = {
      /***********************/
      /* g_tune_pme options: */
      /***********************/
        { "-beta",     FALSE, etREAL, {&user_beta},
            "If positive, overwrite ewald_beta from tpr file with this value" },
        { "-tune",     FALSE, etBOOL, {&bTUNE},
            "If flag is set the splitting parameter will be tuned to distribute the error equally in real and rec. space" },
        { "-self",     FALSE, etREAL, {&fracself},
            "If positive, determine selfinteraction error just over this fraction (default=1.0)" }
    };

    
#define NFILE asize(fnm)
    
    cr = init_par(&argc,&argv);
    
    if (MASTER(cr))
      CopyRight(stderr,argv[0]);
    
    PCA_Flags = PCA_NOEXIT_ON_ARGS;
    PCA_Flags |= (MASTER(cr) ? 0 : PCA_QUIET);
    
    parse_common_args(&argc,argv,PCA_Flags,
                      NFILE,fnm,asize(pa),pa,asize(desc),desc,
                      0,NULL,&oenv);        

    if (!bTUNE)
        bTUNE = opt2bSet("-so",NFILE,fnm);

    info.n_entries = 1;
    
    /* Allocate memory for the inputinfo struct: */
    create_info(&info);
    info.fourier_sp[0] = fs;
    
    /* Read in the tpr file and open logfile for reading */
    if (MASTER(cr))
    {
        snew(ir,1);
        read_tpr_file(opt2fn("-s",NFILE,fnm), &info, &state, &mtop, ir, user_beta,fracself);

        fp=fopen(opt2fn("-o",NFILE,fnm),"w");
    }
    
    /* Check consistency if the user provided fourierspacing */
    if (fs > 0 && MASTER(cr))
    {
        /* Recalculate the grid dimensions using fourierspacing from user input */
        info.nkx[0] = 0;
        info.nky[0] = 0;
        info.nkz[0] = 0;
        calc_grid(stdout,state.box,info.fourier_sp[0],&(info.nkx[0]),&(info.nky[0]),&(info.nkz[0]));
        if ( (ir->nkx != info.nkx[0]) || (ir->nky != info.nky[0]) || (ir->nkz != info.nkz[0]) )
            gmx_fatal(FARGS, "Wrong fourierspacing %f nm, input file grid = %d x %d x %d, computed grid = %d x %d x %d", 
                      fs,ir->nkx,ir->nky,ir->nkz,info.nkx[0],info.nky[0],info.nkz[0]);
    }
    
    /* Estimate (S)PME force error */

    /* Determine the volume of the simulation box */
    if (MASTER(cr))
    {
        info.volume = det(state.box);
        calc_recipbox(state.box,info.recipbox);
        info.natoms = mtop.natoms;
        info.bTUNE  = bTUNE;
    }   

    if (PAR(cr))
        bcast_info(&info, cr);
    
    /* Get an error estimate of the input tpr file */
    estimate_PME_error(&info, &state, &mtop, fp, cr);
    
    if (MASTER(cr))
    {
        ir->ewald_rtol=info.ewald_rtol[0];
        write_tpx_state(opt2fn("-so",NFILE,fnm),ir,&state,&mtop);
        please_cite(fp,"Wang2010");
        fclose(fp);
    }
    
    if (gmx_parallel_env_initialized())
    {
        gmx_finalize();
    }
    
    return 0;
}
コード例 #5
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;
}