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; } }
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); }
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; } }