1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2008, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
54 #include "gmx_fatal.h"
55 #include "mtop_util.h"
68 #if ( defined(GMX_IA32_SSE2) || defined(GMX_X86_64_SSE2) || defined(GMX_SSE2) )
69 #include "genborn_sse2_double.h"
70 #include "genborn_allvsall_sse2_double.h"
73 #if ( defined(GMX_IA32_SSE) || defined(GMX_X86_64_SSE) || defined(GMX_SSE2) )
74 #include "genborn_sse2_single.h"
75 #include "genborn_allvsall_sse2_single.h"
77 #endif /* GMX_DOUBLE */
79 #include "genborn_allvsall.h"
81 /*#define DISABLE_SSE*/
90 typedef struct gbtmpnbls {
96 /* This function is exactly the same as the one in bondfree.c. The reason
97 * it is copied here is that the bonded gb-interactions are evaluated
98 * not in calc_bonds, but rather in calc_gb_forces
100 static int pbc_rvec_sub(const t_pbc *pbc,const rvec xi,const rvec xj,rvec dx)
103 return pbc_dx_aiuc(pbc,xi,xj,dx);
111 int init_gb_nblist(int natoms, t_nblist *nl)
113 nl->maxnri = natoms*4;
123 /*nl->nltype = nltype;*/
125 srenew(nl->iinr, nl->maxnri);
126 srenew(nl->gid, nl->maxnri);
127 srenew(nl->shift, nl->maxnri);
128 srenew(nl->jindex, nl->maxnri+1);
135 int print_nblist(int natoms, t_nblist *nl)
137 int i,k,ai,aj,nj0,nj1;
139 printf("genborn.c: print_nblist, natoms=%d\n",nl->nri);
141 for(i=0;i<nl->nri;i++)
150 printf("ai=%d, aj=%d\n",ai,aj);
162 void fill_log_table(const int n, real *table)
168 int incr = 1 << (23-n);
171 logfactor = 1.0/log(2.0);
173 log_table.exp = 0x3F800000;
177 /* log2(numlog)=log(numlog)/log(2.0) */
178 table[i]=log(log_table.numlog)*logfactor;
184 real table_log(real val, const real *table, const int n)
186 int *const exp_ptr = ((int*)&val);
188 const int log_2 = ((x>>23) & 255) - 127;
192 return ((val+log_2)*0.69314718);
195 void gb_pd_send(t_commrec *cr, real *send_data, int nr)
199 int *index,*sendc,*disp;
201 snew(sendc,cr->nnodes);
202 snew(disp,cr->nnodes);
204 index = pd_index(cr);
207 /* Setup count/index arrays */
208 for(i=0;i<cr->nnodes;i++)
210 sendc[i] = index[i+1]-index[i];
214 /* Do communication */
215 MPI_Gatherv(send_data+index[cur],sendc[cur],GMX_MPI_REAL,send_data,sendc,
216 disp,GMX_MPI_REAL,0,cr->mpi_comm_mygroup);
217 MPI_Bcast(send_data,nr,GMX_MPI_REAL,0,cr->mpi_comm_mygroup);
223 int init_gb_plist(t_params *p_list)
226 p_list->param = NULL;
233 int init_gb_still(const t_commrec *cr, t_forcerec *fr,
234 const t_atomtypes *atype, t_idef *idef, t_atoms *atoms,
235 gmx_genborn_t *born,int natoms)
238 int i,j,i1,i2,k,m,nbond,nang,ia,ib,ic,id,nb,idx,idx2,at;
242 real r,ri,rj,ri2,ri3,rj2,r2,r3,r4,rk,ratio,term,h,doffset;
243 real p1,p2,p3,factor,cosine,rab,rbc;
250 snew(born->gpol_still_work,natoms+3);
256 pd_at_range(cr,&at0,&at1);
258 for(i=0;i<natoms;i++)
275 doffset = born->gb_doffset;
277 for(i=0;i<natoms;i++)
279 born->gpol_globalindex[i]=born->vsolv_globalindex[i]=
280 born->gb_radius_globalindex[i]=0;
283 /* Compute atomic solvation volumes for Still method */
284 for(i=0;i<natoms;i++)
286 ri=atype->gb_radius[atoms->atom[i].type];
287 born->gb_radius_globalindex[i] = ri;
289 born->vsolv_globalindex[i]=(4*M_PI/3)*r3;
292 for(j=0;j<idef->il[F_GB12].nr;j+=3)
294 m=idef->il[F_GB12].iatoms[j];
295 ia=idef->il[F_GB12].iatoms[j+1];
296 ib=idef->il[F_GB12].iatoms[j+2];
298 r=1.01*idef->iparams[m].gb.st;
300 ri = atype->gb_radius[atoms->atom[ia].type];
301 rj = atype->gb_radius[atoms->atom[ib].type];
307 ratio = (rj2-ri2-r*r)/(2*ri*r);
309 term = (M_PI/3.0)*h*h*(3.0*ri-h);
317 born->vsolv_globalindex[ia] -= term;
320 ratio = (ri2-rj2-r*r)/(2*rj*r);
322 term = (M_PI/3.0)*h*h*(3.0*rj-h);
330 born->vsolv_globalindex[ib] -= term;
336 gmx_sum(natoms,vsol,cr);
338 for(i=0;i<natoms;i++)
340 born->vsolv_globalindex[i]=born->vsolv_globalindex[i]-vsol[i];
344 /* Get the self-, 1-2 and 1-3 polarization energies for analytical Still
347 for(j=0;j<natoms;j++)
349 if(born->use_globalindex[j]==1)
351 born->gpol_globalindex[j]=-0.5*ONE_4PI_EPS0/
352 (atype->gb_radius[atoms->atom[j].type]-doffset+STILL_P1);
357 for(j=0;j<idef->il[F_GB12].nr;j+=3)
359 m=idef->il[F_GB12].iatoms[j];
360 ia=idef->il[F_GB12].iatoms[j+1];
361 ib=idef->il[F_GB12].iatoms[j+2];
363 r=idef->iparams[m].gb.st;
369 gp[ia]+=STILL_P2*born->vsolv_globalindex[ib]/r4;
370 gp[ib]+=STILL_P2*born->vsolv_globalindex[ia]/r4;
374 born->gpol_globalindex[ia]=born->gpol_globalindex[ia]+
375 STILL_P2*born->vsolv_globalindex[ib]/r4;
376 born->gpol_globalindex[ib]=born->gpol_globalindex[ib]+
377 STILL_P2*born->vsolv_globalindex[ia]/r4;
382 for(j=0;j<idef->il[F_GB13].nr;j+=3)
384 m=idef->il[F_GB13].iatoms[j];
385 ia=idef->il[F_GB13].iatoms[j+1];
386 ib=idef->il[F_GB13].iatoms[j+2];
388 r=idef->iparams[m].gb.st;
393 gp[ia]+=STILL_P3*born->vsolv[ib]/r4;
394 gp[ib]+=STILL_P3*born->vsolv[ia]/r4;
398 born->gpol_globalindex[ia]=born->gpol_globalindex[ia]+
399 STILL_P3*born->vsolv_globalindex[ib]/r4;
400 born->gpol_globalindex[ib]=born->gpol_globalindex[ib]+
401 STILL_P3*born->vsolv_globalindex[ia]/r4;
407 gmx_sum(natoms,gp,cr);
409 for(i=0;i<natoms;i++)
411 born->gpol_globalindex[i]=born->gpol_globalindex[i]+gp[i];
423 #define LOG_TABLE_ACCURACY 15 /* Accuracy of the table logarithm */
426 /* Initialize all GB datastructs and compute polarization energies */
427 int init_gb(gmx_genborn_t **p_born,
428 const t_commrec *cr, t_forcerec *fr, const t_inputrec *ir,
429 const gmx_mtop_t *mtop, real rgbradii, int gb_algorithm)
431 int i,j,m,ai,aj,jj,natoms,nalloc;
432 real rai,sk,p,doffset;
436 gmx_localtop_t *localtop;
438 natoms = mtop->natoms;
440 atoms = gmx_mtop_global_atoms(mtop);
441 localtop = gmx_mtop_generate_local_top(mtop,ir);
446 born->nr = fr->natoms_force;
449 snew(born->drobc, natoms);
450 snew(born->bRad, natoms);
452 /* Allocate memory for the global data arrays */
453 snew(born->param_globalindex, natoms+3);
454 snew(born->gpol_globalindex, natoms+3);
455 snew(born->vsolv_globalindex, natoms+3);
456 snew(born->gb_radius_globalindex, natoms+3);
457 snew(born->use_globalindex, natoms+3);
459 snew(fr->invsqrta, natoms);
460 snew(fr->dvda, natoms);
463 fr->dadx_rawptr = NULL;
465 born->gpol_still_work = NULL;
466 born->gpol_hct_work = NULL;
468 /* snew(born->asurf,natoms); */
469 /* snew(born->dasurf,natoms); */
471 /* Initialize the gb neighbourlist */
472 init_gb_nblist(natoms,&(fr->gblist));
474 /* Do the Vsites exclusions (if any) */
475 for(i=0;i<natoms;i++)
477 jj = atoms.atom[i].type;
478 if (mtop->atomtypes.gb_radius[atoms.atom[i].type] > 0)
480 born->use_globalindex[i] = 1;
484 born->use_globalindex[i] = 0;
487 /* If we have a Vsite, put vs_globalindex[i]=0 */
488 if (C6 (fr->nbfp,fr->ntype,jj,jj) == 0 &&
489 C12(fr->nbfp,fr->ntype,jj,jj) == 0 &&
490 atoms.atom[i].q == 0)
492 born->use_globalindex[i]=0;
496 /* Copy algorithm parameters from inputrecord to local structure */
497 born->obc_alpha = ir->gb_obc_alpha;
498 born->obc_beta = ir->gb_obc_beta;
499 born->obc_gamma = ir->gb_obc_gamma;
500 born->gb_doffset = ir->gb_dielectric_offset;
501 born->gb_epsilon_solvent = ir->gb_epsilon_solvent;
502 born->epsilon_r = ir->epsilon_r;
504 doffset = born->gb_doffset;
506 /* If Still model, initialise the polarisation energies */
507 if(gb_algorithm==egbSTILL)
509 init_gb_still(cr, fr,&(mtop->atomtypes), &(localtop->idef), &atoms,
514 /* If HCT/OBC, precalculate the sk*atype->S_hct factors */
515 else if(gb_algorithm==egbHCT || gb_algorithm==egbOBC)
518 snew(born->gpol_hct_work, natoms+3);
520 for(i=0;i<natoms;i++)
522 if(born->use_globalindex[i]==1)
524 rai = mtop->atomtypes.gb_radius[atoms.atom[i].type]-doffset;
525 sk = rai * mtop->atomtypes.S_hct[atoms.atom[i].type];
526 born->param_globalindex[i] = sk;
527 born->gb_radius_globalindex[i] = rai;
531 born->param_globalindex[i] = 0;
532 born->gb_radius_globalindex[i] = 0;
537 /* Init the logarithm table */
538 p=pow(2,LOG_TABLE_ACCURACY);
539 snew(born->log_table, p);
541 fill_log_table(LOG_TABLE_ACCURACY, born->log_table);
543 /* Allocate memory for work arrays for temporary use */
544 snew(born->work,natoms+4);
545 snew(born->count,natoms);
546 snew(born->nblist_work,natoms);
548 /* Domain decomposition specific stuff */
557 calc_gb_rad_still(t_commrec *cr, t_forcerec *fr,int natoms, gmx_localtop_t *top,
558 const t_atomtypes *atype, rvec x[], t_nblist *nl,
559 gmx_genborn_t *born,t_mdatoms *md)
561 int i,k,n,nj0,nj1,ai,aj,type;
564 real gpi,dr,dr2,dr4,idr4,rvdw,ratio,ccf,theta,term,rai,raj;
565 real ix1,iy1,iz1,jx1,jy1,jz1,dx11,dy11,dz11;
566 real rinv,idr2,idr6,vaj,dccf,cosq,sinq,prod,gpi2;
568 real vai, prod_ai, icf4,icf6;
570 factor = 0.5*ONE_4PI_EPS0;
573 for(i=0;i<born->nr;i++)
575 born->gpol_still_work[i]=0;
578 for(i=0;i<nl->nri;i++ )
583 nj1 = nl->jindex[i+1];
585 /* Load shifts for this list */
586 shift = nl->shift[i];
587 shX = fr->shift_vec[shift][0];
588 shY = fr->shift_vec[shift][1];
589 shZ = fr->shift_vec[shift][2];
593 rai = top->atomtypes.gb_radius[md->typeA[ai]];
594 vai = born->vsolv[ai];
595 prod_ai = STILL_P4*vai;
597 /* Load atom i coordinates, add shift vectors */
598 ix1 = shX + x[ai][0];
599 iy1 = shY + x[ai][1];
600 iz1 = shZ + x[ai][2];
613 dr2 = dx11*dx11+dy11*dy11+dz11*dz11;
614 rinv = gmx_invsqrt(dr2);
619 raj = top->atomtypes.gb_radius[md->typeA[aj]];
623 ratio = dr2 / (rvdw * rvdw);
624 vaj = born->vsolv[aj];
626 if(ratio>STILL_P5INV)
633 theta = ratio*STILL_PIP5;
635 term = 0.5*(1.0-cosq);
637 sinq = 1.0 - cosq*cosq;
638 dccf = 2.0*term*sinq*gmx_invsqrt(sinq)*theta;
643 icf6 = (4*ccf-dccf)*idr6;
645 born->gpol_still_work[aj] += prod_ai*icf4;
648 /* Save ai->aj and aj->ai chain rule terms */
649 fr->dadx[n++] = prod*icf6;
650 fr->dadx[n++] = prod_ai*icf6;
652 born->gpol_still_work[ai]+=gpi;
655 /* Parallel summations */
658 gmx_sum(natoms, born->gpol_still_work, cr);
660 else if(DOMAINDECOMP(cr))
662 dd_atom_sum_real(cr->dd, born->gpol_still_work);
665 /* Calculate the radii */
666 for(i=0;i<fr->natoms_force;i++) /* PELA born->nr */
668 if(born->use[i] != 0)
671 gpi = born->gpol[i]+born->gpol_still_work[i];
673 born->bRad[i] = factor*gmx_invsqrt(gpi2);
674 fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
678 /* Extra communication required for DD */
681 dd_atom_spread_real(cr->dd, born->bRad);
682 dd_atom_spread_real(cr->dd, fr->invsqrta);
691 calc_gb_rad_hct(t_commrec *cr,t_forcerec *fr,int natoms, gmx_localtop_t *top,
692 const t_atomtypes *atype, rvec x[], t_nblist *nl,
693 gmx_genborn_t *born,t_mdatoms *md)
695 int i,k,n,ai,aj,nj0,nj1,at0,at1;
698 real rai,raj,gpi,dr2,dr,sk,sk_ai,sk2,sk2_ai,lij,uij,diff2,tmp,sum_ai;
699 real rad,min_rad,rinv,rai_inv;
700 real ix1,iy1,iz1,jx1,jy1,jz1,dx11,dy11,dz11;
701 real lij2, uij2, lij3, uij3, t1,t2,t3;
702 real lij_inv,dlij,duij,sk2_rinv,prod,log_term;
703 real doffset,raj_inv,dadx_val;
706 doffset = born->gb_doffset;
707 gb_radius = born->gb_radius;
709 for(i=0;i<born->nr;i++)
711 born->gpol_hct_work[i] = 0;
714 /* Keep the compiler happy */
718 for(i=0;i<nl->nri;i++)
722 nj0 = nl->jindex[ai];
723 nj1 = nl->jindex[ai+1];
725 /* Load shifts for this list */
726 shift = nl->shift[i];
727 shX = fr->shift_vec[shift][0];
728 shY = fr->shift_vec[shift][1];
729 shZ = fr->shift_vec[shift][2];
734 sk_ai = born->param[ai];
735 sk2_ai = sk_ai*sk_ai;
737 /* Load atom i coordinates, add shift vectors */
738 ix1 = shX + x[ai][0];
739 iy1 = shY + x[ai][1];
740 iz1 = shZ + x[ai][2];
756 dr2 = dx11*dx11+dy11*dy11+dz11*dz11;
757 rinv = gmx_invsqrt(dr2);
760 sk = born->param[aj];
763 /* aj -> ai interaction */
784 lij_inv = gmx_invsqrt(lij2);
787 prod = 0.25*sk2_rinv;
789 /* log_term = table_log(uij*lij_inv,born->log_table,
790 LOG_TABLE_ACCURACY); */
791 log_term = log(uij*lij_inv);
793 tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term +
798 tmp = tmp + 2.0 * (rai_inv-lij);
801 t1 = 0.5*lij2 + prod*lij3 - 0.25*(lij*rinv+lij3*dr);
802 t2 = -0.5*uij2 - 0.25*sk2_rinv*uij3 + 0.25*(uij*rinv+uij3*dr);
803 t3 = 0.125*(1.0+sk2_rinv*rinv)*(-diff2)+0.25*log_term*rinv*rinv;
805 dadx_val = (dlij*t1+t2+t3)*rinv; /* rb2 is moved to chainrule */
806 /* fr->dadx[n++] = (dlij*t1+duij*t2+t3)*rinv; */
807 /* rb2 is moved to chainrule */
815 fr->dadx[n++] = dadx_val;
818 /* ai -> aj interaction */
821 lij = 1.0/(dr-sk_ai);
834 uij = 1.0/(dr+sk_ai);
840 lij_inv = gmx_invsqrt(lij2);
841 sk2 = sk2_ai; /* sk2_ai = sk_ai * sk_ai in i loop above */
843 prod = 0.25 * sk2_rinv;
845 /* log_term = table_log(uij*lij_inv,born->log_table,
846 LOG_TABLE_ACCURACY); */
847 log_term = log(uij*lij_inv);
849 tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term +
854 tmp = tmp + 2.0 * (raj_inv-lij);
858 t1 = 0.5*lij2 + prod*lij3 - 0.25*(lij*rinv+lij3*dr);
859 t2 = -0.5*uij2 - 0.25*sk2_rinv*uij3 + 0.25*(uij*rinv+uij3*dr);
860 t3 = 0.125*(1.0+sk2_rinv*rinv)*(-diff2)+0.25*log_term*rinv*rinv;
862 dadx_val = (dlij*t1+t2+t3)*rinv; /* rb2 is moved to chainrule */
863 /* fr->dadx[n++] = (dlij*t1+duij*t2+t3)*rinv; */ /* rb2 is moved to chainrule */
865 born->gpol_hct_work[aj] += 0.5*tmp;
871 fr->dadx[n++] = dadx_val;
874 born->gpol_hct_work[ai] += sum_ai;
877 /* Parallel summations */
880 gmx_sum(natoms, born->gpol_hct_work, cr);
882 else if(DOMAINDECOMP(cr))
884 dd_atom_sum_real(cr->dd, born->gpol_hct_work);
887 for(i=0;i<fr->natoms_force;i++) /* PELA born->nr */
889 if(born->use[i] != 0)
891 rai = top->atomtypes.gb_radius[md->typeA[i]]-doffset;
892 sum_ai = 1.0/rai - born->gpol_hct_work[i];
893 min_rad = rai + doffset;
896 born->bRad[i] = rad > min_rad ? rad : min_rad;
897 fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
901 /* Extra communication required for DD */
904 dd_atom_spread_real(cr->dd, born->bRad);
905 dd_atom_spread_real(cr->dd, fr->invsqrta);
913 calc_gb_rad_obc(t_commrec *cr, t_forcerec *fr, int natoms, gmx_localtop_t *top,
914 const t_atomtypes *atype, rvec x[], t_nblist *nl, gmx_genborn_t *born,t_mdatoms *md)
916 int i,k,ai,aj,nj0,nj1,n,at0,at1;
919 real rai,raj,gpi,dr2,dr,sk,sk2,lij,uij,diff2,tmp,sum_ai;
920 real rad, min_rad,sum_ai2,sum_ai3,tsum,tchain,rinv,rai_inv,lij_inv,rai_inv2;
921 real log_term,prod,sk2_rinv,sk_ai,sk2_ai;
922 real ix1,iy1,iz1,jx1,jy1,jz1,dx11,dy11,dz11;
923 real lij2,uij2,lij3,uij3,dlij,duij,t1,t2,t3;
924 real doffset,raj_inv,dadx_val;
927 /* Keep the compiler happy */
932 doffset = born->gb_doffset;
933 gb_radius = born->gb_radius;
935 for(i=0;i<born->nr;i++)
937 born->gpol_hct_work[i] = 0;
940 for(i=0;i<nl->nri;i++)
945 nj1 = nl->jindex[i+1];
947 /* Load shifts for this list */
948 shift = nl->shift[i];
949 shX = fr->shift_vec[shift][0];
950 shY = fr->shift_vec[shift][1];
951 shZ = fr->shift_vec[shift][2];
956 sk_ai = born->param[ai];
957 sk2_ai = sk_ai*sk_ai;
959 /* Load atom i coordinates, add shift vectors */
960 ix1 = shX + x[ai][0];
961 iy1 = shY + x[ai][1];
962 iz1 = shZ + x[ai][2];
978 dr2 = dx11*dx11+dy11*dy11+dz11*dz11;
979 rinv = gmx_invsqrt(dr2);
982 /* sk is precalculated in init_gb() */
983 sk = born->param[aj];
986 /* aj -> ai interaction */
1006 lij_inv = gmx_invsqrt(lij2);
1008 sk2_rinv = sk2*rinv;
1009 prod = 0.25*sk2_rinv;
1011 log_term = log(uij*lij_inv);
1013 /* log_term = table_log(uij*lij_inv,born->log_table,LOG_TABLE_ACCURACY); */
1014 tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term + prod*(-diff2);
1018 tmp = tmp + 2.0 * (rai_inv-lij);
1022 t1 = 0.5*lij2 + prod*lij3 - 0.25*(lij*rinv+lij3*dr);
1023 t2 = -0.5*uij2 - 0.25*sk2_rinv*uij3 + 0.25*(uij*rinv+uij3*dr);
1024 t3 = 0.125*(1.0+sk2_rinv*rinv)*(-diff2)+0.25*log_term*rinv*rinv;
1026 dadx_val = (dlij*t1+t2+t3)*rinv; /* rb2 is moved to chainrule */
1034 fr->dadx[n++] = dadx_val;
1036 /* ai -> aj interaction */
1037 if(raj < dr + sk_ai)
1039 lij = 1.0/(dr-sk_ai);
1052 uij = 1.0/(dr+sk_ai);
1058 lij_inv = gmx_invsqrt(lij2);
1059 sk2 = sk2_ai; /* sk2_ai = sk_ai * sk_ai in i loop above */
1060 sk2_rinv = sk2*rinv;
1061 prod = 0.25 * sk2_rinv;
1063 /* log_term = table_log(uij*lij_inv,born->log_table,LOG_TABLE_ACCURACY); */
1064 log_term = log(uij*lij_inv);
1066 tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term + prod*(-diff2);
1070 tmp = tmp + 2.0 * (raj_inv-lij);
1073 t1 = 0.5*lij2 + prod*lij3 - 0.25*(lij*rinv+lij3*dr);
1074 t2 = -0.5*uij2 - 0.25*sk2_rinv*uij3 + 0.25*(uij*rinv+uij3*dr);
1075 t3 = 0.125*(1.0+sk2_rinv*rinv)*(-diff2)+0.25*log_term*rinv*rinv;
1077 dadx_val = (dlij*t1+t2+t3)*rinv; /* rb2 is moved to chainrule */
1079 born->gpol_hct_work[aj] += 0.5*tmp;
1086 fr->dadx[n++] = dadx_val;
1089 born->gpol_hct_work[ai] += sum_ai;
1093 /* Parallel summations */
1096 gmx_sum(natoms, born->gpol_hct_work, cr);
1098 else if(DOMAINDECOMP(cr))
1100 dd_atom_sum_real(cr->dd, born->gpol_hct_work);
1103 for(i=0;i<fr->natoms_force;i++) /* PELA born->nr */
1105 if(born->use[i] != 0)
1107 rai = top->atomtypes.gb_radius[md->typeA[i]];
1111 sum_ai = rai * born->gpol_hct_work[i];
1112 sum_ai2 = sum_ai * sum_ai;
1113 sum_ai3 = sum_ai2 * sum_ai;
1115 tsum = tanh(born->obc_alpha*sum_ai-born->obc_beta*sum_ai2+born->obc_gamma*sum_ai3);
1116 born->bRad[i] = rai_inv - tsum*rai_inv2;
1117 born->bRad[i] = 1.0 / born->bRad[i];
1119 fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
1121 tchain = rai * (born->obc_alpha-2*born->obc_beta*sum_ai+3*born->obc_gamma*sum_ai2);
1122 born->drobc[i] = (1.0-tsum*tsum)*tchain*rai_inv2;
1126 /* Extra (local) communication required for DD */
1127 if(DOMAINDECOMP(cr))
1129 dd_atom_spread_real(cr->dd, born->bRad);
1130 dd_atom_spread_real(cr->dd, fr->invsqrta);
1131 dd_atom_spread_real(cr->dd, born->drobc);
1140 int calc_gb_rad(t_commrec *cr, t_forcerec *fr, t_inputrec *ir,gmx_localtop_t *top,
1141 const t_atomtypes *atype, rvec x[], t_nblist *nl, gmx_genborn_t *born,t_mdatoms *md,t_nrnb *nrnb)
1147 if(fr->bAllvsAll && fr->dadx==NULL)
1149 /* We might need up to 8 atoms of padding before and after,
1150 * and another 4 units to guarantee SSE alignment.
1152 fr->nalloc_dadx = 2*(md->homenr+12)*(md->nr/2+1+12);
1153 snew(fr->dadx_rawptr,fr->nalloc_dadx);
1154 fr->dadx = (real *) (((size_t) fr->dadx_rawptr + 16) & (~((size_t) 15)));
1158 /* In the SSE-enabled gb-loops, when writing to dadx, we
1159 * always write 2*4 elements at a time, even in the case with only
1160 * 1-3 j particles, where we only really need to write 2*(1-3)
1161 * elements. This is because we want dadx to be aligned to a 16-
1162 * byte boundary, and being able to use _mm_store/load_ps
1164 ndadx = 2 * (nl->nrj + 3*nl->nri);
1166 /* First, reallocate the dadx array, we need 3 extra for SSE */
1167 if (ndadx + 3 > fr->nalloc_dadx)
1169 fr->nalloc_dadx = over_alloc_large(ndadx) + 3;
1170 srenew(fr->dadx_rawptr,fr->nalloc_dadx);
1171 fr->dadx = (real *) (((size_t) fr->dadx_rawptr + 16) & (~((size_t) 15)));
1177 cnt = md->homenr*(md->nr/2+1);
1179 if(ir->gb_algorithm==egbSTILL)
1181 #if ( defined(GMX_IA32_SSE) || defined(GMX_X86_64_SSE) || (!defined(GMX_DOUBLE) && defined(GMX_SSE2)) )
1182 if(fr->UseOptimizedKernels)
1184 genborn_allvsall_calc_still_radii_sse2_single(fr,md,born,top,x[0],cr,&fr->AllvsAll_workgb);
1188 genborn_allvsall_calc_still_radii(fr,md,born,top,x[0],cr,&fr->AllvsAll_workgb);
1190 #elif ( defined(GMX_IA32_SSE2) || defined(GMX_X86_64_SSE2) || (defined(GMX_DOUBLE) && defined(GMX_SSE2)) )
1191 if(fr->UseOptimizedKernels)
1193 genborn_allvsall_calc_still_radii_sse2_double(fr,md,born,top,x[0],cr,&fr->AllvsAll_workgb);
1197 genborn_allvsall_calc_still_radii(fr,md,born,top,x[0],cr,&fr->AllvsAll_workgb);
1200 genborn_allvsall_calc_still_radii(fr,md,born,top,x[0],cr,&fr->AllvsAll_workgb);
1202 inc_nrnb(nrnb,eNR_BORN_AVA_RADII_STILL,cnt);
1204 else if(ir->gb_algorithm==egbHCT || ir->gb_algorithm==egbOBC)
1206 #if ( defined(GMX_IA32_SSE) || defined(GMX_X86_64_SSE) || (!defined(GMX_DOUBLE) && defined(GMX_SSE2)) )
1207 if(fr->UseOptimizedKernels)
1209 genborn_allvsall_calc_hct_obc_radii_sse2_single(fr,md,born,ir->gb_algorithm,top,x[0],cr,&fr->AllvsAll_workgb);
1213 genborn_allvsall_calc_hct_obc_radii(fr,md,born,ir->gb_algorithm,top,x[0],cr,&fr->AllvsAll_workgb);
1215 #elif ( defined(GMX_IA32_SSE2) || defined(GMX_X86_64_SSE2) || (defined(GMX_DOUBLE) && defined(GMX_SSE2)) )
1216 if(fr->UseOptimizedKernels)
1218 genborn_allvsall_calc_hct_obc_radii_sse2_double(fr,md,born,ir->gb_algorithm,top,x[0],cr,&fr->AllvsAll_workgb);
1222 genborn_allvsall_calc_hct_obc_radii(fr,md,born,ir->gb_algorithm,top,x[0],cr,&fr->AllvsAll_workgb);
1225 genborn_allvsall_calc_hct_obc_radii(fr,md,born,ir->gb_algorithm,top,x[0],cr,&fr->AllvsAll_workgb);
1227 inc_nrnb(nrnb,eNR_BORN_AVA_RADII_HCT_OBC,cnt);
1231 gmx_fatal(FARGS,"Bad gb algorithm for all-vs-all interactions");
1233 inc_nrnb(nrnb,eNR_NBKERNEL_OUTER,md->homenr);
1238 /* Switch for determining which algorithm to use for Born radii calculation */
1241 #if ( defined(GMX_IA32_SSE2) || defined(GMX_X86_64_SSE2) || defined(GMX_SSE2) )
1242 /* x86 or x86-64 with GCC inline assembly and/or SSE intrinsics */
1243 switch(ir->gb_algorithm)
1246 if(fr->UseOptimizedKernels)
1248 calc_gb_rad_still_sse2_double(cr,fr,md->nr,top, atype, x[0], nl, born);
1252 calc_gb_rad_still(cr,fr,born->nr,top,atype,x,nl,born,md);
1256 if(fr->UseOptimizedKernels)
1258 calc_gb_rad_hct_obc_sse2_double(cr,fr,born->nr,top, atype, x[0], nl, born, md, ir->gb_algorithm);
1262 calc_gb_rad_hct(cr,fr,born->nr,top,atype,x,nl,born,md);
1266 if(fr->UseOptimizedKernels)
1268 calc_gb_rad_hct_obc_sse2_double(cr,fr,born->nr,top, atype, x[0], nl, born, md, ir->gb_algorithm);
1272 calc_gb_rad_obc(cr,fr,born->nr,top,atype,x,nl,born,md);
1277 gmx_fatal(FARGS, "Unknown double precision sse-enabled algorithm for Born radii calculation: %d",ir->gb_algorithm);
1280 switch(ir->gb_algorithm)
1283 calc_gb_rad_still(cr,fr,born->nr,top,atype,x,nl,born,md);
1286 calc_gb_rad_hct(cr,fr,born->nr,top,atype,x,nl,born,md);
1289 calc_gb_rad_obc(cr,fr,born->nr,top,atype,x,nl,born,md);
1293 gmx_fatal(FARGS, "Unknown double precision algorithm for Born radii calculation: %d",ir->gb_algorithm);
1300 #if (!defined DISABLE_SSE && ( defined(GMX_IA32_SSE) || defined(GMX_X86_64_SSE) || defined(GMX_SSE2) ) )
1301 /* x86 or x86-64 with GCC inline assembly and/or SSE intrinsics */
1302 switch(ir->gb_algorithm)
1305 if(fr->UseOptimizedKernels)
1307 calc_gb_rad_still_sse2_single(cr,fr,born->nr,top, atype, x[0], nl, born);
1311 calc_gb_rad_still(cr,fr,born->nr,top,atype,x,nl,born,md);
1315 if(fr->UseOptimizedKernels)
1317 calc_gb_rad_hct_obc_sse2_single(cr,fr,born->nr,top, atype, x[0], nl, born, md, ir->gb_algorithm);
1321 calc_gb_rad_hct(cr,fr,born->nr,top,atype,x,nl,born,md);
1326 if(fr->UseOptimizedKernels)
1328 calc_gb_rad_hct_obc_sse2_single(cr,fr,born->nr,top, atype, x[0], nl, born, md, ir->gb_algorithm);
1332 calc_gb_rad_obc(cr,fr,born->nr,top,atype,x,nl,born,md);
1337 gmx_fatal(FARGS, "Unknown sse-enabled algorithm for Born radii calculation: %d",ir->gb_algorithm);
1341 switch(ir->gb_algorithm)
1344 calc_gb_rad_still(cr,fr,born->nr,top,atype,x,nl,born,md);
1347 calc_gb_rad_hct(cr,fr,born->nr,top,atype,x,nl,born,md);
1350 calc_gb_rad_obc(cr,fr,born->nr,top,atype,x,nl,born,md);
1354 gmx_fatal(FARGS, "Unknown algorithm for Born radii calculation: %d",ir->gb_algorithm);
1357 #endif /* Single precision sse */
1359 #endif /* Double or single precision */
1361 if(fr->bAllvsAll==FALSE)
1363 switch(ir->gb_algorithm)
1366 inc_nrnb(nrnb,eNR_BORN_RADII_STILL,nl->nrj);
1370 inc_nrnb(nrnb,eNR_BORN_RADII_HCT_OBC,nl->nrj);
1376 inc_nrnb(nrnb,eNR_NBKERNEL_OUTER,nl->nri);
1384 real gb_bonds_tab(rvec x[], rvec f[], rvec fshift[], real *charge, real *p_gbtabscale,
1385 real *invsqrta, real *dvda, real *GBtab, t_idef *idef, real epsilon_r,
1386 real gb_epsilon_solvent, real facel, const t_pbc *pbc, const t_graph *graph)
1388 int i,j,n0,m,nnn,type,ai,aj;
1394 real isaprod,qq,gbscale,gbtabscale,Y,F,Geps,Heps2,Fp,VV,FF,rt,eps,eps2;
1395 real vgb,fgb,vcoul,fijC,dvdatmp,fscal,dvdaj;
1401 t_iatom *forceatoms;
1403 /* Scale the electrostatics by gb_epsilon_solvent */
1404 facel = facel * ((1.0/epsilon_r) - 1.0/gb_epsilon_solvent);
1406 gbtabscale=*p_gbtabscale;
1409 for(j=F_GB12;j<=F_GB14;j++)
1411 forceatoms = idef->il[j].iatoms;
1413 for(i=0;i<idef->il[j].nr; )
1415 /* To avoid reading in the interaction type, we just increment i to pass over
1416 * the types in the forceatoms array, this saves some memory accesses
1419 ai = forceatoms[i++];
1420 aj = forceatoms[i++];
1422 ki = pbc_rvec_sub(pbc,x[ai],x[aj],dx);
1423 rsq11 = iprod(dx,dx);
1425 isai = invsqrta[ai];
1426 iq = (-1)*facel*charge[ai];
1428 rinv11 = gmx_invsqrt(rsq11);
1429 isaj = invsqrta[aj];
1430 isaprod = isai*isaj;
1431 qq = isaprod*iq*charge[aj];
1432 gbscale = isaprod*gbtabscale;
1441 Geps = eps*GBtab[nnn+2];
1442 Heps2 = eps2*GBtab[nnn+3];
1445 FF = Fp+Geps+2.0*Heps2;
1447 fijC = qq*FF*gbscale;
1448 dvdatmp = -(vgb+fijC*r)*0.5;
1449 dvda[aj] = dvda[aj] + dvdatmp*isaj*isaj;
1450 dvda[ai] = dvda[ai] + dvdatmp*isai*isai;
1451 vctot = vctot + vgb;
1452 fgb = -(fijC)*rinv11;
1455 ivec_sub(SHIFT_IVEC(graph,ai),SHIFT_IVEC(graph,aj),dt);
1459 for (m=0; (m<DIM); m++) { /* 15 */
1463 fshift[ki][m]+=fscal;
1464 fshift[CENTRAL][m]-=fscal;
1472 real calc_gb_selfcorrections(t_commrec *cr, int natoms,
1473 real *charge, gmx_genborn_t *born, real *dvda, t_mdatoms *md, double facel)
1476 real rai,e,derb,q,q2,fi,rai_inv,vtot;
1480 pd_at_range(cr,&at0,&at1);
1482 else if(DOMAINDECOMP(cr))
1485 at1=cr->dd->nat_home;
1494 /* Scale the electrostatics by gb_epsilon_solvent */
1495 facel = facel * ((1.0/born->epsilon_r) - 1.0/born->gb_epsilon_solvent);
1499 /* Apply self corrections */
1500 for(i=at0;i<at1;i++)
1504 if(born->use[ai]==1)
1506 rai = born->bRad[ai];
1512 derb = 0.5*e*rai_inv*rai_inv;
1513 dvda[ai] += derb*rai;
1522 real calc_gb_nonpolar(t_commrec *cr, t_forcerec *fr,int natoms,gmx_genborn_t *born, gmx_localtop_t *top,
1523 const t_atomtypes *atype, real *dvda,int gb_algorithm, t_mdatoms *md)
1526 real e,es,rai,rbi,term,probe,tmp,factor;
1527 real rbi_inv,rbi_inv2;
1529 /* To keep the compiler happy */
1534 pd_at_range(cr,&at0,&at1);
1536 else if(DOMAINDECOMP(cr))
1539 at1 = cr->dd->nat_home;
1547 /* The surface area factor is 0.0049 for Still model, 0.0054 for HCT/OBC */
1548 if(gb_algorithm==egbSTILL)
1550 factor=0.0049*100*CAL2JOULE;
1554 factor=0.0054*100*CAL2JOULE;
1557 /* if(gb_algorithm==egbHCT || gb_algorithm==egbOBC) */
1563 for(i=at0;i<at1;i++)
1567 if(born->use[ai]==1)
1569 rai = top->atomtypes.gb_radius[md->typeA[ai]];
1570 rbi_inv = fr->invsqrta[ai];
1571 rbi_inv2 = rbi_inv * rbi_inv;
1572 tmp = (rai*rbi_inv2)*(rai*rbi_inv2);
1574 e = factor*term*(rai+probe)*(rai+probe)*tmp;
1575 dvda[ai] = dvda[ai] - 6*e*rbi_inv2;
1585 real calc_gb_chainrule(int natoms, t_nblist *nl, real *dadx, real *dvda, rvec x[], rvec t[], rvec fshift[],
1586 rvec shift_vec[], int gb_algorithm, gmx_genborn_t *born, t_mdatoms *md)
1588 int i,k,n,ai,aj,nj0,nj1,n0,n1;
1591 real fgb,fij,rb2,rbi,fix1,fiy1,fiz1;
1592 real ix1,iy1,iz1,jx1,jy1,jz1,dx11,dy11,dz11,rsq11;
1593 real rinv11,tx,ty,tz,rbai,rbaj,fgb_ai;
1602 n1 = md->start+md->homenr+1+natoms/2;
1604 if(gb_algorithm==egbSTILL)
1609 rbi = born->bRad[k];
1610 rb[k] = (2 * rbi * rbi * dvda[k])/ONE_4PI_EPS0;
1613 else if(gb_algorithm==egbHCT)
1618 rbi = born->bRad[k];
1619 rb[k] = rbi * rbi * dvda[k];
1622 else if(gb_algorithm==egbOBC)
1627 rbi = born->bRad[k];
1628 rb[k] = rbi * rbi * born->drobc[k] * dvda[k];
1632 for(i=0;i<nl->nri;i++)
1636 nj0 = nl->jindex[i];
1637 nj1 = nl->jindex[i+1];
1639 /* Load shifts for this list */
1640 shift = nl->shift[i];
1641 shX = shift_vec[shift][0];
1642 shY = shift_vec[shift][1];
1643 shZ = shift_vec[shift][2];
1645 /* Load atom i coordinates, add shift vectors */
1646 ix1 = shX + x[ai][0];
1647 iy1 = shY + x[ai][1];
1648 iz1 = shZ + x[ai][2];
1656 for(k=nj0;k<nj1;k++)
1670 fgb = rbai*dadx[n++];
1671 fgb_ai = rbaj*dadx[n++];
1673 /* Total force between ai and aj is the sum of ai->aj and aj->ai */
1684 /* Update force on atom aj */
1685 t[aj][0] = t[aj][0] - tx;
1686 t[aj][1] = t[aj][1] - ty;
1687 t[aj][2] = t[aj][2] - tz;
1690 /* Update force and shift forces on atom ai */
1691 t[ai][0] = t[ai][0] + fix1;
1692 t[ai][1] = t[ai][1] + fiy1;
1693 t[ai][2] = t[ai][2] + fiz1;
1695 fshift[shift][0] = fshift[shift][0] + fix1;
1696 fshift[shift][1] = fshift[shift][1] + fiy1;
1697 fshift[shift][2] = fshift[shift][2] + fiz1;
1706 calc_gb_forces(t_commrec *cr, t_mdatoms *md, gmx_genborn_t *born, gmx_localtop_t *top, const t_atomtypes *atype,
1707 rvec x[], rvec f[], t_forcerec *fr, t_idef *idef, int gb_algorithm, t_nrnb *nrnb, bool bRad,
1708 const t_pbc *pbc, const t_graph *graph, gmx_enerdata_t *enerd)
1715 const t_pbc *pbc_null;
1722 /* Do a simple ACE type approximation for the non-polar solvation */
1723 enerd->term[F_NPSOLVATION] += calc_gb_nonpolar(cr, fr,born->nr, born, top, atype, fr->dvda, gb_algorithm,md);
1725 /* Calculate the bonded GB-interactions using either table or analytical formula */
1726 enerd->term[F_GBPOL] += gb_bonds_tab(x,f,fr->fshift, md->chargeA,&(fr->gbtabscale),
1727 fr->invsqrta,fr->dvda,fr->gbtab.tab,idef,born->epsilon_r,born->gb_epsilon_solvent, fr->epsfac, pbc_null, graph);
1729 /* Calculate self corrections to the GB energies - currently only A state used! (FIXME) */
1730 enerd->term[F_GBPOL] += calc_gb_selfcorrections(cr,born->nr,md->chargeA, born, fr->dvda, md, fr->epsfac);
1732 /* If parallel, sum the derivative of the potential w.r.t the born radii */
1735 gmx_sum(md->nr,fr->dvda, cr);
1737 else if(DOMAINDECOMP(cr))
1739 dd_atom_sum_real(cr->dd,fr->dvda);
1740 dd_atom_spread_real(cr->dd,fr->dvda);
1745 #if ( defined(GMX_IA32_SSE) || defined(GMX_X86_64_SSE) || (!defined(GMX_DOUBLE) && defined(GMX_SSE2)) )
1746 if(fr->UseOptimizedKernels)
1748 genborn_allvsall_calc_chainrule_sse2_single(fr,md,born,x[0],f[0],gb_algorithm,fr->AllvsAll_workgb);
1752 genborn_allvsall_calc_chainrule(fr,md,born,x[0],f[0],gb_algorithm,fr->AllvsAll_workgb);
1754 #elif ( defined(GMX_IA32_SSE2) || defined(GMX_X86_64_SSE2) || (defined(GMX_DOUBLE) && defined(GMX_SSE2)) )
1755 if(fr->UseOptimizedKernels)
1757 genborn_allvsall_calc_chainrule_sse2_double(fr,md,born,x[0],f[0],gb_algorithm,fr->AllvsAll_workgb);
1761 genborn_allvsall_calc_chainrule(fr,md,born,x[0],f[0],gb_algorithm,fr->AllvsAll_workgb);
1764 genborn_allvsall_calc_chainrule(fr,md,born,x[0],f[0],gb_algorithm,fr->AllvsAll_workgb);
1766 cnt = md->homenr*(md->nr/2+1);
1767 inc_nrnb(nrnb,eNR_BORN_AVA_CHAINRULE,cnt);
1768 inc_nrnb(nrnb,eNR_NBKERNEL_OUTER,md->homenr);
1774 #if ( defined(GMX_IA32_SSE2) || defined(GMX_X86_64_SSE2) || (defined(GMX_DOUBLE) && defined(GMX_SSE2)) )
1775 if(fr->UseOptimizedKernels)
1777 calc_gb_chainrule_sse2_double(born->nr, &(fr->gblist), fr->dadx, fr->dvda,
1778 x[0], f[0], fr->fshift[0], fr->shift_vec[0],
1779 gb_algorithm, born, md);
1783 calc_gb_chainrule(born->nr, &(fr->gblist), fr->dadx, fr->dvda,
1784 x, f, fr->fshift, fr->shift_vec, gb_algorithm, born, md);
1787 calc_gb_chainrule(born->nr, &(fr->gblist), fr->dadx, fr->dvda,
1788 x, f, fr->fshift, fr->shift_vec, gb_algorithm, born, md);
1793 #if ( defined(GMX_IA32_SSE) || defined(GMX_X86_64_SSE) || (!defined(GMX_DOUBLE) && defined(GMX_SSE2)) )
1794 /* x86 or x86-64 with GCC inline assembly and/or SSE intrinsics */
1795 if(fr->UseOptimizedKernels)
1797 calc_gb_chainrule_sse2_single(born->nr, &(fr->gblist), fr->dadx, fr->dvda,
1798 x[0], f[0], fr->fshift[0], fr->shift_vec[0],
1799 gb_algorithm, born, md);
1803 calc_gb_chainrule(born->nr, &(fr->gblist), fr->dadx, fr->dvda,
1804 x, f, fr->fshift, fr->shift_vec, gb_algorithm, born, md);
1808 /* Calculate the forces due to chain rule terms with non sse code */
1809 calc_gb_chainrule(born->nr, &(fr->gblist), fr->dadx, fr->dvda,
1810 x, f, fr->fshift, fr->shift_vec, gb_algorithm, born, md);
1816 inc_nrnb(nrnb,eNR_BORN_CHAINRULE,fr->gblist.nrj);
1817 inc_nrnb(nrnb,eNR_NBKERNEL_OUTER,fr->gblist.nri);
1822 static void add_j_to_gblist(gbtmpnbl_t *list,int aj)
1824 if (list->naj >= list->aj_nalloc)
1826 list->aj_nalloc = over_alloc_large(list->naj+1);
1827 srenew(list->aj,list->aj_nalloc);
1830 list->aj[list->naj++] = aj;
1833 static gbtmpnbl_t *find_gbtmplist(struct gbtmpnbls *lists,int shift)
1837 /* Search the list with the same shift, if there is one */
1839 while (ind < lists->nlist && shift != lists->list[ind].shift)
1843 if (ind == lists->nlist)
1845 if (lists->nlist == lists->list_nalloc)
1847 lists->list_nalloc++;
1848 srenew(lists->list,lists->list_nalloc);
1849 for(i=lists->nlist; i<lists->list_nalloc; i++)
1851 lists->list[i].aj = NULL;
1852 lists->list[i].aj_nalloc = 0;
1857 lists->list[lists->nlist].shift = shift;
1858 lists->list[lists->nlist].naj = 0;
1862 return &lists->list[ind];
1865 static void add_bondeds_to_gblist(t_ilist *il,
1866 bool bMolPBC,t_pbc *pbc,t_graph *g,rvec *x,
1867 struct gbtmpnbls *nls)
1869 int ind,j,ai,aj,shift,found;
1875 for(ind=0; ind<il->nr; ind+=3)
1877 ai = il->iatoms[ind+1];
1878 aj = il->iatoms[ind+2];
1883 rvec_sub(x[ai],x[aj],dx);
1884 ivec_sub(SHIFT_IVEC(g,ai),SHIFT_IVEC(g,aj),dt);
1885 shift = IVEC2IS(dt);
1889 shift = pbc_dx_aiuc(pbc,x[ai],x[aj],dx);
1892 /* Find the list for this shift or create one */
1893 list = find_gbtmplist(&nls[ai],shift);
1897 /* So that we do not add the same bond twice.
1898 * This happens with some constraints between 1-3 atoms
1899 * that are in the bond-list but should not be in the GB nb-list */
1900 for(j=0;j<list->naj;j++)
1902 if (list->aj[j] == aj)
1912 gmx_incons("ai == aj");
1915 add_j_to_gblist(list,aj);
1921 compare_int (const void * a, const void * b)
1923 return ( *(int*)a - *(int*)b );
1928 int make_gb_nblist(t_commrec *cr, int gb_algorithm, real gbcut,
1929 rvec x[], matrix box,
1930 t_forcerec *fr, t_idef *idef, t_graph *graph, gmx_genborn_t *born)
1932 int i,l,ii,j,k,n,nj0,nj1,ai,aj,at0,at1,found,shift,s;
1937 struct gbtmpnbls *nls;
1938 gbtmpnbl_t *list =NULL;
1940 set_pbc(&pbc,fr->ePBC,box);
1941 nls = born->nblist_work;
1943 for(i=0;i<born->nr;i++)
1950 set_pbc_dd(&pbc,fr->ePBC,cr->dd,TRUE,box);
1953 switch (gb_algorithm)
1957 /* Loop over 1-2, 1-3 and 1-4 interactions */
1958 for(j=F_GB12;j<=F_GB14;j++)
1960 add_bondeds_to_gblist(&idef->il[j],fr->bMolPBC,&pbc,graph,x,nls);
1964 /* Loop over 1-4 interactions */
1965 add_bondeds_to_gblist(&idef->il[F_GB14],fr->bMolPBC,&pbc,graph,x,nls);
1968 gmx_incons("Unknown GB algorithm");
1971 /* Loop over the VDWQQ and VDW nblists to set up the nonbonded part of the GB list */
1972 for(n=0; (n<fr->nnblists); n++)
1974 for(i=0; (i<eNL_NR); i++)
1976 nblist=&(fr->nblists[n].nlist_sr[i]);
1978 if (nblist->nri > 0 && (i==eNL_VDWQQ || i==eNL_QQ))
1980 for(j=0;j<nblist->nri;j++)
1982 ai = nblist->iinr[j];
1983 shift = nblist->shift[j];
1985 /* Find the list for this shift or create one */
1986 list = find_gbtmplist(&nls[ai],shift);
1988 nj0 = nblist->jindex[j];
1989 nj1 = nblist->jindex[j+1];
1991 /* Add all the j-atoms in the non-bonded list to the GB list */
1992 for(k=nj0;k<nj1;k++)
1994 add_j_to_gblist(list,nblist->jjnr[k]);
2001 /* Zero out some counters */
2005 fr->gblist.jindex[0] = fr->gblist.nri;
2007 for(i=0;i<fr->natoms_force;i++)
2009 for(s=0; s<nls[i].nlist; s++)
2011 list = &nls[i].list[s];
2013 /* Only add those atoms that actually have neighbours */
2014 if (born->use[i] != 0)
2016 fr->gblist.iinr[fr->gblist.nri] = i;
2017 fr->gblist.shift[fr->gblist.nri] = list->shift;
2020 for(k=0; k<list->naj; k++)
2022 /* Memory allocation for jjnr */
2023 if(fr->gblist.nrj >= fr->gblist.maxnrj)
2025 fr->gblist.maxnrj += over_alloc_large(fr->gblist.maxnrj);
2029 fprintf(debug,"Increasing GB neighbourlist j size to %d\n",fr->gblist.maxnrj);
2032 srenew(fr->gblist.jjnr,fr->gblist.maxnrj);
2036 if(i == list->aj[k])
2038 gmx_incons("i == list->aj[k]");
2040 fr->gblist.jjnr[fr->gblist.nrj++] = list->aj[k];
2043 fr->gblist.jindex[fr->gblist.nri] = fr->gblist.nrj;
2050 for(i=0;i<fr->gblist.nri;i++)
2052 nj0 = fr->gblist.jindex[i];
2053 nj1 = fr->gblist.jindex[i+1];
2054 ai = fr->gblist.iinr[i];
2057 for(j=nj0;j<nj1;j++)
2059 if(fr->gblist.jjnr[j]<ai)
2060 fr->gblist.jjnr[j]+=fr->natoms_force;
2062 qsort(fr->gblist.jjnr+nj0,nj1-nj0,sizeof(int),compare_int);
2064 for(j=nj0;j<nj1;j++)
2066 if(fr->gblist.jjnr[j]>=fr->natoms_force)
2067 fr->gblist.jjnr[j]-=fr->natoms_force;
2076 void make_local_gb(const t_commrec *cr, gmx_genborn_t *born, int gb_algorithm)
2079 gmx_domdec_t *dd=NULL;
2081 if(DOMAINDECOMP(cr))
2089 /* Single node or particle decomp (global==local), just copy pointers and return */
2090 if(gb_algorithm==egbSTILL)
2092 born->gpol = born->gpol_globalindex;
2093 born->vsolv = born->vsolv_globalindex;
2094 born->gb_radius = born->gb_radius_globalindex;
2098 born->param = born->param_globalindex;
2099 born->gb_radius = born->gb_radius_globalindex;
2102 born->use = born->use_globalindex;
2107 /* Reallocation of local arrays if necessary */
2108 /* fr->natoms_force is equal to dd->nat_tot */
2109 if (DOMAINDECOMP(cr) && dd->nat_tot > born->nalloc)
2113 nalloc = dd->nat_tot;
2115 /* Arrays specific to different gb algorithms */
2116 if (gb_algorithm == egbSTILL)
2118 srenew(born->gpol, nalloc+3);
2119 srenew(born->vsolv, nalloc+3);
2120 srenew(born->gb_radius, nalloc+3);
2121 for(i=born->nalloc; (i<nalloc+3); i++)
2125 born->gb_radius[i] = 0;
2130 srenew(born->param, nalloc+3);
2131 srenew(born->gb_radius, nalloc+3);
2132 for(i=born->nalloc; (i<nalloc+3); i++)
2135 born->gb_radius[i] = 0;
2139 /* All gb-algorithms use the array for vsites exclusions */
2140 srenew(born->use, nalloc+3);
2141 for(i=born->nalloc; (i<nalloc+3); i++)
2146 born->nalloc = nalloc;
2149 /* With dd, copy algorithm specific arrays */
2150 if(gb_algorithm==egbSTILL)
2152 for(i=at0;i<at1;i++)
2154 born->gpol[i] = born->gpol_globalindex[dd->gatindex[i]];
2155 born->vsolv[i] = born->vsolv_globalindex[dd->gatindex[i]];
2156 born->gb_radius[i] = born->gb_radius_globalindex[dd->gatindex[i]];
2157 born->use[i] = born->use_globalindex[dd->gatindex[i]];
2162 for(i=at0;i<at1;i++)
2164 born->param[i] = born->param_globalindex[dd->gatindex[i]];
2165 born->gb_radius[i] = born->gb_radius_globalindex[dd->gatindex[i]];
2166 born->use[i] = born->use_globalindex[dd->gatindex[i]];