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; }
void do_nonbonded(t_commrec *cr,t_forcerec *fr, rvec x[],rvec f[],t_mdatoms *mdatoms,t_blocka *excl, real egnb[],real egcoul[],real egpol[],rvec box_size, t_nrnb *nrnb,real lambda,real *dvdlambda, int nls,int eNL,int flags) { gmx_bool bLR,bDoForces,bForeignLambda; t_nblist * nlist; real * fshift; int n,n0,n1,i,i0,i1,nrnb_ind,sz; t_nblists *nblists; gmx_bool bWater; FILE * fp; int fac=0; int nthreads = 1; int tabletype; int outeriter,inneriter; real * tabledata = NULL; gmx_gbdata_t gbdata; nb_kernel_t *kernelptr=NULL; nb_adress_kernel_t *adresskernelptr=NULL; gmx_bool bCG; /* for AdresS */ int k;/* for AdresS */ bLR = (flags & GMX_DONB_LR); bDoForces = (flags & GMX_DONB_FORCES); bForeignLambda = (flags & GMX_DONB_FOREIGNLAMBDA); bCG = FALSE; /* for AdresS */ gbdata.gb_epsilon_solvent = fr->gb_epsilon_solvent; gbdata.epsilon_r = fr->epsilon_r; gbdata.gpol = egpol; if (!fr->adress_type==eAdressOff && !bDoForces){ gmx_fatal(FARGS,"No force kernels not implemeted for adress"); } if(fr->bAllvsAll) { if(fr->bGB) { #if (defined GMX_SSE2 || defined GMX_X86_64_SSE || defined GMX_X86_64_SSE2 || defined GMX_IA32_SSE || defined GMX_IA32_SSE2) # ifdef GMX_DOUBLE if(fr->UseOptimizedKernels) { nb_kernel_allvsallgb_sse2_double(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsallgb(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } # else /* not double */ if(fr->UseOptimizedKernels) { nb_kernel_allvsallgb_sse2_single(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsallgb(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } # endif /* double/single alt. */ #else /* no SSE support compiled in */ nb_kernel_allvsallgb(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); #endif inc_nrnb(nrnb,eNR_NBKERNEL_ALLVSALLGB,inneriter); } else { #if (defined GMX_SSE2 || defined GMX_X86_64_SSE || defined GMX_X86_64_SSE2 || defined GMX_IA32_SSE || defined GMX_IA32_SSE2) # ifdef GMX_DOUBLE if(fr->UseOptimizedKernels) { nb_kernel_allvsall_sse2_double(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsall(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } # else /* not double */ if(fr->UseOptimizedKernels) { nb_kernel_allvsall_sse2_single(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsall(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } # endif /* double/single check */ #else /* No SSE2 support compiled in */ nb_kernel_allvsall(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); #endif inc_nrnb(nrnb,eNR_NBKERNEL_ALLVSALL,inneriter); } inc_nrnb(nrnb,eNR_NBKERNEL_OUTER,outeriter); return; } if (eNL >= 0) { i0 = eNL; i1 = i0+1; } else { i0 = 0; i1 = eNL_NR; } if (nls >= 0) { n0 = nls; n1 = nls+1; } else { n0 = 0; n1 = fr->nnblists; } if(nb_kernel_list == NULL) { gmx_fatal(FARGS,"gmx_setup_kernels has not been called"); } fshift = fr->fshift[0]; for(n=n0; (n<n1); n++) { nblists = &fr->nblists[n]; for(i=i0; (i<i1); i++) { outeriter = inneriter = 0; if (bLR) { nlist = &(nblists->nlist_lr[i]); } else { nlist = &(nblists->nlist_sr[i]); } if (nlist->nri > 0) { nrnb_ind = nlist->il_code; if(nrnb_ind==eNR_NBKERNEL_FREE_ENERGY) { /* generic free energy, use combined table */ tabledata = nblists->tab.tab; } else { if (bForeignLambda) { /* We don't need the non-perturbed interactions */ continue; } tabletype = nb_kernel_table[nrnb_ind]; /* normal kernels, not free energy */ if (!bDoForces) { nrnb_ind += eNR_NBKERNEL_NR/2; } if(tabletype == TABLE_COMBINED) { tabledata = nblists->tab.tab; } else if(tabletype == TABLE_COUL) { tabledata = nblists->coultab; } else if(tabletype == TABLE_VDW) { tabledata = nblists->vdwtab; } else { tabledata = NULL; } } nlist->count = 0; if(nlist->free_energy) { if(nlist->ivdw==2) { gmx_fatal(FARGS,"Cannot do free energy Buckingham interactions."); } gmx_nb_free_energy_kernel(nlist->icoul, nlist->ivdw, nlist->nri, nlist->iinr, nlist->jindex, nlist->jjnr, nlist->shift, fr->shift_vec[0], fshift, nlist->gid, x[0], f[0], mdatoms->chargeA, mdatoms->chargeB, fr->epsfac, fr->k_rf, fr->c_rf, fr->ewaldcoeff, egcoul, mdatoms->typeA, mdatoms->typeB, fr->ntype, fr->nbfp, egnb, nblists->tab.scale, tabledata, lambda, dvdlambda, fr->sc_alpha, fr->sc_power, fr->sc_sigma6_def, fr->sc_sigma6_min, bDoForces, &outeriter, &inneriter); } else if (nlist->enlist == enlistCG_CG) { if (fr->adress_type==eAdressOff){ /* Call the charge group based inner loop */ gmx_nb_generic_cg_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter); } else { /*gmx_nb_generic_adress_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter);*/ gmx_fatal(FARGS,"Death & horror! Adress cgcg kernel not implemented anymore.\n"); } } else { /* AdresS*/ /* for adress we need to determine for each energy group wether it is explicit or coarse-grained */ if (!fr->adress_type == eAdressOff) { bCG = FALSE; if ( !fr->adress_group_explicit[ mdatoms->cENER[nlist->iinr[0]] ] ){ bCG=TRUE; } /* If this processor has only explicit atoms (w=1) skip the coarse grained force calculation. Same for only coarsegrained atoms and explicit interactions. Last condition is to make sure that generic kernel is not skipped*/ if (mdatoms->pureex && bCG && nb_kernel_list[nrnb_ind] != NULL) continue; if (mdatoms->purecg && !bCG && nb_kernel_list[nrnb_ind] != NULL) continue; } if (fr->adress_type == eAdressOff || mdatoms->pureex || mdatoms->purecg){ /* if we only have to calculate pure cg/ex interactions we can use the faster standard gromacs kernels*/ kernelptr = nb_kernel_list[nrnb_ind]; }else{ /* This processor has hybrid interactions which means * we have to * use our own kernels. We have two kernel types: one that * calculates the forces with the explicit prefactor w1*w2 * and one for coarse-grained with (1-w1*w2) * explicit kernels are the second part of the kernel * list */ if (!bCG) nrnb_ind += eNR_NBKERNEL_NR/2; adresskernelptr = nb_kernel_list_adress[nrnb_ind]; } if (kernelptr == NULL && adresskernelptr == NULL) { /* Call a generic nonbonded kernel */ /* If you want to hack/test your own interactions, * do it in this routine and make sure it is called * by setting the environment variable GMX_NB_GENERIC. */ if (fr->adress_type==eAdressOff){ gmx_nb_generic_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter); }else /* do generic AdResS kernels (slow)*/ { gmx_nb_generic_adress_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter, bCG); } } else { /* Call nonbonded kernel from function pointer */ if (kernelptr!=NULL){ (*kernelptr)( &(nlist->nri), nlist->iinr, nlist->jindex, nlist->jjnr, nlist->shift, fr->shift_vec[0], fshift, nlist->gid, x[0], f[0], mdatoms->chargeA, &(fr->epsfac), &(fr->k_rf), &(fr->c_rf), egcoul, mdatoms->typeA, &(fr->ntype), fr->nbfp, egnb, &(nblists->tab.scale), tabledata, fr->invsqrta, fr->dvda, &(fr->gbtabscale), fr->gbtab.tab, &nthreads, &(nlist->count), nlist->mtx, &outeriter, &inneriter, (real *)&gbdata); }else if (adresskernelptr != NULL) { /* Adress kernels */ (*adresskernelptr)( &(nlist->nri), nlist->iinr, nlist->jindex, nlist->jjnr, nlist->shift, fr->shift_vec[0], fshift, nlist->gid, x[0], f[0], mdatoms->chargeA, &(fr->epsfac), &(fr->k_rf), &(fr->c_rf), egcoul, mdatoms->typeA, &(fr->ntype), fr->nbfp, egnb, &(nblists->tab.scale), tabledata, fr->invsqrta, fr->dvda, &(fr->gbtabscale), fr->gbtab.tab, &nthreads, &(nlist->count), nlist->mtx, &outeriter, &inneriter, fr->adress_ex_forcecap, mdatoms->wf); } } } /* Update flop accounting */ /* Outer loop in kernel */ switch (nlist->enlist) { case enlistATOM_ATOM: fac = 1; break; case enlistSPC_ATOM: fac = 3; break; case enlistSPC_SPC: fac = 9; break; case enlistTIP4P_ATOM: fac = 4; break; case enlistTIP4P_TIP4P: fac = 16; break; case enlistCG_CG: fac = 1; break; } inc_nrnb(nrnb,eNR_NBKERNEL_OUTER,fac*outeriter); /* inner loop in kernel */ inc_nrnb(nrnb,nrnb_ind,inneriter); } } } }
void do_nonbonded(t_commrec *cr,t_forcerec *fr, rvec x[],rvec f[],t_mdatoms *mdatoms,t_blocka *excl, real egnb[],real egcoul[],real egpol[],rvec box_size, t_nrnb *nrnb,real lambda,real *dvdlambda, int nls,int eNL,int flags) { gmx_bool bLR,bDoForces,bForeignLambda; t_nblist * nlist; real * fshift; int n,n0,n1,i,i0,i1,nrnb_ind,sz; t_nblists *nblists; gmx_bool bWater; nb_kernel_t * kernelptr; pf_nb_kernel_t *pf_kernelptr; FILE * fp; int fac=0; int nthreads = 1; int tabletype; int outeriter,inneriter; real * tabledata = NULL; gmx_gbdata_t gbdata; bLR = (flags & GMX_DONB_LR); bDoForces = (flags & GMX_DONB_FORCES); bForeignLambda = (flags & GMX_DONB_FOREIGNLAMBDA); gbdata.gb_epsilon_solvent = fr->gb_epsilon_solvent; gbdata.epsilon_r = fr->epsilon_r; gbdata.gpol = egpol; if(fr->bAllvsAll) { if(fr->bGB) { #if (defined GMX_SSE2 || defined GMX_X86_64_SSE || defined GMX_X86_64_SSE2 || defined GMX_IA32_SSE || defined GMX_IA32_SSE2) # ifdef GMX_DOUBLE if(fr->UseOptimizedKernels) { nb_kernel_allvsallgb_sse2_double(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsallgb(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } # else /* not double */ if(fr->UseOptimizedKernels) { nb_kernel_allvsallgb_sse2_single(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsallgb(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); } # endif /* double/single alt. */ #else /* no SSE support compiled in */ nb_kernel_allvsallgb(fr,mdatoms,excl,x[0],f[0],egcoul,egnb,egpol, &outeriter,&inneriter,&fr->AllvsAll_work); #endif inc_nrnb(nrnb,eNR_NBKERNEL_ALLVSALLGB,inneriter); } else { #if (defined GMX_SSE2 || defined GMX_X86_64_SSE || defined GMX_X86_64_SSE2 || defined GMX_IA32_SSE || defined GMX_IA32_SSE2) # ifdef GMX_DOUBLE if(fr->UseOptimizedKernels) { nb_kernel_allvsall_sse2_double(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsall(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } # else /* not double */ if(fr->UseOptimizedKernels) { nb_kernel_allvsall_sse2_single(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } else { nb_kernel_allvsall(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); } # endif /* double/single check */ #else /* No SSE2 support compiled in */ nb_kernel_allvsall(fr,mdatoms,excl,x[0],f[0],egcoul,egnb, &outeriter,&inneriter,&fr->AllvsAll_work); #endif inc_nrnb(nrnb,eNR_NBKERNEL_ALLVSALL,inneriter); } inc_nrnb(nrnb,eNR_NBKERNEL_OUTER,outeriter); return; } if (eNL >= 0) { i0 = eNL; i1 = i0+1; } else { i0 = 0; i1 = eNL_NR; } if (nls >= 0) { n0 = nls; n1 = nls+1; } else { n0 = 0; n1 = fr->nnblists; } if(nb_kernel_list == NULL) { gmx_fatal(FARGS,"gmx_setup_kernels has not been called"); } fshift = fr->fshift[0]; for(n=n0; (n<n1); n++) { nblists = &fr->nblists[n]; for(i=i0; (i<i1); i++) { outeriter = inneriter = 0; if (bLR) { nlist = &(nblists->nlist_lr[i]); } else { nlist = &(nblists->nlist_sr[i]); } if (nlist->nri > 0) { nrnb_ind = nlist->il_code; if(nrnb_ind==eNR_NBKERNEL_FREE_ENERGY) { /* generic free energy, use combined table */ tabledata = nblists->tab.tab; } else { if (bForeignLambda) { /* We don't need the non-perturbed interactions */ continue; } tabletype = nb_kernel_table[nrnb_ind]; /* normal kernels, not free energy */ if (!bDoForces) { nrnb_ind += eNR_NBKERNEL_NR/2; } if(tabletype == TABLE_COMBINED) { tabledata = nblists->tab.tab; } else if(tabletype == TABLE_COUL) { tabledata = nblists->coultab; } else if(tabletype == TABLE_VDW) { tabledata = nblists->vdwtab; } else { tabledata = NULL; } } nlist->count = 0; if(nlist->free_energy) { if(nlist->ivdw==2) { gmx_fatal(FARGS,"Cannot do free energy Buckingham interactions."); } gmx_nb_free_energy_kernel(nlist->icoul, nlist->ivdw, nlist->nri, nlist->iinr, nlist->jindex, nlist->jjnr, nlist->shift, fr->shift_vec[0], fshift, nlist->gid, x[0], f[0], mdatoms->chargeA, mdatoms->chargeB, fr->epsfac, fr->k_rf, fr->c_rf, fr->ewaldcoeff, egcoul, mdatoms->typeA, mdatoms->typeB, fr->ntype, fr->nbfp, egnb, nblists->tab.scale, tabledata, lambda, dvdlambda, fr->sc_alpha, fr->sc_power, fr->sc_sigma6_def, fr->sc_sigma6_min, bDoForces, &outeriter, &inneriter); } else if (nlist->enlist == enlistCG_CG) { /* Call the charge group based inner loop */ gmx_nb_generic_cg_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter); } else { /* Not free energy */ /* Pairwise forces between solute and solvent don't bring much information, as the molecules of solvent * move around. For this reason, only pairwise forces between solute atoms are calculated. * This allows the normal (non-pairwise force) kernels to be used for solute-solvent and solvent-solvent * interactions; the main reason is performance, as the normal kernels are not slowed down by the * checking whether atom is involved in an interesting interaction. */ if ((fr->pf_global) && (nlist->enlist == enlistATOM_ATOM)) { pf_kernelptr = pf_nb_kernel_list[nrnb_ind]; (*pf_kernelptr)( &(nlist->nri), nlist->iinr, nlist->jindex, nlist->jjnr, nlist->shift, fr->shift_vec[0], fshift, nlist->gid, x[0], f[0], mdatoms->chargeA, &(fr->epsfac), &(fr->k_rf), &(fr->c_rf), egcoul, mdatoms->typeA, &(fr->ntype), fr->nbfp, egnb, &(nblists->tab.scale), tabledata, fr->invsqrta, fr->dvda, &(fr->gbtabscale), fr->gbtab.tab, &nthreads, &(nlist->count), nlist->mtx, &outeriter, &inneriter, (real *)&gbdata, fr->pf_global); } else { /* non pairwise force kernel */ kernelptr = nb_kernel_list[nrnb_ind]; if (kernelptr == NULL) { /* Call a generic nonbonded kernel */ /* If you want to hack/test your own interactions, * do it in this routine and make sure it is called * by setting the environment variable GMX_NB_GENERIC. */ gmx_nb_generic_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter); } else { /* Call nonbonded kernel from function pointer */ (*kernelptr)( &(nlist->nri), nlist->iinr, nlist->jindex, nlist->jjnr, nlist->shift, fr->shift_vec[0], fshift, nlist->gid, x[0], f[0], mdatoms->chargeA, &(fr->epsfac), &(fr->k_rf), &(fr->c_rf), egcoul, mdatoms->typeA, &(fr->ntype), fr->nbfp, egnb, &(nblists->tab.scale), tabledata, fr->invsqrta, fr->dvda, &(fr->gbtabscale), fr->gbtab.tab, &nthreads, &(nlist->count), nlist->mtx, &outeriter, &inneriter, (real *)&gbdata); } /* end of non pairwise force kernel */ } } /* Update flop accounting */ /* Outer loop in kernel */ switch (nlist->enlist) { case enlistATOM_ATOM: fac = 1; break; case enlistSPC_ATOM: fac = 3; break; case enlistSPC_SPC: fac = 9; break; case enlistTIP4P_ATOM: fac = 4; break; case enlistTIP4P_TIP4P: fac = 16; break; case enlistCG_CG: fac = 1; break; } inc_nrnb(nrnb,eNR_NBKERNEL_OUTER,fac*outeriter); /* inner loop in kernel */ inc_nrnb(nrnb,nrnb_ind,inneriter); } } } }
void do_nonbonded(t_commrec *cr,t_forcerec *fr, rvec x[],rvec f[],t_mdatoms *mdatoms, real egnb[],real egcoul[],real egpol[],rvec box_size, t_nrnb *nrnb,real lambda,real *dvdlambda, int nls,int eNL,int flags,gmx_mc_move *mc_move) { bool bLR,bDoForces,bForeignLambda; t_nblist * nlist,*nlist2=NULL; t_nblists * nlists; real * fshift; int n,n0,n1,i,i0,i1,nrnb_ind,sz; t_nblists *nblists; bool bWater; nb_kernel_t * kernelptr; FILE * fp; int fac=0; int nthreads = 1; int tabletype; int outeriter,inneriter; int *jindex,nj1,nri,*iinr,*jjnr; real * tabledata = NULL; real * enerd = NULL; gmx_gbdata_t gbdata; bLR = (flags & GMX_DONB_LR); bDoForces = (flags & GMX_DONB_FORCES); bForeignLambda = (flags & GMX_DONB_FOREIGNLAMBDA); gbdata.gb_epsilon_solvent = fr->gb_epsilon_solvent; gbdata.gpol = egpol; if (eNL >= 0) { i0 = eNL; i1 = i0+1; } else { i0 = 0; i1 = eNL_NR; } if (nls >= 0) { n0 = nls; n1 = nls+1; } else { n0 = 0; n1 = fr->nnblists; } if(nb_kernel_list == NULL) { gmx_fatal(FARGS,"gmx_setup_kernels has not been called"); } fshift = fr->fshift[0]; for(n=n0; (n<n1); n++) { nblists = &fr->nblists[n]; for(i=i0; (i<i1); i++) { outeriter = inneriter = 0; if (bLR) { nlist = &(nblists->nlist_lr[i]); } else { nlist = &(nblists->nlist_sr[i]); } if (nlist->nri > 0) { nrnb_ind = nlist->il_code; if(nrnb_ind==eNR_NBKERNEL_FREE_ENERGY) { /* generic free energy, use combined table */ tabledata = nblists->tab.tab; } else { if (bForeignLambda) { /* We don't need the non-perturbed interactions */ continue; } tabletype = nb_kernel_table[nrnb_ind]; /* normal kernels, not free energy */ if (!bDoForces) { nrnb_ind += eNR_NBKERNEL_NR/2; } if(tabletype == TABLE_COMBINED) { tabledata = nblists->tab.tab; } else if(tabletype == TABLE_COUL) { tabledata = nblists->coultab; } else if(tabletype == TABLE_VDW) { tabledata = nblists->vdwtab; } else { tabledata = NULL; } } nlist->count = 0; if(nlist->free_energy) { if(nlist->ivdw==2) { gmx_fatal(FARGS,"Cannot do free energy Buckingham interactions."); } gmx_nb_free_energy_kernel(nlist->icoul, nlist->ivdw, nlist->nri, nlist->iinr, nlist->jindex, nlist->jjnr, nlist->shift, fr->shift_vec[0], fshift, nlist->gid, x[0], f[0], mdatoms->chargeA, mdatoms->chargeB, fr->epsfac, fr->k_rf, fr->c_rf, fr->ewaldcoeff, egcoul, mdatoms->typeA, mdatoms->typeB, fr->ntype, fr->nbfp, egnb, nblists->tab.scale, tabledata, lambda, dvdlambda, fr->sc_alpha, fr->sc_power, fr->sc_sigma6, bDoForces, &outeriter, &inneriter); } else if (nlist->enlist == enlistCG_CG) { /* Call the charge group based inner loop */ gmx_nb_generic_cg_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter); } else { /* Not free energy */ kernelptr = nb_kernel_list[nrnb_ind]; if (kernelptr == NULL) { /* Call a generic nonbonded kernel */ /* If you want to hack/test your own interactions, * do it in this routine and make sure it is called * by setting the environment variable GMX_NB_GENERIC. */ gmx_nb_generic_kernel(nlist, fr, mdatoms, x[0], f[0], fshift, egcoul, egnb, nblists->tab.scale, tabledata, &outeriter, &inneriter); } else { /* Call nonbonded kernel from function pointer */ /*if(mc_move) { if(mc_move->bNS[mc_move->cgs]) { do_mclist(mc_move,nlist,fr->nblists_mc,n,i,bLR); } else if (1 == 2) { nlists = &fr->nblists_mc[mc_move->cgs][n]; if(bLR) { nlist2 = &nlists->nlist_lr[i]; } else { nlist2 = &nlists->nlist_sr[i]; } } }*/ //mc_move=NULL; //printf("nrnb %d %d %d\n",nrnb_ind,mc_move->start,mc_move->end); (*kernelptr)( mc_move && nlist2 ? &(nlist2->nri) : &(nlist->nri), mc_move && nlist2 ? nlist2->iinr : nlist->iinr, mc_move && nlist2 ? nlist2->jindex : nlist->jindex, mc_move && nlist2 ? nlist2->jjnr : nlist->jjnr, mc_move && nlist2 ? nlist2->shift : nlist->shift, fr->shift_vec[0], fshift, mc_move && nlist2 ? nlist2->gid : nlist->gid, x[0], f[0], mdatoms->chargeA, &(fr->epsfac), &(fr->k_rf), &(fr->c_rf), egcoul, mdatoms->typeA, &(fr->ntype), fr->nbfp, egnb, &(nblists->tab.scale), tabledata, mc_move ? mc_move->enerd[F_COUL_SR] : NULL, mc_move ? mc_move->enerd[F_LJ] : NULL, (mc_move) ? mc_move->enerd_prev[F_COUL_SR] : NULL, (mc_move) ? mc_move->enerd_prev[F_LJ] : NULL, (mc_move) ? mc_move->cgindex : NULL, (mc_move) ? &mc_move->end : NULL, (mc_move) ? &mc_move->homenr : NULL, (mc_move) ? mc_move->sum_index : NULL, fr->invsqrta, fr->dvda, &(fr->gbtabscale), fr->gbtab.tab, &nthreads, &(nlist->count), nlist->mtx, &outeriter, &inneriter, (real *)&gbdata); } } /* Update flop accounting */ /* Outer loop in kernel */ switch (nlist->enlist) { case enlistATOM_ATOM: fac = 1; break; case enlistSPC_ATOM: fac = 3; break; case enlistSPC_SPC: fac = 9; break; case enlistTIP4P_ATOM: fac = 4; break; case enlistTIP4P_TIP4P: fac = 16; break; case enlistCG_CG: fac = 1; break; } inc_nrnb(nrnb,eNR_NBKERNEL_OUTER,fac*outeriter); /* inner loop in kernel */ inc_nrnb(nrnb,nrnb_ind,inneriter); } } } }