real do_listed_vdw_q(int ftype,int nbonds, const t_iatom iatoms[],const t_iparams iparams[], const rvec x[],rvec f[],rvec fshift[], const t_pbc *pbc,const t_graph *g, real lambda,real *dvdlambda, const t_mdatoms *md, const t_forcerec *fr,gmx_grppairener_t *grppener, int *global_atom_index) { static gmx_bool bWarn=FALSE; real eps,r2,*tab,rtab2=0; rvec dx,x14[2],f14[2]; int i,ai,aj,itype; int typeA[2]={0,0},typeB[2]={0,1}; real chargeA[2]={0,0},chargeB[2]; int gid,shift_vir,shift_f; int j_index[] = { 0, 1 }; int i0=0,i1=1,i2=2; ivec dt; int outeriter,inneriter; int nthreads = 1; int count; real krf,crf,tabscale; int ntype=0; real *nbfp=NULL; real *egnb=NULL,*egcoul=NULL; t_nblist tmplist; int icoul,ivdw; gmx_bool bMolPBC,bFreeEnergy; t_pf_global *pf_global; #if GMX_THREAD_SHM_FDECOMP pthread_mutex_t mtx; #else void * mtx = NULL; #endif #if GMX_THREAD_SHM_FDECOMP pthread_mutex_initialize(&mtx); #endif bMolPBC = fr->bMolPBC; pf_global = fr->pf_global; switch (ftype) { case F_LJ14: case F_LJC14_Q: eps = fr->epsfac*fr->fudgeQQ; ntype = 1; egnb = grppener->ener[egLJ14]; egcoul = grppener->ener[egCOUL14]; break; case F_LJC_PAIRS_NB: eps = fr->epsfac; ntype = 1; egnb = grppener->ener[egLJSR]; egcoul = grppener->ener[egCOULSR]; break; default: gmx_fatal(FARGS,"Unknown function type %d in do_nonbonded14", ftype); } tab = fr->tab14.tab; rtab2 = sqr(fr->tab14.r); tabscale = fr->tab14.scale; krf = fr->k_rf; crf = fr->c_rf; /* Determine the values for icoul/ivdw. */ if (fr->bEwald) { icoul = 1; } else if(fr->bcoultab) { icoul = 3; } else if(fr->eeltype == eelRF_NEC) { icoul = 2; } else { icoul = 1; } if(fr->bvdwtab) { ivdw = 3; } else if(fr->bBHAM) { ivdw = 2; } else { ivdw = 1; } /* We don't do SSE or altivec here, due to large overhead for 4-fold * unrolling on short lists */ bFreeEnergy = FALSE; for(i=0; (i<nbonds); ) { itype = iatoms[i++]; ai = iatoms[i++]; aj = iatoms[i++]; gid = GID(md->cENER[ai],md->cENER[aj],md->nenergrp); switch (ftype) { case F_LJ14: bFreeEnergy = (fr->efep != efepNO && ((md->nPerturbed && (md->bPerturbed[ai] || md->bPerturbed[aj])) || iparams[itype].lj14.c6A != iparams[itype].lj14.c6B || iparams[itype].lj14.c12A != iparams[itype].lj14.c12B)); chargeA[0] = md->chargeA[ai]; chargeA[1] = md->chargeA[aj]; nbfp = (real *)&(iparams[itype].lj14.c6A); break; case F_LJC14_Q: eps = fr->epsfac*iparams[itype].ljc14.fqq; chargeA[0] = iparams[itype].ljc14.qi; chargeA[1] = iparams[itype].ljc14.qj; nbfp = (real *)&(iparams[itype].ljc14.c6); break; case F_LJC_PAIRS_NB: chargeA[0] = iparams[itype].ljcnb.qi; chargeA[1] = iparams[itype].ljcnb.qj; nbfp = (real *)&(iparams[itype].ljcnb.c6); break; } if (!bMolPBC) { /* This is a bonded interaction, atoms are in the same box */ shift_f = CENTRAL; r2 = distance2(x[ai],x[aj]); } else { /* Apply full periodic boundary conditions */ shift_f = pbc_dx_aiuc(pbc,x[ai],x[aj],dx); r2 = norm2(dx); } if (r2 >= rtab2) { if (!bWarn) { fprintf(stderr,"Warning: 1-4 interaction between %d and %d " "at distance %.3f which is larger than the 1-4 table size %.3f nm\n", glatnr(global_atom_index,ai), glatnr(global_atom_index,aj), sqrt(r2), sqrt(rtab2)); fprintf(stderr,"These are ignored for the rest of the simulation\n"); fprintf(stderr,"This usually means your system is exploding,\n" "if not, you should increase table-extension in your mdp file\n" "or with user tables increase the table size\n"); bWarn = TRUE; } if (debug) fprintf(debug,"%8f %8f %8f\n%8f %8f %8f\n1-4 (%d,%d) interaction not within cut-off! r=%g. Ignored\n", x[ai][XX],x[ai][YY],x[ai][ZZ], x[aj][XX],x[aj][YY],x[aj][ZZ], glatnr(global_atom_index,ai), glatnr(global_atom_index,aj), sqrt(r2)); } else { copy_rvec(x[ai],x14[0]); copy_rvec(x[aj],x14[1]); clear_rvec(f14[0]); clear_rvec(f14[1]); #ifdef DEBUG fprintf(debug,"LJ14: grp-i=%2d, grp-j=%2d, ngrp=%2d, GID=%d\n", md->cENER[ai],md->cENER[aj],md->nenergrp,gid); #endif outeriter = inneriter = count = 0; if (bFreeEnergy) { chargeB[0] = md->chargeB[ai]; chargeB[1] = md->chargeB[aj]; /* We pass &(iparams[itype].lj14.c6A) as LJ parameter matrix * to the innerloops. * Here we use that the LJ-14 parameters are stored in iparams * as c6A,c12A,c6B,c12B, which are referenced correctly * in the innerloops if we assign type combinations 0-0 and 0-1 * to atom pair ai-aj in topologies A and B respectively. */ if(ivdw==2) { gmx_fatal(FARGS,"Cannot do free energy Buckingham interactions."); } count = 0; gmx_nb_free_energy_kernel(icoul, ivdw, i1, &i0, j_index, &i1, &shift_f, fr->shift_vec[0], fshift[0], &gid, x14[0], f14[0], chargeA, chargeB, eps, krf, crf, fr->ewaldcoeff, egcoul, typeA, typeB, ntype, nbfp, egnb, tabscale, tab, lambda, dvdlambda, fr->sc_alpha, fr->sc_power, fr->sc_sigma6_def, fr->sc_sigma6_min, TRUE, &outeriter, &inneriter); } else { /* Not perturbed - call kernel 330 */ nb_kernel330 ( &i1, &i0, j_index, &i1, &shift_f, fr->shift_vec[0], fshift[0], &gid, x14[0], f14[0], chargeA, &eps, &krf, &crf, egcoul, typeA, &ntype, nbfp, egnb, &tabscale, tab, NULL, NULL, NULL, NULL, &nthreads, &count, (void *)&mtx, &outeriter, &inneriter, NULL); } /* Add the forces */ rvec_inc(f[ai],f14[0]); rvec_dec(f[aj],f14[0]); if (pf_global->bInitialized) pf_atom_add_bonded(pf_global, ai, aj, PF_INTER_NB14, f14[0]); if (g) { /* Correct the shift forces using the graph */ ivec_sub(SHIFT_IVEC(g,ai),SHIFT_IVEC(g,aj),dt); shift_vir = IVEC2IS(dt); rvec_inc(fshift[shift_vir],f14[0]); rvec_dec(fshift[CENTRAL],f14[0]); } /* flops: eNR_KERNEL_OUTER + eNR_KERNEL330 + 12 */ } } return 0.0; }
real orires(int nfa,const t_iatom forceatoms[],const t_iparams ip[], const rvec x[],rvec f[],rvec fshift[], const t_pbc *pbc,const t_graph *g, real lambda,real *dvdlambda, const t_mdatoms *md,t_fcdata *fcd, int *global_atom_index,int ftype,gmx_mc_move *mc_move) { atom_id ai,aj; int fa,d,i,type,ex,power,ki=CENTRAL; ivec dt; real r2,invr,invr2,fc,smooth_fc,dev,devins,pfac; rvec r,Sr,fij; real vtot; const t_oriresdata *od; bool bTAV; vtot = 0; od = &(fcd->orires); if (od->fc != 0) { bTAV = (od->edt != 0); smooth_fc = od->fc; if (bTAV) { /* Smoothly switch on the restraining when time averaging is used */ smooth_fc *= (1.0 - od->exp_min_t_tau); } d = 0; for(fa=0; fa<nfa; fa+=3) { type = forceatoms[fa]; ai = forceatoms[fa+1]; aj = forceatoms[fa+2]; if (pbc) { ki = pbc_dx_aiuc(pbc,x[ai],x[aj],r); } else { rvec_sub(x[ai],x[aj],r); } r2 = norm2(r); invr = invsqrt(r2); invr2 = invr*invr; ex = ip[type].orires.ex; power = ip[type].orires.power; fc = smooth_fc*ip[type].orires.kfac; dev = od->otav[d] - ip[type].orires.obs; /* NOTE: * there is no real potential when time averaging is applied */ vtot += 0.5*fc*sqr(dev); if (bTAV) { /* Calculate the force as the sqrt of tav times instantaneous */ devins = od->oins[d] - ip[type].orires.obs; if (dev*devins <= 0) { dev = 0; } else { dev = sqrt(dev*devins); if (devins < 0) { dev = -dev; } } } pfac = fc*ip[type].orires.c*invr2; for(i=0; i<power; i++) { pfac *= invr; } mvmul(od->S[ex],r,Sr); for(i=0; i<DIM; i++) { fij[i] = -pfac*dev*(4*Sr[i] - 2*(2+power)*invr2*iprod(Sr,r)*r[i]); } if (g) { ivec_sub(SHIFT_IVEC(g,ai),SHIFT_IVEC(g,aj),dt); ki=IVEC2IS(dt); } for(i=0; i<DIM; i++) { f[ai][i] += fij[i]; f[aj][i] -= fij[i]; fshift[ki][i] += fij[i]; fshift[CENTRAL][i] -= fij[i]; } d++; } } return vtot; /* Approx. 80*nfa/3 flops */ }
real ta_disres(int nfa,const t_iatom forceatoms[],const t_iparams ip[], const rvec x[],rvec f[],rvec fshift[], const t_pbc *pbc,const t_graph *g, real lambda,real *dvdlambda, const t_mdatoms *md,t_fcdata *fcd, int *global_atom_index) { const real sixth=1.0/6.0; const real seven_three=7.0/3.0; atom_id ai,aj; int fa,res,npair,p,pair,ki=CENTRAL,m; int type; rvec dx; real weight_rt_1; real smooth_fc,Rt,Rtav,rt2,*Rtl_6,*Rt_6,*Rtav_6; real k0,f_scal=0,fmax_scal,fk_scal,fij; real tav_viol,instant_viol,mixed_viol,violtot,vtot; real tav_viol_Rtav7,instant_viol_Rtav7; real up1,up2,low; gmx_bool bConservative,bMixed,bViolation; ivec it,jt,dt; t_disresdata *dd; int dr_weighting; gmx_bool dr_bMixed; dd = &(fcd->disres); dr_weighting = dd->dr_weighting; dr_bMixed = dd->dr_bMixed; Rtl_6 = dd->Rtl_6; Rt_6 = dd->Rt_6; Rtav_6 = dd->Rtav_6; tav_viol=instant_viol=mixed_viol=tav_viol_Rtav7=instant_viol_Rtav7=0; smooth_fc = dd->dr_fc; if (dd->dr_tau != 0) { /* scaling factor to smoothly turn on the restraint forces * * when using time averaging */ smooth_fc *= (1.0 - dd->exp_min_t_tau); } violtot = 0; vtot = 0; /* 'loop' over all atom pairs (pair_nr=fa/3) involved in restraints, * * the total number of atoms pairs is nfa/3 */ res = 0; fa = 0; while (fa < nfa) { type = forceatoms[fa]; /* Take action depending on restraint, calculate scalar force */ npair = ip[type].disres.npair; up1 = ip[type].disres.up1; up2 = ip[type].disres.up2; low = ip[type].disres.low; k0 = smooth_fc*ip[type].disres.kfac; /* save some flops when there is only one pair */ if (ip[type].disres.type != 2) { bConservative = (dr_weighting == edrwConservative) && (npair > 1); bMixed = dr_bMixed; Rt = pow(Rt_6[res],-sixth); Rtav = pow(Rtav_6[res],-sixth); } else { /* When rtype=2 use instantaneous not ensemble avereged distance */ bConservative = (npair > 1); bMixed = FALSE; Rt = pow(Rtl_6[res],-sixth); Rtav = Rt; } if (Rtav > up1) { bViolation = TRUE; tav_viol = Rtav - up1; } else if (Rtav < low) { bViolation = TRUE; tav_viol = Rtav - low; } else { bViolation = FALSE; } if (bViolation) { /* NOTE: * there is no real potential when time averaging is applied */ vtot += 0.5*k0*sqr(tav_viol); if (1/vtot == 0) { printf("vtot is inf: %f\n",vtot); } if (!bMixed) { f_scal = -k0*tav_viol; violtot += fabs(tav_viol); } else { if (Rt > up1) { if (tav_viol > 0) { instant_viol = Rt - up1; } else { bViolation = FALSE; } } else if (Rt < low) { if (tav_viol < 0) { instant_viol = Rt - low; } else { bViolation = FALSE; } } else { bViolation = FALSE; } if (bViolation) { mixed_viol = sqrt(tav_viol*instant_viol); f_scal = -k0*mixed_viol; violtot += mixed_viol; } } } if (bViolation) { fmax_scal = -k0*(up2-up1); /* Correct the force for the number of restraints */ if (bConservative) { f_scal = max(f_scal,fmax_scal); if (!bMixed) { f_scal *= Rtav/Rtav_6[res]; } else { f_scal /= 2*mixed_viol; tav_viol_Rtav7 = tav_viol*Rtav/Rtav_6[res]; instant_viol_Rtav7 = instant_viol*Rt/Rt_6[res]; } } else { f_scal /= (real)npair; f_scal = max(f_scal,fmax_scal); } /* Exert the force ... */ /* Loop over the atom pairs of 'this' restraint */ for(p=0; p<npair; p++) { pair = fa/3; ai = forceatoms[fa+1]; aj = forceatoms[fa+2]; if (pbc) { ki = pbc_dx_aiuc(pbc,x[ai],x[aj],dx); } else { rvec_sub(x[ai],x[aj],dx); } rt2 = iprod(dx,dx); weight_rt_1 = gmx_invsqrt(rt2); if (bConservative) { if (!dr_bMixed) { weight_rt_1 *= pow(dd->rm3tav[pair],seven_three); } else { weight_rt_1 *= tav_viol_Rtav7*pow(dd->rm3tav[pair],seven_three)+ instant_viol_Rtav7*pow(dd->rt[pair],-7); } } fk_scal = f_scal*weight_rt_1; if (g) { ivec_sub(SHIFT_IVEC(g,ai),SHIFT_IVEC(g,aj),dt); ki=IVEC2IS(dt); } for(m=0; m<DIM; m++) { fij = fk_scal*dx[m]; f[ai][m] += fij; f[aj][m] -= fij; fshift[ki][m] += fij; fshift[CENTRAL][m] -= fij; } fa += 3; } } else { /* No violation so force and potential contributions */ fa += 3*npair; } res++; } dd->sumviol = violtot; /* Return energy */ return vtot; }
real RF_excl_correction(FILE *log, const t_forcerec *fr,t_graph *g, const t_mdatoms *mdatoms,const t_blocka *excl, rvec x[],rvec f[],rvec *fshift,const t_pbc *pbc, real lambda,real *dvdlambda) { /* Calculate the reaction-field energy correction for this node: * epsfac q_i q_j (k_rf r_ij^2 - c_rf) * and force correction for all excluded pairs, including self pairs. */ int top,i,j,j1,j2,k,ki; double q2sumA,q2sumB,ener; const real *chargeA,*chargeB; real ek,ec,L1,qiA,qiB,qqA,qqB,qqL,v; rvec dx,df; atom_id *AA; ivec dt; int start = mdatoms->start; int end = mdatoms->homenr+start; int niat; gmx_bool bMolPBC = fr->bMolPBC; if (fr->n_tpi) /* For test particle insertion we only correct for the test molecule */ start = mdatoms->nr - fr->n_tpi; ek = fr->epsfac*fr->k_rf; ec = fr->epsfac*fr->c_rf; chargeA = mdatoms->chargeA; chargeB = mdatoms->chargeB; AA = excl->a; ki = CENTRAL; if (fr->bDomDec) niat = excl->nr; else niat = end; q2sumA = 0; q2sumB = 0; ener = 0; if (mdatoms->nChargePerturbed == 0) { for(i=start; i<niat; i++) { qiA = chargeA[i]; if (i < end) q2sumA += qiA*qiA; /* Do the exclusions */ j1 = excl->index[i]; j2 = excl->index[i+1]; for(j=j1; j<j2; j++) { k = AA[j]; if (k > i) { qqA = qiA*chargeA[k]; if (qqA != 0) { if (g) { rvec_sub(x[i],x[k],dx); ivec_sub(SHIFT_IVEC(g,i),SHIFT_IVEC(g,k),dt); ki=IVEC2IS(dt); } else if (bMolPBC) { ki = pbc_dx_aiuc(pbc,x[i],x[k],dx); } else rvec_sub(x[i],x[k],dx); ener += qqA*(ek*norm2(dx) - ec); svmul(-2*qqA*ek,dx,df); rvec_inc(f[i],df); rvec_dec(f[k],df); rvec_inc(fshift[ki],df); rvec_dec(fshift[CENTRAL],df); } } } } ener += -0.5*ec*q2sumA; } else { L1 = 1.0 - lambda; for(i=start; i<niat; i++) { qiA = chargeA[i]; qiB = chargeB[i]; if (i < end) { q2sumA += qiA*qiA; q2sumB += qiB*qiB; } /* Do the exclusions */ j1 = excl->index[i]; j2 = excl->index[i+1]; for(j=j1; j<j2; j++) { k = AA[j]; if (k > i) { qqA = qiA*chargeA[k]; qqB = qiB*chargeB[k]; if (qqA != 0 || qqB != 0) { qqL = L1*qqA + lambda*qqB; if (g) { rvec_sub(x[i],x[k],dx); ivec_sub(SHIFT_IVEC(g,i),SHIFT_IVEC(g,k),dt); ki=IVEC2IS(dt); } else if (bMolPBC) { ki = pbc_dx_aiuc(pbc,x[i],x[k],dx); } else rvec_sub(x[i],x[k],dx); v = ek*norm2(dx) - ec; ener += qqL*v; svmul(-2*qqL*ek,dx,df); rvec_inc(f[i],df); rvec_dec(f[k],df); rvec_inc(fshift[ki],df); rvec_dec(fshift[CENTRAL],df); *dvdlambda += (qqB - qqA)*v; } } } } ener += -0.5*ec*(L1*q2sumA + lambda*q2sumB); *dvdlambda += -0.5*ec*(q2sumB - q2sumA); } if (debug) fprintf(debug,"RF exclusion energy: %g\n",ener); return ener; }
real do_nonbonded_listed(int ftype, int nbonds, const t_iatom iatoms[], const t_iparams iparams[], const rvec x[], rvec f[], rvec fshift[], const t_pbc *pbc, const t_graph *g, real *lambda, real *dvdl, const t_mdatoms *md, const t_forcerec *fr, gmx_grppairener_t *grppener, int *global_atom_index) { int ielec, ivdw; real qq, c6, c12; rvec dx; ivec dt; int i, j, itype, ai, aj, gid; int fshift_index; real r2, rinv; real fscal, velec, vvdw; real * energygrp_elec; real * energygrp_vdw; static gmx_bool warned_rlimit = FALSE; /* Free energy stuff */ gmx_bool bFreeEnergy; real LFC[2], LFV[2], DLF[2], lfac_coul[2], lfac_vdw[2], dlfac_coul[2], dlfac_vdw[2]; real qqB, c6B, c12B, sigma2_def, sigma2_min; switch (ftype) { case F_LJ14: case F_LJC14_Q: energygrp_elec = grppener->ener[egCOUL14]; energygrp_vdw = grppener->ener[egLJ14]; break; case F_LJC_PAIRS_NB: energygrp_elec = grppener->ener[egCOULSR]; energygrp_vdw = grppener->ener[egLJSR]; break; default: energygrp_elec = NULL; /* Keep compiler happy */ energygrp_vdw = NULL; /* Keep compiler happy */ gmx_fatal(FARGS, "Unknown function type %d in do_nonbonded14", ftype); break; } if (fr->efep != efepNO) { /* Lambda factor for state A=1-lambda and B=lambda */ LFC[0] = 1.0 - lambda[efptCOUL]; LFV[0] = 1.0 - lambda[efptVDW]; LFC[1] = lambda[efptCOUL]; LFV[1] = lambda[efptVDW]; /*derivative of the lambda factor for state A and B */ DLF[0] = -1; DLF[1] = 1; /* precalculate */ sigma2_def = pow(fr->sc_sigma6_def, 1.0/3.0); sigma2_min = pow(fr->sc_sigma6_min, 1.0/3.0); for (i = 0; i < 2; i++) { lfac_coul[i] = (fr->sc_power == 2 ? (1-LFC[i])*(1-LFC[i]) : (1-LFC[i])); dlfac_coul[i] = DLF[i]*fr->sc_power/fr->sc_r_power*(fr->sc_power == 2 ? (1-LFC[i]) : 1); lfac_vdw[i] = (fr->sc_power == 2 ? (1-LFV[i])*(1-LFV[i]) : (1-LFV[i])); dlfac_vdw[i] = DLF[i]*fr->sc_power/fr->sc_r_power*(fr->sc_power == 2 ? (1-LFV[i]) : 1); } } else { sigma2_min = sigma2_def = 0; } bFreeEnergy = FALSE; for (i = 0; (i < nbonds); ) { itype = iatoms[i++]; ai = iatoms[i++]; aj = iatoms[i++]; gid = GID(md->cENER[ai], md->cENER[aj], md->nenergrp); /* Get parameters */ switch (ftype) { case F_LJ14: bFreeEnergy = (fr->efep != efepNO && ((md->nPerturbed && (md->bPerturbed[ai] || md->bPerturbed[aj])) || iparams[itype].lj14.c6A != iparams[itype].lj14.c6B || iparams[itype].lj14.c12A != iparams[itype].lj14.c12B)); qq = md->chargeA[ai]*md->chargeA[aj]*fr->epsfac*fr->fudgeQQ; c6 = iparams[itype].lj14.c6A; c12 = iparams[itype].lj14.c12A; break; case F_LJC14_Q: qq = iparams[itype].ljc14.qi*iparams[itype].ljc14.qj*fr->epsfac*iparams[itype].ljc14.fqq; c6 = iparams[itype].ljc14.c6; c12 = iparams[itype].ljc14.c12; break; case F_LJC_PAIRS_NB: qq = iparams[itype].ljcnb.qi*iparams[itype].ljcnb.qj*fr->epsfac; c6 = iparams[itype].ljcnb.c6; c12 = iparams[itype].ljcnb.c12; break; default: /* Cannot happen since we called gmx_fatal() above in this case */ qq = c6 = c12 = 0; /* Keep compiler happy */ break; } /* To save flops in the optimized kernels, c6/c12 have 6.0/12.0 derivative prefactors * included in the general nfbp array now. This means the tables are scaled down by the * same factor, so when we use the original c6/c12 parameters from iparams[] they must * be scaled up. */ c6 *= 6.0; c12 *= 12.0; /* Do we need to apply full periodic boundary conditions? */ if (fr->bMolPBC == TRUE) { fshift_index = pbc_dx_aiuc(pbc, x[ai], x[aj], dx); } else { fshift_index = CENTRAL; rvec_sub(x[ai], x[aj], dx); } r2 = norm2(dx); if (r2 >= fr->tab14.r*fr->tab14.r) { if (warned_rlimit == FALSE) { nb_listed_warning_rlimit(x, ai, aj, global_atom_index, sqrt(r2), fr->tab14.r); warned_rlimit = TRUE; } continue; } if (bFreeEnergy) { /* Currently free energy is only supported for F_LJ14, so no need to check for that if we got here */ qqB = md->chargeB[ai]*md->chargeB[aj]*fr->epsfac*fr->fudgeQQ; c6B = iparams[itype].lj14.c6B*6.0; c12B = iparams[itype].lj14.c12B*12.0; fscal = nb_free_energy_evaluate_single(r2, fr->sc_r_power, fr->sc_alphacoul, fr->sc_alphavdw, fr->tab14.scale, fr->tab14.data, qq, c6, c12, qqB, c6B, c12B, LFC, LFV, DLF, lfac_coul, lfac_vdw, dlfac_coul, dlfac_vdw, fr->sc_sigma6_def, fr->sc_sigma6_min, sigma2_def, sigma2_min, &velec, &vvdw, dvdl); } else { /* Evaluate tabulated interaction without free energy */ fscal = nb_evaluate_single(r2, fr->tab14.scale, fr->tab14.data, qq, c6, c12, &velec, &vvdw); } energygrp_elec[gid] += velec; energygrp_vdw[gid] += vvdw; svmul(fscal, dx, dx); /* Add the forces */ rvec_inc(f[ai], dx); rvec_dec(f[aj], dx); if (g) { /* Correct the shift forces using the graph */ ivec_sub(SHIFT_IVEC(g, ai), SHIFT_IVEC(g, aj), dt); fshift_index = IVEC2IS(dt); } if (fshift_index != CENTRAL) { rvec_inc(fshift[fshift_index], dx); rvec_dec(fshift[CENTRAL], dx); } } return 0.0; }
real orires(int nfa,t_iatom forceatoms[],t_iparams ip[], rvec x[],rvec f[],t_forcerec *fr,t_graph *g, matrix box,real lambda,real *dvdlambda, t_mdatoms *md,int ngrp,real egnb[],real egcoul[], t_fcdata *fcd) { atom_id ai,aj; int fa,d,i,type,ex,power,ki; ivec dt; real r2,invr,invr2,fc,smooth_fc,dev,devins,pfac; rvec r,Sr,fij; real vtot; t_oriresdata *od; bool bTAV; vtot = 0; od = &(fcd->orires); if (fabs(od->fc) > GMX_REAL_MIN) { bTAV = (fabs(od->edt) > GMX_REAL_MIN); /* Smoothly switch on the restraining when time averaging is used */ smooth_fc = od->fc*(1.0 - od->exp_min_t_tau); d = 0; for(fa=0; fa<nfa; fa+=3) { type = forceatoms[fa]; ai = forceatoms[fa+1]; aj = forceatoms[fa+2]; rvec_sub(x[ai],x[aj],r); r2 = norm2(r); invr = invsqrt(r2); invr2 = invr*invr; ex = ip[type].orires.ex; power = ip[type].orires.pow; fc = smooth_fc*ip[type].orires.kfac; dev = od->otav[d] - ip[type].orires.obs; /* NOTE: there is no real potential when time averaging is applied */ vtot += 0.5*fc*sqr(dev); if (bTAV) { /* Calculate the force as the sqrt of tav times instantaneous */ devins = od->oins[d] - ip[type].orires.obs; if (dev*devins <= 0) dev = 0; else { dev = sqrt(dev*devins); if (devins < 0) dev = -dev; } } pfac = fc*ip[type].orires.c*invr2; for(i=0; i<power; i++) pfac *= invr; mvmul(od->S[ex],r,Sr); for(i=0; i<DIM; i++) fij[i] = -pfac*dev*(4*Sr[i] - 2*(2+power)*invr2*iprod(Sr,r)*r[i]); ivec_sub(SHIFT_IVEC(g,ai),SHIFT_IVEC(g,aj),dt); ki=IVEC2IS(dt); for(i=0; i<DIM; i++) { f[ai][i] += fij[i]; f[aj][i] -= fij[i]; fr->fshift[ki][i] += fij[i]; fr->fshift[CENTRAL][i] -= fij[i]; } d++; } } return vtot; /* Approx. 80*nfa/3 flops */ }