示例#1
0
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;
}
示例#2
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);
            }
        }
    }
}
示例#3
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;
	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);
            }
        }
    }
}
示例#4
0
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);
            }
        }
    }
}