Ejemplo n.º 1
0
void calc_listed_lambda(const t_idef *idef,
                        const rvec x[],
                        t_forcerec *fr,
                        const struct t_pbc *pbc, const struct t_graph *g,
                        gmx_grppairener_t *grpp, real *epot, t_nrnb *nrnb,
                        real *lambda,
                        const t_mdatoms *md,
                        t_fcdata *fcd,
                        int *global_atom_index)
{
    int           ftype, nr_nonperturbed, nr;
    real          v;
    real          dvdl_dum[efptNR] = {0};
    rvec         *f, *fshift;
    const  t_pbc *pbc_null;
    t_idef        idef_fe;

    if (fr->bMolPBC)
    {
        pbc_null = pbc;
    }
    else
    {
        pbc_null = NULL;
    }

    /* Copy the whole idef, so we can modify the contents locally */
    idef_fe          = *idef;
    idef_fe.nthreads = 1;
    snew(idef_fe.il_thread_division, F_NRE*(idef_fe.nthreads+1));

    /* We already have the forces, so we use temp buffers here */
    snew(f, fr->natoms_force);
    snew(fshift, SHIFTS);

    /* Loop over all bonded force types to calculate the bonded energies */
    for (ftype = 0; (ftype < F_NRE); ftype++)
    {
        if (ftype_is_bonded_potential(ftype))
        {
            /* Set the work range of thread 0 to the perturbed bondeds only */
            nr_nonperturbed                       = idef->il[ftype].nr_nonperturbed;
            nr                                    = idef->il[ftype].nr;
            idef_fe.il_thread_division[ftype*2+0] = nr_nonperturbed;
            idef_fe.il_thread_division[ftype*2+1] = nr;

            /* This is only to get the flop count correct */
            idef_fe.il[ftype].nr = nr - nr_nonperturbed;

            if (nr - nr_nonperturbed > 0)
            {
                v = calc_one_bond(0, ftype, &idef_fe,
                                  x, f, fshift, fr, pbc_null, g,
                                  grpp, nrnb, lambda, dvdl_dum,
                                  md, fcd, TRUE,
                                  global_atom_index);
                epot[ftype] += v;
            }
        }
    }

    sfree(fshift);
    sfree(f);

    sfree(idef_fe.il_thread_division);
}
Ejemplo n.º 2
0
void calc_listed_lambda(const t_idef *idef,
                        const rvec x[],
                        const t_forcerec *fr,
                        const struct t_pbc *pbc, const struct t_graph *g,
                        gmx_grppairener_t *grpp, real *epot, t_nrnb *nrnb,
                        const real *lambda,
                        const t_mdatoms *md,
                        t_fcdata *fcd,
                        int *global_atom_index)
{
    real               v;
    real               dvdl_dum[efptNR] = {0};
    rvec4             *f;
    rvec              *fshift;
    const  t_pbc      *pbc_null;
    t_idef             idef_fe;
    bonded_threading_t bondedThreading;

    if (fr->bMolPBC)
    {
        pbc_null = pbc;
    }
    else
    {
        pbc_null = nullptr;
    }

    /* Copy the whole idef, so we can modify the contents locally */
    idef_fe                  = *idef;
    bondedThreading.nthreads = 1;
    snew(bondedThreading.il_thread_division, F_NRE*(bondedThreading.nthreads+1));

    /* We already have the forces, so we use temp buffers here */
    snew(f, fr->natoms_force);
    snew(fshift, SHIFTS);

    /* Loop over all bonded force types to calculate the bonded energies */
    for (int ftype = 0; (ftype < F_NRE); ftype++)
    {
        if (ftype_is_bonded_potential(ftype))
        {
            const t_ilist &ilist     = idef->il[ftype];
            /* Create a temporary t_ilist with only perturbed interactions */
            t_ilist       &ilist_fe  = idef_fe.il[ftype];
            ilist_fe.iatoms          = ilist.iatoms + ilist.nr_nonperturbed;
            ilist_fe.nr_nonperturbed = 0;
            ilist_fe.nr              = ilist.nr - ilist.nr_nonperturbed;
            /* Set the work range of thread 0 to the perturbed bondeds */
            bondedThreading.il_thread_division[ftype*2 + 0] = 0;
            bondedThreading.il_thread_division[ftype*2 + 1] = ilist_fe.nr;

            if (ilist_fe.nr > 0)
            {
                v = calc_one_bond(0, ftype, &idef_fe, bondedThreading,
                                  x, f, fshift, fr, pbc_null, g,
                                  grpp, nrnb, lambda, dvdl_dum,
                                  md, fcd, TRUE,
                                  global_atom_index);
                epot[ftype] += v;
            }
        }
    }

    sfree(fshift);
    sfree(f);

    sfree(bondedThreading.il_thread_division);
}
Ejemplo n.º 3
0
void calc_listed(const gmx_multisim_t *ms,
                 gmx_wallcycle        *wcycle,
                 const t_idef *idef,
                 const rvec x[], history_t *hist,
                 rvec f[], t_forcerec *fr,
                 const struct t_pbc *pbc,
                 const struct t_pbc *pbc_full,
                 const struct t_graph *g,
                 gmx_enerdata_t *enerd, t_nrnb *nrnb,
                 real *lambda,
                 const t_mdatoms *md,
                 t_fcdata *fcd, int *global_atom_index,
                 int force_flags)
{
    gmx_bool      bCalcEnerVir;
    int           i;
    real          dvdl[efptNR]; /* The dummy array is to have a place to store the dhdl at other values
                                                        of lambda, which will be thrown away in the end*/
    const  t_pbc *pbc_null;
    int           thread;

    assert(fr->nthreads == idef->nthreads);

    bCalcEnerVir = (force_flags & (GMX_FORCE_VIRIAL | GMX_FORCE_ENERGY));

    for (i = 0; i < efptNR; i++)
    {
        dvdl[i] = 0.0;
    }
    if (fr->bMolPBC)
    {
        pbc_null = pbc;
    }
    else
    {
        pbc_null = NULL;
    }

#ifdef DEBUG
    if (g && debug)
    {
        p_graph(debug, "Bondage is fun", g);
    }
#endif

    if ((idef->il[F_POSRES].nr > 0) ||
        (idef->il[F_FBPOSRES].nr > 0) ||
        (idef->il[F_ORIRES].nr > 0) ||
        (idef->il[F_DISRES].nr > 0))
    {
        /* TODO Use of restraints triggers further function calls
           inside the loop over calc_one_bond(), but those are too
           awkward to account to this subtimer properly in the present
           code. We don't test / care much about performance with
           restraints, anyway. */
        wallcycle_sub_start(wcycle, ewcsRESTRAINTS);

        if (idef->il[F_POSRES].nr > 0)
        {
            posres_wrapper(nrnb, idef, pbc_full, x, enerd, lambda, fr);
        }

        if (idef->il[F_FBPOSRES].nr > 0)
        {
            fbposres_wrapper(nrnb, idef, pbc_full, x, enerd, fr);
        }

        /* Do pre force calculation stuff which might require communication */
        if (idef->il[F_ORIRES].nr > 0)
        {
            enerd->term[F_ORIRESDEV] =
                calc_orires_dev(ms, idef->il[F_ORIRES].nr,
                                idef->il[F_ORIRES].iatoms,
                                idef->iparams, md, x,
                                pbc_null, fcd, hist);
        }
        if (idef->il[F_DISRES].nr)
        {
            calc_disres_R_6(idef->il[F_DISRES].nr,
                            idef->il[F_DISRES].iatoms,
                            idef->iparams, x, pbc_null,
                            fcd, hist);
#ifdef GMX_MPI
            if (fcd->disres.nsystems > 1)
            {
                gmx_sum_sim(2*fcd->disres.nres, fcd->disres.Rt_6, ms);
            }
#endif
        }

        wallcycle_sub_stop(wcycle, ewcsRESTRAINTS);
    }

    wallcycle_sub_start(wcycle, ewcsLISTED);
#pragma omp parallel for num_threads(fr->nthreads) schedule(static)
    for (thread = 0; thread < fr->nthreads; thread++)
    {
        int                ftype;
        real              *epot, v;
        /* thread stuff */
        rvec              *ft, *fshift;
        real              *dvdlt;
        gmx_grppairener_t *grpp;

        if (thread == 0)
        {
            ft     = f;
            fshift = fr->fshift;
            epot   = enerd->term;
            grpp   = &enerd->grpp;
            dvdlt  = dvdl;
        }
        else
        {
            zero_thread_forces(&fr->f_t[thread], fr->natoms_force,
                               fr->red_nblock, 1<<fr->red_ashift);

            ft     = fr->f_t[thread].f;
            fshift = fr->f_t[thread].fshift;
            epot   = fr->f_t[thread].ener;
            grpp   = &fr->f_t[thread].grpp;
            dvdlt  = fr->f_t[thread].dvdl;
        }
        /* Loop over all bonded force types to calculate the bonded forces */
        for (ftype = 0; (ftype < F_NRE); ftype++)
        {
            if (idef->il[ftype].nr > 0 && ftype_is_bonded_potential(ftype))
            {
                v = calc_one_bond(thread, ftype, idef, x,
                                  ft, fshift, fr, pbc_null, g, grpp,
                                  nrnb, lambda, dvdlt,
                                  md, fcd, bCalcEnerVir,
                                  global_atom_index);
                epot[ftype] += v;
            }
        }
    }
    wallcycle_sub_stop(wcycle, ewcsLISTED);

    if (fr->nthreads > 1)
    {
        wallcycle_sub_start(wcycle, ewcsLISTED_BUF_OPS);
        reduce_thread_forces(fr->natoms_force, f, fr->fshift,
                             enerd->term, &enerd->grpp, dvdl,
                             fr->nthreads, fr->f_t,
                             fr->red_nblock, 1<<fr->red_ashift,
                             bCalcEnerVir,
                             force_flags & GMX_FORCE_DHDL);
        wallcycle_sub_stop(wcycle, ewcsLISTED_BUF_OPS);
    }

    /* Remaining code does not have enough flops to bother counting */
    if (force_flags & GMX_FORCE_DHDL)
    {
        for (i = 0; i < efptNR; i++)
        {
            enerd->dvdl_nonlin[i] += dvdl[i];
        }
    }

    /* Copy the sum of violations for the distance restraints from fcd */
    if (fcd)
    {
        enerd->term[F_DISRESVIOL] = fcd->disres.sumviol;

    }
}
Ejemplo n.º 4
0
/*! \brief Compute the bonded part of the listed forces, parallelized over threads
 */
static void
calcBondedForces(const t_idef     *idef,
                 const rvec        x[],
                 const t_forcerec *fr,
                 const t_pbc      *pbc_null,
                 const t_graph    *g,
                 gmx_enerdata_t   *enerd,
                 t_nrnb           *nrnb,
                 const real       *lambda,
                 real             *dvdl,
                 const t_mdatoms  *md,
                 t_fcdata         *fcd,
                 gmx_bool          bCalcEnerVir,
                 int              *global_atom_index)
{
    bonded_threading_t *bt = fr->bondedThreading;

#pragma omp parallel for num_threads(bt->nthreads) schedule(static)
    for (int thread = 0; thread < bt->nthreads; thread++)
    {
        try
        {
            int                ftype;
            real              *epot, v;
            /* thread stuff */
            rvec4             *ft;
            rvec              *fshift;
            real              *dvdlt;
            gmx_grppairener_t *grpp;

            zero_thread_output(bt, thread);

            ft = bt->f_t[thread].f;

            if (thread == 0)
            {
                fshift = fr->fshift;
                epot   = enerd->term;
                grpp   = &enerd->grpp;
                dvdlt  = dvdl;
            }
            else
            {
                fshift = bt->f_t[thread].fshift;
                epot   = bt->f_t[thread].ener;
                grpp   = &bt->f_t[thread].grpp;
                dvdlt  = bt->f_t[thread].dvdl;
            }
            /* Loop over all bonded force types to calculate the bonded forces */
            for (ftype = 0; (ftype < F_NRE); ftype++)
            {
                if (idef->il[ftype].nr > 0 && ftype_is_bonded_potential(ftype))
                {
                    v = calc_one_bond(thread, ftype, idef,
                                      *fr->bondedThreading, x,
                                      ft, fshift, fr, pbc_null, g, grpp,
                                      nrnb, lambda, dvdlt,
                                      md, fcd, bCalcEnerVir,
                                      global_atom_index);
                    epot[ftype] += v;
                }
            }
        }
        GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
    }
}