示例#1
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;

    }
}
示例#2
0
static void check_viol(FILE *log,t_commrec *cr,
		       t_ilist *disres,t_iparams forceparams[],
		       t_functype functype[],rvec x[],rvec f[],
		       t_forcerec *fr,t_pbc *pbc,t_graph *g,t_dr_result dr[],
		       int clust_id,int isize,atom_id index[],real vvindex[],
		       t_fcdata *fcd)
{
  t_iatom *forceatoms;
  int     i,j,nat,n,type,nviol,ndr,label;
  real    ener,rt,mviol,tviol,viol,lam,dvdl,drt;
  static  gmx_bool bFirst=TRUE;
  
  lam  =0;
  dvdl =0;
  tviol=0;
  nviol=0;
  mviol=0;
  ndr=0;
  if (ntop)
    reset5();
  forceatoms=disres->iatoms;
  for(j=0; (j<isize); j++) {
    vvindex[j]=0;
  }
  nat = interaction_function[F_DISRES].nratoms+1; 
  for(i=0; (i<disres->nr); ) {
    type  = forceatoms[i];
    n     = 0;
    label = forceparams[type].disres.label;
    if (debug) 
      fprintf(debug,"DISRE: ndr = %d, label = %d  i=%d, n =%d\n",
	      ndr,label,i,n);
    if (ndr != label) 
      gmx_fatal(FARGS,"tpr inconsistency. ndr = %d, label = %d\n",ndr,label);
    do {
      n += nat;
    } while (((i+n) < disres->nr) && 
	     (forceparams[forceatoms[i+n]].disres.label == label));
    
    calc_disres_R_6(cr->ms,n,&forceatoms[i],forceparams,
		    (const rvec*)x,pbc,fcd,NULL);

    if (fcd->disres.Rt_6[0] <= 0) 
      gmx_fatal(FARGS,"ndr = %d, rt_6 = %f",ndr,fcd->disres.Rt_6[0]);
    
    rt = pow(fcd->disres.Rt_6[0],-1.0/6.0);
    dr[clust_id].aver1[ndr]  += rt;
    dr[clust_id].aver2[ndr]  += sqr(rt);
    drt = pow(rt,-3.0);
    dr[clust_id].aver_3[ndr] += drt;
    dr[clust_id].aver_6[ndr] += fcd->disres.Rt_6[0];
    
    ener=interaction_function[F_DISRES].ifunc(n,&forceatoms[i],forceparams,
					      (const rvec*)x,f,fr->fshift,
					      pbc,g,lam,&dvdl,NULL,fcd,NULL);
    viol = fcd->disres.sumviol;
    
    if (viol > 0) {
      nviol++;
      if (ntop)
	add5(forceparams[type].disres.label,viol);
      if (viol > mviol) 
	mviol = viol;
      tviol += viol;
      for(j=0; (j<isize); j++) {
	if (index[j] == forceparams[type].disres.label)
	  vvindex[j]=pow(fcd->disres.Rt_6[0],-1.0/6.0);
	}
    }
    ndr ++;
    i   += n;
  }
  dr[clust_id].nv   = nviol;
  dr[clust_id].maxv = mviol;
  dr[clust_id].sumv = tviol;
  dr[clust_id].averv= tviol/ndr;
  dr[clust_id].nframes++;
  
  if (bFirst) {
    fprintf(stderr,"\nThere are %d restraints and %d pairs\n",
	    ndr,disres->nr/nat);
    bFirst = FALSE;
  }
  if (ntop)
    print5(log);
}
示例#3
0
void calc_listed(const t_commrec             *cr,
                 const gmx_multisim_t *ms,
                 struct gmx_wallcycle        *wcycle,
                 const t_idef *idef,
                 const rvec x[], history_t *hist,
                 rvec f[],
                 gmx::ForceWithVirial *forceWithVirial,
                 const 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,
                 const real *lambda,
                 const t_mdatoms *md,
                 t_fcdata *fcd, int *global_atom_index,
                 int force_flags)
{
    gmx_bool                   bCalcEnerVir;
    const  t_pbc              *pbc_null;
    bonded_threading_t        *bt  = fr->bondedThreading;

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

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

    if ((idef->il[F_POSRES].nr > 0) ||
        (idef->il[F_FBPOSRES].nr > 0) ||
        fcd->orires.nr > 0 ||
        fcd->disres.nres > 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,
                           forceWithVirial);
        }

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

        /* Do pre force calculation stuff which might require communication */
        if (fcd->orires.nr > 0)
        {
            /* This assertion is to ensure we have whole molecules.
             * Unfortunately we do not have an mdrun state variable that tells
             * us if molecules in x are not broken over PBC, so we have to make
             * do with checking graph!=nullptr, which should tell us if we made
             * molecules whole before calling the current function.
             */
            GMX_RELEASE_ASSERT(fr->ePBC == epbcNONE || g != nullptr, "With orientation restraints molecules should be whole");
            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 (fcd->disres.nres > 0)
        {
            calc_disres_R_6(cr, ms,
                            idef->il[F_DISRES].nr,
                            idef->il[F_DISRES].iatoms,
                            x, pbc_null,
                            fcd, hist);
        }

        wallcycle_sub_stop(wcycle, ewcsRESTRAINTS);
    }

    if (bt->haveBondeds)
    {
        wallcycle_sub_start(wcycle, ewcsLISTED);
        /* 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 */
        real dvdl[efptNR] = {0};
        calcBondedForces(idef, x, fr, pbc_null, g, enerd, nrnb, lambda, dvdl, md,
                         fcd, bCalcEnerVir, global_atom_index);
        wallcycle_sub_stop(wcycle, ewcsLISTED);

        wallcycle_sub_start(wcycle, ewcsLISTED_BUF_OPS);
        reduce_thread_output(fr->natoms_force, f, fr->fshift,
                             enerd->term, &enerd->grpp, dvdl,
                             bt,
                             bCalcEnerVir,
                             (force_flags & GMX_FORCE_DHDL) != 0);

        if (force_flags & GMX_FORCE_DHDL)
        {
            for (int i = 0; i < efptNR; i++)
            {
                enerd->dvdl_nonlin[i] += dvdl[i];
            }
        }
        wallcycle_sub_stop(wcycle, ewcsLISTED_BUF_OPS);
    }

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