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;
}
Ejemplo n.º 2
0
int main(int argc, char* argv[])
{
    GLFWwindow window;
    double t, dt_total, t_old;

    if (!glfwInit())
    {
        fprintf(stderr, "GLFW initialization failed\n");
        exit(EXIT_FAILURE);
    }

    window = glfwOpenWindow(640, 480, GLFW_WINDOWED, "Wave Simulation", NULL);
    if (!window)
    {
        fprintf(stderr, "Could not open window\n");
        exit(EXIT_FAILURE);
    }

    glfwSwapInterval(1);

    // Keyboard handler
    glfwSetKeyCallback(key_callback);
    glfwSetInputMode(window, GLFW_KEY_REPEAT, GL_TRUE);

    // Window resize handler
    glfwSetWindowSizeCallback(window_resize_callback);
    glfwSetMouseButtonCallback(mouse_button_callback);
    glfwSetMousePosCallback(mouse_position_callback);
    glfwSetScrollCallback(scroll_callback);

    // Initialize OpenGL
    init_opengl();

    // Initialize simulation
    init_vertices();
    init_grid();
    adjust_grid();

    // Initialize timer
    t_old = glfwGetTime() - 0.01;

    while (running)
    {
        t = glfwGetTime();
        dt_total = t - t_old;
        t_old = t;

        // Safety - iterate if dt_total is too large
        while (dt_total > 0.f)
        {
            // Select iteration time step
            dt = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total;
            dt_total -= dt;

            // Calculate wave propagation
            calc_grid();
        }

        // Compute height of each vertex
        adjust_grid();

        // Draw wave grid to OpenGL display
        draw_scene();

        glfwPollEvents();

        // Still running?
        running = running && glfwIsWindow(window);
    }

    exit(EXIT_SUCCESS);
}
Ejemplo n.º 3
0
int main(int argc, char **argv)
{
    int c;
    int inflag = 0;
    int dbg = 0;
    int sr_ds = 200;
    char * rec_name = "vfdb/427";
    char * db_path = "/opt/physiobank/database";
    size_t win_sec = 8;
    /* r stands for record with folder
     * p for path
     * i for information of record
     * s downsample sr
     * w window length default:8
     * d debug
     */
    while ((c = getopt(argc, argv, "idr:p:s:w:")) != -1)
        switch (c){
            case 'i':
                inflag = 1; 
                break;
            case 'r':
                rec_name = optarg;
                break;
            case 'p':
                db_path = optarg;
                break;
            case 's':
                sr_ds= atoi(optarg);
                break;
            case'w':
                win_sec = atoi(optarg);
                break;
            case'd':
                dbg = 1;
                break;
            default:
                abort();
        }            
    int i, j, nsig;
    WFDB_Sample *v;
    WFDB_Siginfo *s;
    WFDB_Anninfo a;
    setwfdb(db_path);
    
    nsig = isigopen(rec_name, NULL, 0);
    if (nsig < 1){
        printf("nsig:%d\n",nsig);
        exit(1);
    }
    s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo));
    if (isigopen(rec_name, s, nsig) != nsig)
        exit(1);
    v = (WFDB_Sample *)malloc(nsig * sizeof(WFDB_Sample));

    int orig_sr = sampfreq(rec_name);
    a.name = "atr"; a.stat = WFDB_READ;
    if (wfdbinit(rec_name, &a, 1, s, nsig) != nsig) exit(3);
    if(1 == inflag ){
        printf("sr:%d\n",orig_sr);
        printf("%d signals\n", nsig);
        for (i = 0; i < nsig; i++) {
            printf("Group %d, Signal %d:\n", s[i].group, i); 
            printf("File: %s\n", s[i].fname);
            printf("Description: %s\n", s[i].desc);
            printf("Gain: ");
            if (s[i].gain == 0.) 
                printf("uncalibrated; assume %g", WFDB_DEFGAIN);
            else printf("%g", s[i].gain);
            printf(" adu/%s\n", s[i].units ? s[i].units : "mV");
            printf(" Initial value: %d\n", s[i].initval);
            printf(" Storage format: %d\n", s[i].fmt);
            printf(" I/O: ");
            if (s[i].bsize == 0) printf("can be unbuffered\n");
            else printf("%d-byte blocks\n", s[i].bsize);
            printf(" ADC resolution: %d bits\n", s[i].adcres);
            printf(" ADC zero: %d\n", s[i].adczero);
            if (s[i].nsamp > 0L) {
                printf(" Length: %s (%ld sample intervals)\n",
                       timstr(s[i].nsamp), s[i].nsamp);
                printf(" Checksum: %d\n", s[i].cksum);
            }
            else printf(" Length undefined\n");
        }
    }

    fifo_t fifo_ecg;
    int fifo_ecg_buf[FIFO_SIZE];
    fifo_init(&fifo_ecg, fifo_ecg_buf, FIFO_SIZE);

    fifo_t fifo_bt;
    int fifo_bt_buf[FIFO_SIZE];
    fifo_init(&fifo_bt, fifo_bt_buf, FIFO_SIZE);

    int tmp = 0;
    int sr = 200;
    WFDB_Time begin_samp = 0;
    WFDB_Time end_samp = orig_sr*win_sec;
    WFDB_Annotation begin_ann;
    WFDB_Annotation end_ann;
    getann(0, &begin_ann);
    while(0 == getann(0, &end_ann))
         if ((end_ann.aux != NULL && *end_ann.aux > 0)
                    ||0 == strcmp(annstr(end_ann.anntyp), "[")
                    ||0 == strcmp(annstr(end_ann.anntyp), "]")
                    ||0 == strcmp(annstr(end_ann.anntyp), "~")
                ){
            break;
        }
    
    int * pBt_len = (int*)calloc(win_sec,sizeof(int));
    ResetBDAC();
    for (; ;) {
        if (getvec(v) < 0)
            break;
//        for (j = 0; j < nsig; j++){
//        }
        tmp = v[nsig-1];
        tmp = v[0];
        int vout1 = 0;
        static int bt_i = 0;
        static unsigned int samplecnt = 0;
        int idx = 0;
        if(down_sample(tmp, &vout1, orig_sr, sr)) {
                samplecnt ++;
                fifo_write(&fifo_ecg, &vout1, 1*sizeof(int));
                int beatType, beatMatch;
                long ltmp = vout1-s[0].adczero;
                ltmp *= 200; ltmp /= s[0].gain;
                int bdac_dly = BeatDetectAndClassify(ltmp, &beatType, &beatMatch);
                idx = bt_i/sr;
                if (0 != bdac_dly ) {
                    pBt_len[idx]++;
                    fifo_write(&fifo_bt, &beatType, sizeof(int));
                }
                bt_i = ++bt_i%(win_sec*sr);
        }

        double cm = 0.0;

        int size = win_sec*sr;
        if(fifo_len(&fifo_ecg)/sizeof(int) >= sr*win_sec){
            int * win_data = (int*)malloc(win_sec*sr*sizeof(int));
            int * ds_data = (int*)malloc(win_sec*sr_ds*sizeof(int));
            
            int len = fifo_len(&fifo_bt)/sizeof(int);
            int * p = (int*)calloc(len, sizeof(int));
           
            if (0 != len){
               //printf("bt_i:%d\n", bt_i);
                fifo_read_steps(&fifo_bt, p, len*sizeof(int), pBt_len[bt_i/sr]*sizeof(int));
                //for (i = 0;i< len;i++) printf("%d ", p[i]);
                //printf("\n");

            }
            pBt_len[bt_i/sr] = 0;
            
            fifo_read_steps(&fifo_ecg, win_data, size*sizeof(int), sr*sizeof(int));
            filtering(win_data, size, sr);
            int i = 0;
            int ds_size = 0;
            int vout;
            for(i = 0;i < size;i++){
               // if(down_sample(win_data[i], &vout, sr, sr_ds)) ds_data[ds_size++] = vout;
            }
            double dven = 0.0;

            if (0 != len){
                int tmp_cnt = 0;
                for(i = 0; i < len ; i++){
                    if(5 == p[i]) dven ++;
                }
                //printf("div:%d %d\n", tmp_cnt, len);
                dven /= len; 
            }
                         
            //cm = ecg_complexity_measure(win_data, size);
            //cm = ecg_complexity_measure(ds_data, ds_size);
            //cm = cpsd(ds_data, ds_size, 0.5*sr_ds);
            //cm = calc_grid(ds_data, ds_size, 0.5*sr_ds);
            cm = calc_grid(win_data, size, 0.5*sr);


        
            if (-1 == cm ) continue;
            //VT print 1;
            //VF print 2;
            
            int hr =  (int)((double)(len*60)/win_sec+0.5);
            int ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(VT");
            if (1 == ret){
                printf("%d %lf %lf %d\n", 1, cm, dven, hr);
            } else if (0 == ret) {
                ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(VFL");
                int ret2 = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "[");
                if (1 == ret || 1 == ret2){
                    printf("%d %lf %lf %d\n", 2, cm, dven, hr);
                } else if (0 == ret){
//                    ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(N");
//                    int ret3 = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "N");
//                    if ((1 == ret  || 1 == ret3) && -1 != begin_ann.subtyp) printf ("%d %lf %lf %d\n", 0, cm, dven, hr); 

                    if (1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(AFIB") 
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(AFL")
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(IVR")
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(SVTA")
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(SBR")
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(BII")
                       ) printf ("%d %lf %lf %d\n", 0, cm, dven, hr); 
                    
                   // int ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(SVTA");
                   // if (1 == ret)  printf ("%d %lf\n", 0, cm); 
                }
            }
            //iannsettime(begin_samp);
            begin_samp += orig_sr;
            end_samp += orig_sr;
            if(end_ann.time < begin_samp){
                begin_ann = end_ann;
                
                while(1)
                    if (0 != getann(0, &end_ann)){
                        end_ann = begin_ann;
                        /*the last sample of the signal*/
                        end_ann.time = s[nsig-1].nsamp;
                        break;
                    }else if ((end_ann.aux != NULL && *end_ann.aux > 0)
                                ||0 == strcmp(annstr(end_ann.anntyp), "[")
                                ||0 == strcmp(annstr(end_ann.anntyp), "]")
                                ||0 == strcmp(annstr(end_ann.anntyp), "~")
                            ){
                        break;
                    }
                if(dbg){
                    printf("begin tm:%s type:%s ", mstimstr(begin_ann.time), annstr(begin_ann.anntyp));
                    if(begin_ann.aux != NULL)
                        printf("begin aux:%s", begin_ann.aux+1);
                    printf("\n");
                    printf("end tm:%s type:%s ", mstimstr(end_ann.time), annstr(end_ann.anntyp));
                    if (end_ann.aux != NULL)
                        printf("end aux:%s", end_ann.aux+1);
                    printf("\n");

                    printf("begin sample:%s\n", mstimstr(begin_samp));
                    printf("ann diff:%s\n", mstimstr(end_ann.time-begin_ann.time));
                }
            }
            free(p);
            free(ds_data);
            free(win_data);
        }

    }
    free(pBt_len);
    wfdbquit();
    return 0;
}
Ejemplo n.º 4
0
static gmx_bool pme_loadbal_increase_cutoff(pme_load_balancing_t  pme_lb,
                                            int                   pme_order,
                                            const gmx_domdec_t   *dd)
{
    pme_setup_t *set;
    int          npmenodes_x, npmenodes_y;
    real         fac, sp;
    real         tmpr_coulomb, tmpr_vdw;
    int          d;
    gmx_bool     grid_ok;

    /* Try to add a new setup with next larger cut-off to the list */
    pme_lb->n++;
    srenew(pme_lb->setup, pme_lb->n);
    set          = &pme_lb->setup[pme_lb->n-1];
    set->pmedata = NULL;

    get_pme_nnodes(dd, &npmenodes_x, &npmenodes_y);

    fac = 1;
    do
    {
        /* Avoid infinite while loop, which can occur at the minimum grid size.
         * Note that in practice load balancing will stop before this point.
         * The factor 2.1 allows for the extreme case in which only grids
         * of powers of 2 are allowed (the current code supports more grids).
         */
        if (fac > 2.1)
        {
            pme_lb->n--;

            return FALSE;
        }

        fac *= 1.01;
        clear_ivec(set->grid);
        sp = calc_grid(NULL, pme_lb->box_start,
                       fac*pme_lb->setup[pme_lb->cur].spacing,
                       &set->grid[XX],
                       &set->grid[YY],
                       &set->grid[ZZ]);

        /* As here we can't easily check if one of the PME nodes
         * uses threading, we do a conservative grid check.
         * This means we can't use pme_order or less grid lines
         * per PME node along x, which is not a strong restriction.
         */
        gmx_pme_check_restrictions(pme_order,
                                   set->grid[XX], set->grid[YY], set->grid[ZZ],
                                   npmenodes_x, npmenodes_y,
                                   TRUE,
                                   FALSE,
                                   &grid_ok);
    }
    while (sp <= 1.001*pme_lb->setup[pme_lb->cur].spacing || !grid_ok);

    set->rcut_coulomb = pme_lb->cut_spacing*sp;
    if (set->rcut_coulomb < pme_lb->rcut_coulomb_start)
    {
        /* This is unlikely, but can happen when e.g. continuing from
         * a checkpoint after equilibration where the box shrank a lot.
         * We want to avoid rcoulomb getting smaller than rvdw
         * and there might be more issues with decreasing rcoulomb.
         */
        set->rcut_coulomb = pme_lb->rcut_coulomb_start;
    }

    if (pme_lb->cutoff_scheme == ecutsVERLET)
    {
        set->rlist        = set->rcut_coulomb + pme_lb->rbuf_coulomb;
        /* We dont use LR lists with Verlet, but this avoids if-statements in further checks */
        set->rlistlong    = set->rlist;
    }
    else
    {
        tmpr_coulomb          = set->rcut_coulomb + pme_lb->rbuf_coulomb;
        tmpr_vdw              = pme_lb->rcut_vdw + pme_lb->rbuf_vdw;
        set->rlist            = min(tmpr_coulomb, tmpr_vdw);
        set->rlistlong        = max(tmpr_coulomb, tmpr_vdw);

        /* Set the long-range update frequency */
        if (set->rlist == set->rlistlong)
        {
            /* No long-range interactions if the short-/long-range cutoffs are identical */
            set->nstcalclr = 0;
        }
        else if (pme_lb->nstcalclr_start == 0 || pme_lb->nstcalclr_start == 1)
        {
            /* We were not doing long-range before, but now we are since rlist!=rlistlong */
            set->nstcalclr = 1;
        }
        else
        {
            /* We were already doing long-range interactions from the start */
            if (pme_lb->rcut_vdw > pme_lb->rcut_coulomb_start)
            {
                /* We were originally doing long-range VdW-only interactions.
                 * If rvdw is still longer than rcoulomb we keep the original nstcalclr,
                 * but if the coulomb cutoff has become longer we should update the long-range
                 * part every step.
                 */
                set->nstcalclr = (tmpr_vdw > tmpr_coulomb) ? pme_lb->nstcalclr_start : 1;
            }
            else
            {
                /* We were not doing any long-range interaction from the start,
                 * since it is not possible to do twin-range coulomb for the PME interaction.
                 */
                set->nstcalclr = 1;
            }
        }
    }

    set->spacing      = sp;
    /* The grid efficiency is the size wrt a grid with uniform x/y/z spacing */
    set->grid_efficiency = 1;
    for (d = 0; d < DIM; d++)
    {
        set->grid_efficiency *= (set->grid[d]*sp)/norm(pme_lb->box_start[d]);
    }
    /* The Ewald coefficient is inversly proportional to the cut-off */
    set->ewaldcoeff_q =
        pme_lb->setup[0].ewaldcoeff_q*pme_lb->setup[0].rcut_coulomb/set->rcut_coulomb;
    /* We set ewaldcoeff_lj in set, even when LJ-PME is not used */
    set->ewaldcoeff_lj =
        pme_lb->setup[0].ewaldcoeff_lj*pme_lb->setup[0].rcut_coulomb/set->rcut_coulomb;

    set->count   = 0;
    set->cycles  = 0;

    if (debug)
    {
        fprintf(debug, "PME loadbal: grid %d %d %d, coulomb cutoff %f\n",
                set->grid[XX], set->grid[YY], set->grid[ZZ], set->rcut_coulomb);
    }
    return TRUE;
}
Ejemplo n.º 5
0
static gmx_bool pme_loadbal_increase_cutoff(pme_load_balancing_t pme_lb,
                                            int                  pme_order)
{
    pme_setup_t *set;
    real         fac, sp;
    real         tmpr_coulomb, tmpr_vdw;
    int          d;

    /* Try to add a new setup with next larger cut-off to the list */
    pme_lb->n++;
    srenew(pme_lb->setup, pme_lb->n);
    set          = &pme_lb->setup[pme_lb->n-1];
    set->pmedata = NULL;

    fac = 1;
    do
    {
        fac *= 1.01;
        clear_ivec(set->grid);
        sp = calc_grid(NULL, pme_lb->box_start,
                       fac*pme_lb->setup[pme_lb->cur].spacing,
                       &set->grid[XX],
                       &set->grid[YY],
                       &set->grid[ZZ]);

        /* In parallel we can't have grids smaller than 2*pme_order,
         * and we would anyhow not gain much speed at these grid sizes.
         */
        for (d = 0; d < DIM; d++)
        {
            if (set->grid[d] <= 2*pme_order)
            {
                pme_lb->n--;

                return FALSE;
            }
        }
    }
    while (sp <= 1.001*pme_lb->setup[pme_lb->cur].spacing);

    set->rcut_coulomb = pme_lb->cut_spacing*sp;

    if (pme_lb->cutoff_scheme == ecutsVERLET)
    {
        set->rlist        = set->rcut_coulomb + pme_lb->rbuf_coulomb;
        /* We dont use LR lists with Verlet, but this avoids if-statements in further checks */
        set->rlistlong    = set->rlist;
    }
    else
    {
        tmpr_coulomb          = set->rcut_coulomb + pme_lb->rbuf_coulomb;
        tmpr_vdw              = pme_lb->rcut_vdw + pme_lb->rbuf_vdw;
        set->rlist            = min(tmpr_coulomb, tmpr_vdw);
        set->rlistlong        = max(tmpr_coulomb, tmpr_vdw);

        /* Set the long-range update frequency */
        if (set->rlist == set->rlistlong)
        {
            /* No long-range interactions if the short-/long-range cutoffs are identical */
            set->nstcalclr = 0;
        }
        else if (pme_lb->nstcalclr_start == 0 || pme_lb->nstcalclr_start == 1)
        {
            /* We were not doing long-range before, but now we are since rlist!=rlistlong */
            set->nstcalclr = 1;
        }
        else
        {
            /* We were already doing long-range interactions from the start */
            if (pme_lb->rcut_vdw > pme_lb->rcut_coulomb_start)
            {
                /* We were originally doing long-range VdW-only interactions.
                 * If rvdw is still longer than rcoulomb we keep the original nstcalclr,
                 * but if the coulomb cutoff has become longer we should update the long-range
                 * part every step.
                 */
                set->nstcalclr = (tmpr_vdw > tmpr_coulomb) ? pme_lb->nstcalclr_start : 1;
            }
            else
            {
                /* We were not doing any long-range interaction from the start,
                 * since it is not possible to do twin-range coulomb for the PME interaction.
                 */
                set->nstcalclr = 1;
            }
        }
    }

    set->spacing      = sp;
    /* The grid efficiency is the size wrt a grid with uniform x/y/z spacing */
    set->grid_efficiency = 1;
    for (d = 0; d < DIM; d++)
    {
        set->grid_efficiency *= (set->grid[d]*sp)/norm(pme_lb->box_start[d]);
    }
    /* The Ewald coefficient is inversly proportional to the cut-off */
    set->ewaldcoeff =
        pme_lb->setup[0].ewaldcoeff*pme_lb->setup[0].rcut_coulomb/set->rcut_coulomb;

    set->count   = 0;
    set->cycles  = 0;

    if (debug)
    {
        fprintf(debug, "PME loadbal: grid %d %d %d, coulomb cutoff %f\n",
                set->grid[XX], set->grid[YY], set->grid[ZZ], set->rcut_coulomb);
    }
    return TRUE;
}
Ejemplo n.º 6
0
int main(int argc, char* argv[])
{
    GLFWwindow* window;
    double t, dt_total, t_old;
    int width, height;

    glfwSetErrorCallback(error_callback);

    if (!glfwInit())
        exit(EXIT_FAILURE);

    window = glfwCreateWindow(640, 480, "Wave Simulation", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    glfwSetKeyCallback(window, key_callback);
    glfwSetWindowSizeCallback(window, window_size_callback);
    glfwSetMouseButtonCallback(window, mouse_button_callback);
    glfwSetCursorPosCallback(window, cursor_position_callback);
    glfwSetScrollCallback(window, scroll_callback);

    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    glfwGetWindowSize(window, &width, &height);
    window_size_callback(window, width, height);

    // Initialize OpenGL
    init_opengl();

    // Initialize simulation
    init_vertices();
    init_grid();
    adjust_grid();

    // Initialize timer
    t_old = glfwGetTime() - 0.01;

    while (!glfwWindowShouldClose(window))
    {
        t = glfwGetTime();
        dt_total = t - t_old;
        t_old = t;

        // Safety - iterate if dt_total is too large
        while (dt_total > 0.f)
        {
            // Select iteration time step
            dt = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total;
            dt_total -= dt;

            // Calculate wave propagation
            calc_grid();
        }

        // Compute height of each vertex
        adjust_grid();

        // Draw wave grid to OpenGL display
        draw_scene(window);

        glfwPollEvents();
    }

    exit(EXIT_SUCCESS);
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
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;
}