2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2008, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
57 #include "gmx_fatal.h"
58 #include "mtop_util.h"
72 # include "genborn_sse2_double.h"
73 # include "genborn_allvsall_sse2_double.h"
75 # include "genborn_sse2_single.h"
76 # include "genborn_allvsall_sse2_single.h"
77 # endif /* GMX_DOUBLE */
78 #endif /* SSE or AVX present */
80 #include "genborn_allvsall.h"
82 /*#define DISABLE_SSE*/
91 typedef struct gbtmpnbls {
97 /* This function is exactly the same as the one in bondfree.c. The reason
98 * it is copied here is that the bonded gb-interactions are evaluated
99 * not in calc_bonds, but rather in calc_gb_forces
101 static int pbc_rvec_sub(const t_pbc *pbc,const rvec xi,const rvec xj,rvec dx)
104 return pbc_dx_aiuc(pbc,xi,xj,dx);
112 int init_gb_nblist(int natoms, t_nblist *nl)
114 nl->maxnri = natoms*4;
124 /*nl->nltype = nltype;*/
126 srenew(nl->iinr, nl->maxnri);
127 srenew(nl->gid, nl->maxnri);
128 srenew(nl->shift, nl->maxnri);
129 srenew(nl->jindex, nl->maxnri+1);
136 void gb_pd_send(t_commrec *cr, real *send_data, int nr)
140 int *index,*sendc,*disp;
142 snew(sendc,cr->nnodes);
143 snew(disp,cr->nnodes);
145 index = pd_index(cr);
148 /* Setup count/index arrays */
149 for(i=0;i<cr->nnodes;i++)
151 sendc[i] = index[i+1]-index[i];
155 /* Do communication */
156 MPI_Gatherv(send_data+index[cur],sendc[cur],GMX_MPI_REAL,send_data,sendc,
157 disp,GMX_MPI_REAL,0,cr->mpi_comm_mygroup);
158 MPI_Bcast(send_data,nr,GMX_MPI_REAL,0,cr->mpi_comm_mygroup);
164 int init_gb_plist(t_params *p_list)
167 p_list->param = NULL;
174 int init_gb_still(const t_commrec *cr, t_forcerec *fr,
175 const t_atomtypes *atype, t_idef *idef, t_atoms *atoms,
176 gmx_genborn_t *born,int natoms)
179 int i,j,i1,i2,k,m,nbond,nang,ia,ib,ic,id,nb,idx,idx2,at;
183 real r,ri,rj,ri2,ri3,rj2,r2,r3,r4,rk,ratio,term,h,doffset;
184 real p1,p2,p3,factor,cosine,rab,rbc;
191 snew(born->gpol_still_work,natoms+3);
197 pd_at_range(cr,&at0,&at1);
199 for(i=0;i<natoms;i++)
216 doffset = born->gb_doffset;
218 for(i=0;i<natoms;i++)
220 born->gpol_globalindex[i]=born->vsolv_globalindex[i]=
221 born->gb_radius_globalindex[i]=0;
224 /* Compute atomic solvation volumes for Still method */
225 for(i=0;i<natoms;i++)
227 ri=atype->gb_radius[atoms->atom[i].type];
228 born->gb_radius_globalindex[i] = ri;
230 born->vsolv_globalindex[i]=(4*M_PI/3)*r3;
233 for(j=0;j<idef->il[F_GB12].nr;j+=3)
235 m=idef->il[F_GB12].iatoms[j];
236 ia=idef->il[F_GB12].iatoms[j+1];
237 ib=idef->il[F_GB12].iatoms[j+2];
239 r=1.01*idef->iparams[m].gb.st;
241 ri = atype->gb_radius[atoms->atom[ia].type];
242 rj = atype->gb_radius[atoms->atom[ib].type];
248 ratio = (rj2-ri2-r*r)/(2*ri*r);
250 term = (M_PI/3.0)*h*h*(3.0*ri-h);
258 born->vsolv_globalindex[ia] -= term;
261 ratio = (ri2-rj2-r*r)/(2*rj*r);
263 term = (M_PI/3.0)*h*h*(3.0*rj-h);
271 born->vsolv_globalindex[ib] -= term;
277 gmx_sum(natoms,vsol,cr);
279 for(i=0;i<natoms;i++)
281 born->vsolv_globalindex[i]=born->vsolv_globalindex[i]-vsol[i];
285 /* Get the self-, 1-2 and 1-3 polarization energies for analytical Still
288 for(j=0;j<natoms;j++)
290 if(born->use_globalindex[j]==1)
292 born->gpol_globalindex[j]=-0.5*ONE_4PI_EPS0/
293 (atype->gb_radius[atoms->atom[j].type]-doffset+STILL_P1);
298 for(j=0;j<idef->il[F_GB12].nr;j+=3)
300 m=idef->il[F_GB12].iatoms[j];
301 ia=idef->il[F_GB12].iatoms[j+1];
302 ib=idef->il[F_GB12].iatoms[j+2];
304 r=idef->iparams[m].gb.st;
310 gp[ia]+=STILL_P2*born->vsolv_globalindex[ib]/r4;
311 gp[ib]+=STILL_P2*born->vsolv_globalindex[ia]/r4;
315 born->gpol_globalindex[ia]=born->gpol_globalindex[ia]+
316 STILL_P2*born->vsolv_globalindex[ib]/r4;
317 born->gpol_globalindex[ib]=born->gpol_globalindex[ib]+
318 STILL_P2*born->vsolv_globalindex[ia]/r4;
323 for(j=0;j<idef->il[F_GB13].nr;j+=3)
325 m=idef->il[F_GB13].iatoms[j];
326 ia=idef->il[F_GB13].iatoms[j+1];
327 ib=idef->il[F_GB13].iatoms[j+2];
329 r=idef->iparams[m].gb.st;
334 gp[ia]+=STILL_P3*born->vsolv[ib]/r4;
335 gp[ib]+=STILL_P3*born->vsolv[ia]/r4;
339 born->gpol_globalindex[ia]=born->gpol_globalindex[ia]+
340 STILL_P3*born->vsolv_globalindex[ib]/r4;
341 born->gpol_globalindex[ib]=born->gpol_globalindex[ib]+
342 STILL_P3*born->vsolv_globalindex[ia]/r4;
348 gmx_sum(natoms,gp,cr);
350 for(i=0;i<natoms;i++)
352 born->gpol_globalindex[i]=born->gpol_globalindex[i]+gp[i];
362 /* Initialize all GB datastructs and compute polarization energies */
363 int init_gb(gmx_genborn_t **p_born,
364 const t_commrec *cr, t_forcerec *fr, const t_inputrec *ir,
365 const gmx_mtop_t *mtop, real rgbradii, int gb_algorithm)
367 int i,j,m,ai,aj,jj,natoms,nalloc;
368 real rai,sk,p,doffset;
372 gmx_localtop_t *localtop;
374 natoms = mtop->natoms;
376 atoms = gmx_mtop_global_atoms(mtop);
377 localtop = gmx_mtop_generate_local_top(mtop,ir);
384 snew(born->drobc, natoms);
385 snew(born->bRad, natoms);
387 /* Allocate memory for the global data arrays */
388 snew(born->param_globalindex, natoms+3);
389 snew(born->gpol_globalindex, natoms+3);
390 snew(born->vsolv_globalindex, natoms+3);
391 snew(born->gb_radius_globalindex, natoms+3);
392 snew(born->use_globalindex, natoms+3);
394 snew(fr->invsqrta, natoms);
395 snew(fr->dvda, natoms);
398 fr->dadx_rawptr = NULL;
400 born->gpol_still_work = NULL;
401 born->gpol_hct_work = NULL;
403 /* snew(born->asurf,natoms); */
404 /* snew(born->dasurf,natoms); */
406 /* Initialize the gb neighbourlist */
407 init_gb_nblist(natoms,&(fr->gblist));
409 /* Do the Vsites exclusions (if any) */
410 for(i=0;i<natoms;i++)
412 jj = atoms.atom[i].type;
413 if (mtop->atomtypes.gb_radius[atoms.atom[i].type] > 0)
415 born->use_globalindex[i] = 1;
419 born->use_globalindex[i] = 0;
422 /* If we have a Vsite, put vs_globalindex[i]=0 */
423 if (C6 (fr->nbfp,fr->ntype,jj,jj) == 0 &&
424 C12(fr->nbfp,fr->ntype,jj,jj) == 0 &&
425 atoms.atom[i].q == 0)
427 born->use_globalindex[i]=0;
431 /* Copy algorithm parameters from inputrecord to local structure */
432 born->obc_alpha = ir->gb_obc_alpha;
433 born->obc_beta = ir->gb_obc_beta;
434 born->obc_gamma = ir->gb_obc_gamma;
435 born->gb_doffset = ir->gb_dielectric_offset;
436 born->gb_epsilon_solvent = ir->gb_epsilon_solvent;
437 born->epsilon_r = ir->epsilon_r;
439 doffset = born->gb_doffset;
441 /* Set the surface tension */
442 born->sa_surface_tension = ir->sa_surface_tension;
444 /* If Still model, initialise the polarisation energies */
445 if(gb_algorithm==egbSTILL)
447 init_gb_still(cr, fr,&(mtop->atomtypes), &(localtop->idef), &atoms,
452 /* If HCT/OBC, precalculate the sk*atype->S_hct factors */
453 else if(gb_algorithm==egbHCT || gb_algorithm==egbOBC)
456 snew(born->gpol_hct_work, natoms+3);
458 for(i=0;i<natoms;i++)
460 if(born->use_globalindex[i]==1)
462 rai = mtop->atomtypes.gb_radius[atoms.atom[i].type]-doffset;
463 sk = rai * mtop->atomtypes.S_hct[atoms.atom[i].type];
464 born->param_globalindex[i] = sk;
465 born->gb_radius_globalindex[i] = rai;
469 born->param_globalindex[i] = 0;
470 born->gb_radius_globalindex[i] = 0;
475 /* Allocate memory for work arrays for temporary use */
476 snew(born->work,natoms+4);
477 snew(born->count,natoms);
478 snew(born->nblist_work,natoms);
480 /* Domain decomposition specific stuff */
489 calc_gb_rad_still(t_commrec *cr, t_forcerec *fr,int natoms, gmx_localtop_t *top,
490 const t_atomtypes *atype, rvec x[], t_nblist *nl,
491 gmx_genborn_t *born,t_mdatoms *md)
493 int i,k,n,nj0,nj1,ai,aj,type;
496 real gpi,dr,dr2,dr4,idr4,rvdw,ratio,ccf,theta,term,rai,raj;
497 real ix1,iy1,iz1,jx1,jy1,jz1,dx11,dy11,dz11;
498 real rinv,idr2,idr6,vaj,dccf,cosq,sinq,prod,gpi2;
500 real vai, prod_ai, icf4,icf6;
502 factor = 0.5*ONE_4PI_EPS0;
505 for(i=0;i<born->nr;i++)
507 born->gpol_still_work[i]=0;
510 for(i=0;i<nl->nri;i++ )
515 nj1 = nl->jindex[i+1];
517 /* Load shifts for this list */
518 shift = nl->shift[i];
519 shX = fr->shift_vec[shift][0];
520 shY = fr->shift_vec[shift][1];
521 shZ = fr->shift_vec[shift][2];
525 rai = top->atomtypes.gb_radius[md->typeA[ai]];
526 vai = born->vsolv[ai];
527 prod_ai = STILL_P4*vai;
529 /* Load atom i coordinates, add shift vectors */
530 ix1 = shX + x[ai][0];
531 iy1 = shY + x[ai][1];
532 iz1 = shZ + x[ai][2];
545 dr2 = dx11*dx11+dy11*dy11+dz11*dz11;
546 rinv = gmx_invsqrt(dr2);
551 raj = top->atomtypes.gb_radius[md->typeA[aj]];
555 ratio = dr2 / (rvdw * rvdw);
556 vaj = born->vsolv[aj];
558 if(ratio>STILL_P5INV)
565 theta = ratio*STILL_PIP5;
567 term = 0.5*(1.0-cosq);
569 sinq = 1.0 - cosq*cosq;
570 dccf = 2.0*term*sinq*gmx_invsqrt(sinq)*theta;
575 icf6 = (4*ccf-dccf)*idr6;
577 born->gpol_still_work[aj] += prod_ai*icf4;
580 /* Save ai->aj and aj->ai chain rule terms */
581 fr->dadx[n++] = prod*icf6;
582 fr->dadx[n++] = prod_ai*icf6;
584 born->gpol_still_work[ai]+=gpi;
587 /* Parallel summations */
590 gmx_sum(natoms, born->gpol_still_work, cr);
592 else if(DOMAINDECOMP(cr))
594 dd_atom_sum_real(cr->dd, born->gpol_still_work);
597 /* Calculate the radii */
598 for(i=0;i<fr->natoms_force;i++) /* PELA born->nr */
600 if(born->use[i] != 0)
603 gpi = born->gpol[i]+born->gpol_still_work[i];
605 born->bRad[i] = factor*gmx_invsqrt(gpi2);
606 fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
610 /* Extra communication required for DD */
613 dd_atom_spread_real(cr->dd, born->bRad);
614 dd_atom_spread_real(cr->dd, fr->invsqrta);
623 calc_gb_rad_hct(t_commrec *cr,t_forcerec *fr,int natoms, gmx_localtop_t *top,
624 const t_atomtypes *atype, rvec x[], t_nblist *nl,
625 gmx_genborn_t *born,t_mdatoms *md)
627 int i,k,n,ai,aj,nj0,nj1,at0,at1;
630 real rai,raj,gpi,dr2,dr,sk,sk_ai,sk2,sk2_ai,lij,uij,diff2,tmp,sum_ai;
631 real rad,min_rad,rinv,rai_inv;
632 real ix1,iy1,iz1,jx1,jy1,jz1,dx11,dy11,dz11;
633 real lij2, uij2, lij3, uij3, t1,t2,t3;
634 real lij_inv,dlij,duij,sk2_rinv,prod,log_term;
635 real doffset,raj_inv,dadx_val;
638 doffset = born->gb_doffset;
639 gb_radius = born->gb_radius;
641 for(i=0;i<born->nr;i++)
643 born->gpol_hct_work[i] = 0;
646 /* Keep the compiler happy */
650 for(i=0;i<nl->nri;i++)
655 nj1 = nl->jindex[i+1];
657 /* Load shifts for this list */
658 shift = nl->shift[i];
659 shX = fr->shift_vec[shift][0];
660 shY = fr->shift_vec[shift][1];
661 shZ = fr->shift_vec[shift][2];
666 sk_ai = born->param[ai];
667 sk2_ai = sk_ai*sk_ai;
669 /* Load atom i coordinates, add shift vectors */
670 ix1 = shX + x[ai][0];
671 iy1 = shY + x[ai][1];
672 iz1 = shZ + x[ai][2];
688 dr2 = dx11*dx11+dy11*dy11+dz11*dz11;
689 rinv = gmx_invsqrt(dr2);
692 sk = born->param[aj];
695 /* aj -> ai interaction */
716 lij_inv = gmx_invsqrt(lij2);
719 prod = 0.25*sk2_rinv;
721 log_term = log(uij*lij_inv);
723 tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term +
728 tmp = tmp + 2.0 * (rai_inv-lij);
731 t1 = 0.5*lij2 + prod*lij3 - 0.25*(lij*rinv+lij3*dr);
732 t2 = -0.5*uij2 - 0.25*sk2_rinv*uij3 + 0.25*(uij*rinv+uij3*dr);
733 t3 = 0.125*(1.0+sk2_rinv*rinv)*(-diff2)+0.25*log_term*rinv*rinv;
735 dadx_val = (dlij*t1+t2+t3)*rinv; /* rb2 is moved to chainrule */
736 /* fr->dadx[n++] = (dlij*t1+duij*t2+t3)*rinv; */
737 /* rb2 is moved to chainrule */
745 fr->dadx[n++] = dadx_val;
748 /* ai -> aj interaction */
751 lij = 1.0/(dr-sk_ai);
764 uij = 1.0/(dr+sk_ai);
770 lij_inv = gmx_invsqrt(lij2);
771 sk2 = sk2_ai; /* sk2_ai = sk_ai * sk_ai in i loop above */
773 prod = 0.25 * sk2_rinv;
775 /* log_term = table_log(uij*lij_inv,born->log_table,
776 LOG_TABLE_ACCURACY); */
777 log_term = log(uij*lij_inv);
779 tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term +
784 tmp = tmp + 2.0 * (raj_inv-lij);
788 t1 = 0.5*lij2 + prod*lij3 - 0.25*(lij*rinv+lij3*dr);
789 t2 = -0.5*uij2 - 0.25*sk2_rinv*uij3 + 0.25*(uij*rinv+uij3*dr);
790 t3 = 0.125*(1.0+sk2_rinv*rinv)*(-diff2)+0.25*log_term*rinv*rinv;
792 dadx_val = (dlij*t1+t2+t3)*rinv; /* rb2 is moved to chainrule */
793 /* fr->dadx[n++] = (dlij*t1+duij*t2+t3)*rinv; */ /* rb2 is moved to chainrule */
795 born->gpol_hct_work[aj] += 0.5*tmp;
801 fr->dadx[n++] = dadx_val;
804 born->gpol_hct_work[ai] += sum_ai;
807 /* Parallel summations */
810 gmx_sum(natoms, born->gpol_hct_work, cr);
812 else if(DOMAINDECOMP(cr))
814 dd_atom_sum_real(cr->dd, born->gpol_hct_work);
817 for(i=0;i<fr->natoms_force;i++) /* PELA born->nr */
819 if(born->use[i] != 0)
821 rai = top->atomtypes.gb_radius[md->typeA[i]]-doffset;
822 sum_ai = 1.0/rai - born->gpol_hct_work[i];
823 min_rad = rai + doffset;
826 born->bRad[i] = rad > min_rad ? rad : min_rad;
827 fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
831 /* Extra communication required for DD */
834 dd_atom_spread_real(cr->dd, born->bRad);
835 dd_atom_spread_real(cr->dd, fr->invsqrta);
843 calc_gb_rad_obc(t_commrec *cr, t_forcerec *fr, int natoms, gmx_localtop_t *top,
844 const t_atomtypes *atype, rvec x[], t_nblist *nl, gmx_genborn_t *born,t_mdatoms *md)
846 int i,k,ai,aj,nj0,nj1,n,at0,at1;
849 real rai,raj,gpi,dr2,dr,sk,sk2,lij,uij,diff2,tmp,sum_ai;
850 real rad, min_rad,sum_ai2,sum_ai3,tsum,tchain,rinv,rai_inv,lij_inv,rai_inv2;
851 real log_term,prod,sk2_rinv,sk_ai,sk2_ai;
852 real ix1,iy1,iz1,jx1,jy1,jz1,dx11,dy11,dz11;
853 real lij2,uij2,lij3,uij3,dlij,duij,t1,t2,t3;
854 real doffset,raj_inv,dadx_val;
857 /* Keep the compiler happy */
862 doffset = born->gb_doffset;
863 gb_radius = born->gb_radius;
865 for(i=0;i<born->nr;i++)
867 born->gpol_hct_work[i] = 0;
870 for(i=0;i<nl->nri;i++)
875 nj1 = nl->jindex[i+1];
877 /* Load shifts for this list */
878 shift = nl->shift[i];
879 shX = fr->shift_vec[shift][0];
880 shY = fr->shift_vec[shift][1];
881 shZ = fr->shift_vec[shift][2];
886 sk_ai = born->param[ai];
887 sk2_ai = sk_ai*sk_ai;
889 /* Load atom i coordinates, add shift vectors */
890 ix1 = shX + x[ai][0];
891 iy1 = shY + x[ai][1];
892 iz1 = shZ + x[ai][2];
908 dr2 = dx11*dx11+dy11*dy11+dz11*dz11;
909 rinv = gmx_invsqrt(dr2);
912 /* sk is precalculated in init_gb() */
913 sk = born->param[aj];
916 /* aj -> ai interaction */
936 lij_inv = gmx_invsqrt(lij2);
939 prod = 0.25*sk2_rinv;
941 log_term = log(uij*lij_inv);
943 tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term + prod*(-diff2);
947 tmp = tmp + 2.0 * (rai_inv-lij);
951 t1 = 0.5*lij2 + prod*lij3 - 0.25*(lij*rinv+lij3*dr);
952 t2 = -0.5*uij2 - 0.25*sk2_rinv*uij3 + 0.25*(uij*rinv+uij3*dr);
953 t3 = 0.125*(1.0+sk2_rinv*rinv)*(-diff2)+0.25*log_term*rinv*rinv;
955 dadx_val = (dlij*t1+t2+t3)*rinv; /* rb2 is moved to chainrule */
963 fr->dadx[n++] = dadx_val;
965 /* ai -> aj interaction */
968 lij = 1.0/(dr-sk_ai);
981 uij = 1.0/(dr+sk_ai);
987 lij_inv = gmx_invsqrt(lij2);
988 sk2 = sk2_ai; /* sk2_ai = sk_ai * sk_ai in i loop above */
990 prod = 0.25 * sk2_rinv;
992 /* log_term = table_log(uij*lij_inv,born->log_table,LOG_TABLE_ACCURACY); */
993 log_term = log(uij*lij_inv);
995 tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term + prod*(-diff2);
999 tmp = tmp + 2.0 * (raj_inv-lij);
1002 t1 = 0.5*lij2 + prod*lij3 - 0.25*(lij*rinv+lij3*dr);
1003 t2 = -0.5*uij2 - 0.25*sk2_rinv*uij3 + 0.25*(uij*rinv+uij3*dr);
1004 t3 = 0.125*(1.0+sk2_rinv*rinv)*(-diff2)+0.25*log_term*rinv*rinv;
1006 dadx_val = (dlij*t1+t2+t3)*rinv; /* rb2 is moved to chainrule */
1008 born->gpol_hct_work[aj] += 0.5*tmp;
1015 fr->dadx[n++] = dadx_val;
1018 born->gpol_hct_work[ai] += sum_ai;
1022 /* Parallel summations */
1025 gmx_sum(natoms, born->gpol_hct_work, cr);
1027 else if(DOMAINDECOMP(cr))
1029 dd_atom_sum_real(cr->dd, born->gpol_hct_work);
1032 for(i=0;i<fr->natoms_force;i++) /* PELA born->nr */
1034 if(born->use[i] != 0)
1036 rai = top->atomtypes.gb_radius[md->typeA[i]];
1040 sum_ai = rai * born->gpol_hct_work[i];
1041 sum_ai2 = sum_ai * sum_ai;
1042 sum_ai3 = sum_ai2 * sum_ai;
1044 tsum = tanh(born->obc_alpha*sum_ai-born->obc_beta*sum_ai2+born->obc_gamma*sum_ai3);
1045 born->bRad[i] = rai_inv - tsum*rai_inv2;
1046 born->bRad[i] = 1.0 / born->bRad[i];
1048 fr->invsqrta[i] = gmx_invsqrt(born->bRad[i]);
1050 tchain = rai * (born->obc_alpha-2*born->obc_beta*sum_ai+3*born->obc_gamma*sum_ai2);
1051 born->drobc[i] = (1.0-tsum*tsum)*tchain*rai_inv2;
1055 /* Extra (local) communication required for DD */
1056 if(DOMAINDECOMP(cr))
1058 dd_atom_spread_real(cr->dd, born->bRad);
1059 dd_atom_spread_real(cr->dd, fr->invsqrta);
1060 dd_atom_spread_real(cr->dd, born->drobc);
1069 int calc_gb_rad(t_commrec *cr, t_forcerec *fr, t_inputrec *ir,gmx_localtop_t *top,
1070 const t_atomtypes *atype, rvec x[], t_nblist *nl, gmx_genborn_t *born,t_mdatoms *md,t_nrnb *nrnb)
1076 if(fr->bAllvsAll && fr->dadx==NULL)
1078 /* We might need up to 8 atoms of padding before and after,
1079 * and another 4 units to guarantee SSE alignment.
1081 fr->nalloc_dadx = 2*(md->homenr+12)*(md->nr/2+1+12);
1082 snew(fr->dadx_rawptr,fr->nalloc_dadx);
1083 fr->dadx = (real *) (((size_t) fr->dadx_rawptr + 16) & (~((size_t) 15)));
1087 /* In the SSE-enabled gb-loops, when writing to dadx, we
1088 * always write 2*4 elements at a time, even in the case with only
1089 * 1-3 j particles, where we only really need to write 2*(1-3)
1090 * elements. This is because we want dadx to be aligned to a 16-
1091 * byte boundary, and being able to use _mm_store/load_ps
1093 ndadx = 2 * (nl->nrj + 3*nl->nri);
1095 /* First, reallocate the dadx array, we need 3 extra for SSE */
1096 if (ndadx + 3 > fr->nalloc_dadx)
1098 fr->nalloc_dadx = over_alloc_large(ndadx) + 3;
1099 srenew(fr->dadx_rawptr,fr->nalloc_dadx);
1100 fr->dadx = (real *) (((size_t) fr->dadx_rawptr + 16) & (~((size_t) 15)));
1106 cnt = md->homenr*(md->nr/2+1);
1108 if(ir->gb_algorithm==egbSTILL)
1110 #if 0 && defined (GMX_X86_SSE2)
1111 if(fr->use_acceleration)
1114 genborn_allvsall_calc_still_radii_sse2_double(fr,md,born,top,x[0],cr,&fr->AllvsAll_workgb);
1116 genborn_allvsall_calc_still_radii_sse2_single(fr,md,born,top,x[0],cr,&fr->AllvsAll_workgb);
1121 genborn_allvsall_calc_still_radii(fr,md,born,top,x[0],cr,&fr->AllvsAll_workgb);
1124 genborn_allvsall_calc_still_radii(fr,md,born,top,x[0],cr,&fr->AllvsAll_workgb);
1126 /* 13 flops in outer loop, 47 flops in inner loop */
1127 inc_nrnb(nrnb,eNR_BORN_AVA_RADII_STILL,md->homenr*13+cnt*47);
1129 else if(ir->gb_algorithm==egbHCT || ir->gb_algorithm==egbOBC)
1131 #if 0 && defined (GMX_X86_SSE2)
1132 if(fr->use_acceleration)
1135 genborn_allvsall_calc_hct_obc_radii_sse2_double(fr,md,born,ir->gb_algorithm,top,x[0],cr,&fr->AllvsAll_workgb);
1137 genborn_allvsall_calc_hct_obc_radii_sse2_single(fr,md,born,ir->gb_algorithm,top,x[0],cr,&fr->AllvsAll_workgb);
1142 genborn_allvsall_calc_hct_obc_radii(fr,md,born,ir->gb_algorithm,top,x[0],cr,&fr->AllvsAll_workgb);
1145 genborn_allvsall_calc_hct_obc_radii(fr,md,born,ir->gb_algorithm,top,x[0],cr,&fr->AllvsAll_workgb);
1147 /* 24 flops in outer loop, 183 in inner */
1148 inc_nrnb(nrnb,eNR_BORN_AVA_RADII_HCT_OBC,md->homenr*24+cnt*183);
1152 gmx_fatal(FARGS,"Bad gb algorithm for all-vs-all interactions");
1157 /* Switch for determining which algorithm to use for Born radii calculation */
1160 #if 0 && defined (GMX_X86_SSE2)
1161 /* x86 or x86-64 with GCC inline assembly and/or SSE intrinsics */
1162 switch(ir->gb_algorithm)
1165 if(fr->use_acceleration)
1167 calc_gb_rad_still_sse2_double(cr,fr,born->nr,top, atype, x[0], nl, born);
1171 calc_gb_rad_still(cr,fr,born->nr,top,atype,x,nl,born,md);
1175 if(fr->use_acceleration)
1177 calc_gb_rad_hct_obc_sse2_double(cr,fr,born->nr,top, atype, x[0], nl, born, md, ir->gb_algorithm);
1181 calc_gb_rad_hct(cr,fr,born->nr,top,atype,x,nl,born,md);
1185 if(fr->use_acceleration)
1187 calc_gb_rad_hct_obc_sse2_double(cr,fr,born->nr,top, atype, x[0], nl, born, md, ir->gb_algorithm);
1191 calc_gb_rad_obc(cr,fr,born->nr,top,atype,x,nl,born,md);
1196 gmx_fatal(FARGS, "Unknown double precision sse-enabled algorithm for Born radii calculation: %d",ir->gb_algorithm);
1199 switch(ir->gb_algorithm)
1202 calc_gb_rad_still(cr,fr,born->nr,top,atype,x,nl,born,md);
1205 calc_gb_rad_hct(cr,fr,born->nr,top,atype,x,nl,born,md);
1208 calc_gb_rad_obc(cr,fr,born->nr,top,atype,x,nl,born,md);
1212 gmx_fatal(FARGS, "Unknown double precision algorithm for Born radii calculation: %d",ir->gb_algorithm);
1219 #if 0 && defined (GMX_X86_SSE2)
1220 /* x86 or x86-64 with GCC inline assembly and/or SSE intrinsics */
1221 switch(ir->gb_algorithm)
1224 if(fr->use_acceleration)
1226 calc_gb_rad_still_sse2_single(cr,fr,born->nr,top, atype, x[0], nl, born);
1230 calc_gb_rad_still(cr,fr,born->nr,top,atype,x,nl,born,md);
1234 if(fr->use_acceleration)
1236 calc_gb_rad_hct_obc_sse2_single(cr,fr,born->nr,top, atype, x[0], nl, born, md, ir->gb_algorithm);
1240 calc_gb_rad_hct(cr,fr,born->nr,top,atype,x,nl,born,md);
1245 if(fr->use_acceleration)
1247 calc_gb_rad_hct_obc_sse2_single(cr,fr,born->nr,top, atype, x[0], nl, born, md, ir->gb_algorithm);
1251 calc_gb_rad_obc(cr,fr,born->nr,top,atype,x,nl,born,md);
1256 gmx_fatal(FARGS, "Unknown sse-enabled algorithm for Born radii calculation: %d",ir->gb_algorithm);
1260 switch(ir->gb_algorithm)
1263 calc_gb_rad_still(cr,fr,born->nr,top,atype,x,nl,born,md);
1266 calc_gb_rad_hct(cr,fr,born->nr,top,atype,x,nl,born,md);
1269 calc_gb_rad_obc(cr,fr,born->nr,top,atype,x,nl,born,md);
1273 gmx_fatal(FARGS, "Unknown algorithm for Born radii calculation: %d",ir->gb_algorithm);
1276 #endif /* Single precision sse */
1278 #endif /* Double or single precision */
1280 if(fr->bAllvsAll==FALSE)
1282 switch(ir->gb_algorithm)
1285 /* 17 flops per outer loop iteration, 47 flops per inner loop */
1286 inc_nrnb(nrnb,eNR_BORN_RADII_STILL,nl->nri*17+nl->nrj*47);
1290 /* 61 (assuming 10 for tanh) flops for outer loop iteration, 183 flops per inner loop */
1291 inc_nrnb(nrnb,eNR_BORN_RADII_HCT_OBC,nl->nri*61+nl->nrj*183);
1304 real gb_bonds_tab(rvec x[], rvec f[], rvec fshift[], real *charge, real *p_gbtabscale,
1305 real *invsqrta, real *dvda, real *GBtab, t_idef *idef, real epsilon_r,
1306 real gb_epsilon_solvent, real facel, const t_pbc *pbc, const t_graph *graph)
1308 int i,j,n0,m,nnn,type,ai,aj;
1314 real isaprod,qq,gbscale,gbtabscale,Y,F,Geps,Heps2,Fp,VV,FF,rt,eps,eps2;
1315 real vgb,fgb,vcoul,fijC,dvdatmp,fscal,dvdaj;
1321 t_iatom *forceatoms;
1323 /* Scale the electrostatics by gb_epsilon_solvent */
1324 facel = facel * ((1.0/epsilon_r) - 1.0/gb_epsilon_solvent);
1326 gbtabscale=*p_gbtabscale;
1329 for(j=F_GB12;j<=F_GB14;j++)
1331 forceatoms = idef->il[j].iatoms;
1333 for(i=0;i<idef->il[j].nr; )
1335 /* To avoid reading in the interaction type, we just increment i to pass over
1336 * the types in the forceatoms array, this saves some memory accesses
1339 ai = forceatoms[i++];
1340 aj = forceatoms[i++];
1342 ki = pbc_rvec_sub(pbc,x[ai],x[aj],dx);
1343 rsq11 = iprod(dx,dx);
1345 isai = invsqrta[ai];
1346 iq = (-1)*facel*charge[ai];
1348 rinv11 = gmx_invsqrt(rsq11);
1349 isaj = invsqrta[aj];
1350 isaprod = isai*isaj;
1351 qq = isaprod*iq*charge[aj];
1352 gbscale = isaprod*gbtabscale;
1361 Geps = eps*GBtab[nnn+2];
1362 Heps2 = eps2*GBtab[nnn+3];
1365 FF = Fp+Geps+2.0*Heps2;
1367 fijC = qq*FF*gbscale;
1368 dvdatmp = -(vgb+fijC*r)*0.5;
1369 dvda[aj] = dvda[aj] + dvdatmp*isaj*isaj;
1370 dvda[ai] = dvda[ai] + dvdatmp*isai*isai;
1371 vctot = vctot + vgb;
1372 fgb = -(fijC)*rinv11;
1375 ivec_sub(SHIFT_IVEC(graph,ai),SHIFT_IVEC(graph,aj),dt);
1379 for (m=0; (m<DIM); m++) { /* 15 */
1383 fshift[ki][m]+=fscal;
1384 fshift[CENTRAL][m]-=fscal;
1392 real calc_gb_selfcorrections(t_commrec *cr, int natoms,
1393 real *charge, gmx_genborn_t *born, real *dvda, t_mdatoms *md, double facel)
1396 real rai,e,derb,q,q2,fi,rai_inv,vtot;
1400 pd_at_range(cr,&at0,&at1);
1402 else if(DOMAINDECOMP(cr))
1405 at1=cr->dd->nat_home;
1414 /* Scale the electrostatics by gb_epsilon_solvent */
1415 facel = facel * ((1.0/born->epsilon_r) - 1.0/born->gb_epsilon_solvent);
1419 /* Apply self corrections */
1420 for(i=at0;i<at1;i++)
1424 if(born->use[ai]==1)
1426 rai = born->bRad[ai];
1432 derb = 0.5*e*rai_inv*rai_inv;
1433 dvda[ai] += derb*rai;
1442 real calc_gb_nonpolar(t_commrec *cr, t_forcerec *fr,int natoms,gmx_genborn_t *born, gmx_localtop_t *top,
1443 const t_atomtypes *atype, real *dvda,int gb_algorithm, t_mdatoms *md)
1446 real e,es,rai,rbi,term,probe,tmp,factor;
1447 real rbi_inv,rbi_inv2;
1449 /* To keep the compiler happy */
1454 pd_at_range(cr,&at0,&at1);
1456 else if(DOMAINDECOMP(cr))
1459 at1 = cr->dd->nat_home;
1467 /* factor is the surface tension */
1468 factor = born->sa_surface_tension;
1471 // The surface tension factor is 0.0049 for Still model, 0.0054 for HCT/OBC
1472 if(gb_algorithm==egbSTILL)
1474 factor=0.0049*100*CAL2JOULE;
1478 factor=0.0054*100*CAL2JOULE;
1481 /* if(gb_algorithm==egbHCT || gb_algorithm==egbOBC) */
1487 for(i=at0;i<at1;i++)
1491 if(born->use[ai]==1)
1493 rai = top->atomtypes.gb_radius[md->typeA[ai]];
1494 rbi_inv = fr->invsqrta[ai];
1495 rbi_inv2 = rbi_inv * rbi_inv;
1496 tmp = (rai*rbi_inv2)*(rai*rbi_inv2);
1498 e = factor*term*(rai+probe)*(rai+probe)*tmp;
1499 dvda[ai] = dvda[ai] - 6*e*rbi_inv2;
1509 real calc_gb_chainrule(int natoms, t_nblist *nl, real *dadx, real *dvda, rvec x[], rvec t[], rvec fshift[],
1510 rvec shift_vec[], int gb_algorithm, gmx_genborn_t *born, t_mdatoms *md)
1512 int i,k,n,ai,aj,nj0,nj1,n0,n1;
1515 real fgb,fij,rb2,rbi,fix1,fiy1,fiz1;
1516 real ix1,iy1,iz1,jx1,jy1,jz1,dx11,dy11,dz11,rsq11;
1517 real rinv11,tx,ty,tz,rbai,rbaj,fgb_ai;
1527 if(gb_algorithm==egbSTILL)
1531 rbi = born->bRad[i];
1532 rb[i] = (2 * rbi * rbi * dvda[i])/ONE_4PI_EPS0;
1535 else if(gb_algorithm==egbHCT)
1539 rbi = born->bRad[i];
1540 rb[i] = rbi * rbi * dvda[i];
1543 else if(gb_algorithm==egbOBC)
1547 rbi = born->bRad[i];
1548 rb[i] = rbi * rbi * born->drobc[i] * dvda[i];
1552 for(i=0;i<nl->nri;i++)
1556 nj0 = nl->jindex[i];
1557 nj1 = nl->jindex[i+1];
1559 /* Load shifts for this list */
1560 shift = nl->shift[i];
1561 shX = shift_vec[shift][0];
1562 shY = shift_vec[shift][1];
1563 shZ = shift_vec[shift][2];
1565 /* Load atom i coordinates, add shift vectors */
1566 ix1 = shX + x[ai][0];
1567 iy1 = shY + x[ai][1];
1568 iz1 = shZ + x[ai][2];
1576 for(k=nj0;k<nj1;k++)
1590 fgb = rbai*dadx[n++];
1591 fgb_ai = rbaj*dadx[n++];
1593 /* Total force between ai and aj is the sum of ai->aj and aj->ai */
1604 /* Update force on atom aj */
1605 t[aj][0] = t[aj][0] - tx;
1606 t[aj][1] = t[aj][1] - ty;
1607 t[aj][2] = t[aj][2] - tz;
1610 /* Update force and shift forces on atom ai */
1611 t[ai][0] = t[ai][0] + fix1;
1612 t[ai][1] = t[ai][1] + fiy1;
1613 t[ai][2] = t[ai][2] + fiz1;
1615 fshift[shift][0] = fshift[shift][0] + fix1;
1616 fshift[shift][1] = fshift[shift][1] + fiy1;
1617 fshift[shift][2] = fshift[shift][2] + fiz1;
1626 calc_gb_forces(t_commrec *cr, t_mdatoms *md, gmx_genborn_t *born, gmx_localtop_t *top, const t_atomtypes *atype,
1627 rvec x[], rvec f[], t_forcerec *fr, t_idef *idef, int gb_algorithm, int sa_algorithm, t_nrnb *nrnb, gmx_bool bRad,
1628 const t_pbc *pbc, const t_graph *graph, gmx_enerdata_t *enerd)
1635 const t_pbc *pbc_null;
1642 if(sa_algorithm == esaAPPROX)
1644 /* Do a simple ACE type approximation for the non-polar solvation */
1645 enerd->term[F_NPSOLVATION] += calc_gb_nonpolar(cr, fr,born->nr, born, top, atype, fr->dvda, gb_algorithm,md);
1648 /* Calculate the bonded GB-interactions using either table or analytical formula */
1649 enerd->term[F_GBPOL] += gb_bonds_tab(x,f,fr->fshift, md->chargeA,&(fr->gbtabscale),
1650 fr->invsqrta,fr->dvda,fr->gbtab.data,idef,born->epsilon_r,born->gb_epsilon_solvent, fr->epsfac, pbc_null, graph);
1652 /* Calculate self corrections to the GB energies - currently only A state used! (FIXME) */
1653 enerd->term[F_GBPOL] += calc_gb_selfcorrections(cr,born->nr,md->chargeA, born, fr->dvda, md, fr->epsfac);
1655 /* If parallel, sum the derivative of the potential w.r.t the born radii */
1658 gmx_sum(md->nr,fr->dvda, cr);
1660 else if(DOMAINDECOMP(cr))
1662 dd_atom_sum_real(cr->dd,fr->dvda);
1663 dd_atom_spread_real(cr->dd,fr->dvda);
1668 #if 0 && defined (GMX_X86_SSE2)
1669 if(fr->use_acceleration)
1672 genborn_allvsall_calc_chainrule_sse2_double(fr,md,born,x[0],f[0],gb_algorithm,fr->AllvsAll_workgb);
1674 genborn_allvsall_calc_chainrule_sse2_single(fr,md,born,x[0],f[0],gb_algorithm,fr->AllvsAll_workgb);
1679 genborn_allvsall_calc_chainrule(fr,md,born,x[0],f[0],gb_algorithm,fr->AllvsAll_workgb);
1682 genborn_allvsall_calc_chainrule(fr,md,born,x[0],f[0],gb_algorithm,fr->AllvsAll_workgb);
1684 cnt = md->homenr*(md->nr/2+1);
1685 /* 9 flops for outer loop, 15 for inner */
1686 inc_nrnb(nrnb,eNR_BORN_AVA_CHAINRULE,md->homenr*9+cnt*15);
1690 #if 0 && defined (GMX_X86_SSE2)
1691 if(fr->use_acceleration)
1694 calc_gb_chainrule_sse2_double(fr->natoms_force, &(fr->gblist),fr->dadx,fr->dvda,x[0],
1695 f[0],fr->fshift[0],fr->shift_vec[0],gb_algorithm,born,md);
1697 calc_gb_chainrule_sse2_single(fr->natoms_force, &(fr->gblist),fr->dadx,fr->dvda,x[0],
1698 f[0],fr->fshift[0],fr->shift_vec[0],gb_algorithm,born,md);
1703 calc_gb_chainrule(fr->natoms_force, &(fr->gblist), fr->dadx, fr->dvda,
1704 x, f, fr->fshift, fr->shift_vec, gb_algorithm, born, md);
1707 calc_gb_chainrule(fr->natoms_force, &(fr->gblist), fr->dadx, fr->dvda,
1708 x, f, fr->fshift, fr->shift_vec, gb_algorithm, born, md);
1713 /* 9 flops for outer loop, 15 for inner */
1714 inc_nrnb(nrnb,eNR_BORN_CHAINRULE,fr->gblist.nri*9+fr->gblist.nrj*15);
1718 static void add_j_to_gblist(gbtmpnbl_t *list,int aj)
1720 if (list->naj >= list->aj_nalloc)
1722 list->aj_nalloc = over_alloc_large(list->naj+1);
1723 srenew(list->aj,list->aj_nalloc);
1726 list->aj[list->naj++] = aj;
1729 static gbtmpnbl_t *find_gbtmplist(struct gbtmpnbls *lists,int shift)
1733 /* Search the list with the same shift, if there is one */
1735 while (ind < lists->nlist && shift != lists->list[ind].shift)
1739 if (ind == lists->nlist)
1741 if (lists->nlist == lists->list_nalloc)
1743 lists->list_nalloc++;
1744 srenew(lists->list,lists->list_nalloc);
1745 for(i=lists->nlist; i<lists->list_nalloc; i++)
1747 lists->list[i].aj = NULL;
1748 lists->list[i].aj_nalloc = 0;
1753 lists->list[lists->nlist].shift = shift;
1754 lists->list[lists->nlist].naj = 0;
1758 return &lists->list[ind];
1761 static void add_bondeds_to_gblist(t_ilist *il,
1762 gmx_bool bMolPBC,t_pbc *pbc,t_graph *g,rvec *x,
1763 struct gbtmpnbls *nls)
1765 int ind,j,ai,aj,shift,found;
1771 for(ind=0; ind<il->nr; ind+=3)
1773 ai = il->iatoms[ind+1];
1774 aj = il->iatoms[ind+2];
1779 rvec_sub(x[ai],x[aj],dx);
1780 ivec_sub(SHIFT_IVEC(g,ai),SHIFT_IVEC(g,aj),dt);
1781 shift = IVEC2IS(dt);
1785 shift = pbc_dx_aiuc(pbc,x[ai],x[aj],dx);
1788 /* Find the list for this shift or create one */
1789 list = find_gbtmplist(&nls[ai],shift);
1793 /* So that we do not add the same bond twice.
1794 * This happens with some constraints between 1-3 atoms
1795 * that are in the bond-list but should not be in the GB nb-list */
1796 for(j=0;j<list->naj;j++)
1798 if (list->aj[j] == aj)
1808 gmx_incons("ai == aj");
1811 add_j_to_gblist(list,aj);
1817 compare_int (const void * a, const void * b)
1819 return ( *(int*)a - *(int*)b );
1824 int make_gb_nblist(t_commrec *cr, int gb_algorithm, real gbcut,
1825 rvec x[], matrix box,
1826 t_forcerec *fr, t_idef *idef, t_graph *graph, gmx_genborn_t *born)
1828 int i,l,ii,j,k,n,nj0,nj1,ai,aj,at0,at1,found,shift,s;
1833 struct gbtmpnbls *nls;
1834 gbtmpnbl_t *list =NULL;
1836 set_pbc(&pbc,fr->ePBC,box);
1837 nls = born->nblist_work;
1839 for(i=0;i<born->nr;i++)
1846 set_pbc_dd(&pbc,fr->ePBC,cr->dd,TRUE,box);
1849 switch (gb_algorithm)
1853 /* Loop over 1-2, 1-3 and 1-4 interactions */
1854 for(j=F_GB12;j<=F_GB14;j++)
1856 add_bondeds_to_gblist(&idef->il[j],fr->bMolPBC,&pbc,graph,x,nls);
1860 /* Loop over 1-4 interactions */
1861 add_bondeds_to_gblist(&idef->il[F_GB14],fr->bMolPBC,&pbc,graph,x,nls);
1864 gmx_incons("Unknown GB algorithm");
1867 /* Loop over the VDWQQ and VDW nblists to set up the nonbonded part of the GB list */
1868 for(n=0; (n<fr->nnblists); n++)
1870 for(i=0; (i<eNL_NR); i++)
1872 nblist=&(fr->nblists[n].nlist_sr[i]);
1874 if (nblist->nri > 0 && (i==eNL_VDWQQ || i==eNL_QQ))
1876 for(j=0;j<nblist->nri;j++)
1878 ai = nblist->iinr[j];
1879 shift = nblist->shift[j];
1881 /* Find the list for this shift or create one */
1882 list = find_gbtmplist(&nls[ai],shift);
1884 nj0 = nblist->jindex[j];
1885 nj1 = nblist->jindex[j+1];
1887 /* Add all the j-atoms in the non-bonded list to the GB list */
1888 for(k=nj0;k<nj1;k++)
1890 add_j_to_gblist(list,nblist->jjnr[k]);
1897 /* Zero out some counters */
1901 fr->gblist.jindex[0] = fr->gblist.nri;
1903 for(i=0;i<fr->natoms_force;i++)
1905 for(s=0; s<nls[i].nlist; s++)
1907 list = &nls[i].list[s];
1909 /* Only add those atoms that actually have neighbours */
1910 if (born->use[i] != 0)
1912 fr->gblist.iinr[fr->gblist.nri] = i;
1913 fr->gblist.shift[fr->gblist.nri] = list->shift;
1916 for(k=0; k<list->naj; k++)
1918 /* Memory allocation for jjnr */
1919 if(fr->gblist.nrj >= fr->gblist.maxnrj)
1921 fr->gblist.maxnrj += over_alloc_large(fr->gblist.maxnrj);
1925 fprintf(debug,"Increasing GB neighbourlist j size to %d\n",fr->gblist.maxnrj);
1928 srenew(fr->gblist.jjnr,fr->gblist.maxnrj);
1932 if(i == list->aj[k])
1934 gmx_incons("i == list->aj[k]");
1936 fr->gblist.jjnr[fr->gblist.nrj++] = list->aj[k];
1939 fr->gblist.jindex[fr->gblist.nri] = fr->gblist.nrj;
1946 for(i=0;i<fr->gblist.nri;i++)
1948 nj0 = fr->gblist.jindex[i];
1949 nj1 = fr->gblist.jindex[i+1];
1950 ai = fr->gblist.iinr[i];
1953 for(j=nj0;j<nj1;j++)
1955 if(fr->gblist.jjnr[j]<ai)
1956 fr->gblist.jjnr[j]+=fr->natoms_force;
1958 qsort(fr->gblist.jjnr+nj0,nj1-nj0,sizeof(int),compare_int);
1960 for(j=nj0;j<nj1;j++)
1962 if(fr->gblist.jjnr[j]>=fr->natoms_force)
1963 fr->gblist.jjnr[j]-=fr->natoms_force;
1972 void make_local_gb(const t_commrec *cr, gmx_genborn_t *born, int gb_algorithm)
1975 gmx_domdec_t *dd=NULL;
1977 if(DOMAINDECOMP(cr))
1985 /* Single node or particle decomp (global==local), just copy pointers and return */
1986 if(gb_algorithm==egbSTILL)
1988 born->gpol = born->gpol_globalindex;
1989 born->vsolv = born->vsolv_globalindex;
1990 born->gb_radius = born->gb_radius_globalindex;
1994 born->param = born->param_globalindex;
1995 born->gb_radius = born->gb_radius_globalindex;
1998 born->use = born->use_globalindex;
2003 /* Reallocation of local arrays if necessary */
2004 /* fr->natoms_force is equal to dd->nat_tot */
2005 if (DOMAINDECOMP(cr) && dd->nat_tot > born->nalloc)
2009 nalloc = dd->nat_tot;
2011 /* Arrays specific to different gb algorithms */
2012 if (gb_algorithm == egbSTILL)
2014 srenew(born->gpol, nalloc+3);
2015 srenew(born->vsolv, nalloc+3);
2016 srenew(born->gb_radius, nalloc+3);
2017 for(i=born->nalloc; (i<nalloc+3); i++)
2021 born->gb_radius[i] = 0;
2026 srenew(born->param, nalloc+3);
2027 srenew(born->gb_radius, nalloc+3);
2028 for(i=born->nalloc; (i<nalloc+3); i++)
2031 born->gb_radius[i] = 0;
2035 /* All gb-algorithms use the array for vsites exclusions */
2036 srenew(born->use, nalloc+3);
2037 for(i=born->nalloc; (i<nalloc+3); i++)
2042 born->nalloc = nalloc;
2045 /* With dd, copy algorithm specific arrays */
2046 if(gb_algorithm==egbSTILL)
2048 for(i=at0;i<at1;i++)
2050 born->gpol[i] = born->gpol_globalindex[dd->gatindex[i]];
2051 born->vsolv[i] = born->vsolv_globalindex[dd->gatindex[i]];
2052 born->gb_radius[i] = born->gb_radius_globalindex[dd->gatindex[i]];
2053 born->use[i] = born->use_globalindex[dd->gatindex[i]];
2058 for(i=at0;i<at1;i++)
2060 born->param[i] = born->param_globalindex[dd->gatindex[i]];
2061 born->gb_radius[i] = born->gb_radius_globalindex[dd->gatindex[i]];
2062 born->use[i] = born->use_globalindex[dd->gatindex[i]];