Prepared t_mdatoms for using vector
[gromacs.git] / src / gromacs / mdlib / genborn.cpp
blob7d9cc0f617658a47b0d6d882355f94c056d367a1
1 /*
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 * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
38 #include "gmxpre.h"
40 #include "genborn.h"
42 #include <string.h>
44 #include <cmath>
46 #include <algorithm>
48 #include "gromacs/domdec/domdec.h"
49 #include "gromacs/domdec/domdec_struct.h"
50 #include "gromacs/fileio/pdbio.h"
51 #include "gromacs/gmxlib/network.h"
52 #include "gromacs/gmxlib/nrnb.h"
53 #include "gromacs/math/functions.h"
54 #include "gromacs/math/units.h"
55 #include "gromacs/math/vec.h"
56 #include "gromacs/mdlib/genborn_allvsall.h"
57 #include "gromacs/mdtypes/commrec.h"
58 #include "gromacs/mdtypes/inputrec.h"
59 #include "gromacs/mdtypes/md_enums.h"
60 #include "gromacs/mdtypes/nblist.h"
61 #include "gromacs/pbcutil/ishift.h"
62 #include "gromacs/pbcutil/mshift.h"
63 #include "gromacs/pbcutil/pbc.h"
64 #include "gromacs/topology/mtop_util.h"
65 #include "gromacs/utility/fatalerror.h"
66 #include "gromacs/utility/gmxmpi.h"
67 #include "gromacs/utility/smalloc.h"
70 typedef struct {
71 int shift;
72 int naj;
73 int *aj;
74 int aj_nalloc;
75 } gbtmpnbl_t;
77 typedef struct gbtmpnbls {
78 int nlist;
79 gbtmpnbl_t *list;
80 int list_nalloc;
81 } t_gbtmpnbls;
83 /* This function is exactly the same as the one in listed-forces/bonded.cpp. The reason
84 * it is copied here is that the bonded gb-interactions are evaluated
85 * not in calc_bonds, but rather in calc_gb_forces
87 static int pbc_rvec_sub(const t_pbc *pbc, const rvec xi, const rvec xj, rvec dx)
89 if (pbc)
91 return pbc_dx_aiuc(pbc, xi, xj, dx);
93 else
95 rvec_sub(xi, xj, dx);
96 return CENTRAL;
100 static int init_gb_nblist(int natoms, t_nblist *nl)
102 nl->maxnri = natoms*4;
103 nl->maxnrj = 0;
104 nl->nri = 0;
105 nl->nrj = 0;
106 nl->iinr = nullptr;
107 nl->gid = nullptr;
108 nl->shift = nullptr;
109 nl->jindex = nullptr;
110 nl->jjnr = nullptr;
111 /*nl->nltype = nltype;*/
113 srenew(nl->iinr, nl->maxnri);
114 srenew(nl->gid, nl->maxnri);
115 srenew(nl->shift, nl->maxnri);
116 srenew(nl->jindex, nl->maxnri+1);
118 nl->jindex[0] = 0;
120 return 0;
124 static int init_gb_still(const t_atomtypes *atype, t_idef *idef, t_atoms *atoms,
125 gmx_genborn_t *born, int natoms)
128 int i, j, m, ia, ib;
129 real r, ri, rj, ri2, rj2, r3, r4, ratio, term, h, doffset;
131 real *vsol;
132 real *gp;
134 snew(vsol, natoms);
135 snew(gp, natoms);
136 snew(born->gpol_still_work, natoms+3);
138 doffset = born->gb_doffset;
140 for (i = 0; i < natoms; i++)
142 born->gpol_globalindex[i] = born->vsolv_globalindex[i] =
143 born->gb_radius_globalindex[i] = 0;
146 /* Compute atomic solvation volumes for Still method */
147 for (i = 0; i < natoms; i++)
149 ri = atype->gb_radius[atoms->atom[i].type];
150 born->gb_radius_globalindex[i] = ri;
151 r3 = ri*ri*ri;
152 born->vsolv_globalindex[i] = (4*M_PI/3)*r3;
155 for (j = 0; j < idef->il[F_GB12].nr; j += 3)
157 m = idef->il[F_GB12].iatoms[j];
158 ia = idef->il[F_GB12].iatoms[j+1];
159 ib = idef->il[F_GB12].iatoms[j+2];
161 r = 1.01*idef->iparams[m].gb.st;
163 ri = atype->gb_radius[atoms->atom[ia].type];
164 rj = atype->gb_radius[atoms->atom[ib].type];
166 ri2 = ri*ri;
167 rj2 = rj*rj;
169 ratio = (rj2-ri2-r*r)/(2*ri*r);
170 h = ri*(1+ratio);
171 term = (M_PI/3.0)*h*h*(3.0*ri-h);
173 born->vsolv_globalindex[ia] -= term;
175 ratio = (ri2-rj2-r*r)/(2*rj*r);
176 h = rj*(1+ratio);
177 term = (M_PI/3.0)*h*h*(3.0*rj-h);
179 born->vsolv_globalindex[ib] -= term;
182 /* Get the self-, 1-2 and 1-3 polarization energies for analytical Still
183 method */
184 /* Self */
185 for (j = 0; j < natoms; j++)
187 if (born->use_globalindex[j] == 1)
189 born->gpol_globalindex[j] = -0.5*ONE_4PI_EPS0/
190 (atype->gb_radius[atoms->atom[j].type]-doffset+STILL_P1);
194 /* 1-2 */
195 for (j = 0; j < idef->il[F_GB12].nr; j += 3)
197 m = idef->il[F_GB12].iatoms[j];
198 ia = idef->il[F_GB12].iatoms[j+1];
199 ib = idef->il[F_GB12].iatoms[j+2];
201 r = idef->iparams[m].gb.st;
203 r4 = r*r*r*r;
205 born->gpol_globalindex[ia] = born->gpol_globalindex[ia]+
206 STILL_P2*born->vsolv_globalindex[ib]/r4;
207 born->gpol_globalindex[ib] = born->gpol_globalindex[ib]+
208 STILL_P2*born->vsolv_globalindex[ia]/r4;
211 /* 1-3 */
212 for (j = 0; j < idef->il[F_GB13].nr; j += 3)
214 m = idef->il[F_GB13].iatoms[j];
215 ia = idef->il[F_GB13].iatoms[j+1];
216 ib = idef->il[F_GB13].iatoms[j+2];
218 r = idef->iparams[m].gb.st;
219 r4 = r*r*r*r;
221 born->gpol_globalindex[ia] = born->gpol_globalindex[ia]+
222 STILL_P3*born->vsolv_globalindex[ib]/r4;
223 born->gpol_globalindex[ib] = born->gpol_globalindex[ib]+
224 STILL_P3*born->vsolv_globalindex[ia]/r4;
227 sfree(vsol);
228 sfree(gp);
230 return 0;
233 /* Initialize all GB datastructs and compute polarization energies */
234 int init_gb(gmx_genborn_t **p_born,
235 t_forcerec *fr, const t_inputrec *ir,
236 const gmx_mtop_t *mtop, int gb_algorithm)
238 int i, jj, natoms;
239 real rai, sk, doffset;
241 t_atoms atoms;
242 gmx_genborn_t *born;
243 gmx_localtop_t *localtop;
245 natoms = mtop->natoms;
247 atoms = gmx_mtop_global_atoms(mtop);
248 localtop = gmx_mtop_generate_local_top(mtop, ir->efep != efepNO);
250 snew(born, 1);
251 *p_born = born;
253 born->nr = natoms;
255 snew(born->drobc, natoms);
256 snew(born->bRad, natoms);
258 /* Allocate memory for the global data arrays */
259 snew(born->param_globalindex, natoms+3);
260 snew(born->gpol_globalindex, natoms+3);
261 snew(born->vsolv_globalindex, natoms+3);
262 snew(born->gb_radius_globalindex, natoms+3);
263 snew(born->use_globalindex, natoms+3);
265 snew(fr->invsqrta, natoms);
266 snew(fr->dvda, natoms);
268 fr->dadx = nullptr;
269 fr->dadx_rawptr = nullptr;
270 fr->nalloc_dadx = 0;
271 born->gpol_still_work = nullptr;
272 born->gpol_hct_work = nullptr;
274 /* snew(born->asurf,natoms); */
275 /* snew(born->dasurf,natoms); */
277 /* Initialize the gb neighbourlist */
278 snew(fr->gblist, 1);
279 init_gb_nblist(natoms, fr->gblist);
281 /* Do the Vsites exclusions (if any) */
282 for (i = 0; i < natoms; i++)
284 jj = atoms.atom[i].type;
285 if (mtop->atomtypes.gb_radius[atoms.atom[i].type] > 0)
287 born->use_globalindex[i] = 1;
289 else
291 born->use_globalindex[i] = 0;
294 /* If we have a Vsite, put vs_globalindex[i]=0 */
295 if (C6 (fr->nbfp, fr->ntype, jj, jj) == 0 &&
296 C12(fr->nbfp, fr->ntype, jj, jj) == 0 &&
297 atoms.atom[i].q == 0)
299 born->use_globalindex[i] = 0;
303 /* Copy algorithm parameters from inputrecord to local structure */
304 born->obc_alpha = ir->gb_obc_alpha;
305 born->obc_beta = ir->gb_obc_beta;
306 born->obc_gamma = ir->gb_obc_gamma;
307 born->gb_doffset = ir->gb_dielectric_offset;
308 born->gb_epsilon_solvent = ir->gb_epsilon_solvent;
309 born->epsilon_r = ir->epsilon_r;
311 doffset = born->gb_doffset;
313 /* Set the surface tension */
314 born->sa_surface_tension = ir->sa_surface_tension;
316 /* If Still model, initialise the polarisation energies */
317 if (gb_algorithm == egbSTILL)
319 init_gb_still(&(mtop->atomtypes), &(localtop->idef), &atoms,
320 born, natoms);
324 /* If HCT/OBC, precalculate the sk*atype->S_hct factors */
325 else if (gb_algorithm == egbHCT || gb_algorithm == egbOBC)
328 snew(born->gpol_hct_work, natoms+3);
330 for (i = 0; i < natoms; i++)
332 if (born->use_globalindex[i] == 1)
334 rai = mtop->atomtypes.gb_radius[atoms.atom[i].type]-doffset;
335 sk = rai * mtop->atomtypes.S_hct[atoms.atom[i].type];
336 born->param_globalindex[i] = sk;
337 born->gb_radius_globalindex[i] = rai;
339 else
341 born->param_globalindex[i] = 0;
342 born->gb_radius_globalindex[i] = 0;
347 /* Allocate memory for work arrays for temporary use */
348 snew(born->work, natoms+4);
349 snew(born->count, natoms);
350 snew(born->nblist_work, natoms);
352 /* Domain decomposition specific stuff */
353 born->nalloc = 0;
355 return 0;
360 static int
361 calc_gb_rad_still(t_commrec *cr, t_forcerec *fr, gmx_localtop_t *top,
362 rvec x[], t_nblist *nl,
363 gmx_genborn_t *born, t_mdatoms *md)
365 int i, k, n, nj0, nj1, ai, aj;
366 int shift;
367 real shX, shY, shZ;
368 real gpi, dr2, idr4, rvdw, ratio, ccf, theta, term, rai, raj;
369 real ix1, iy1, iz1, jx1, jy1, jz1, dx11, dy11, dz11;
370 real rinv, idr2, idr6, vaj, dccf, cosq, sinq, prod, gpi2;
371 real factor;
372 real vai, prod_ai, icf4, icf6;
374 factor = 0.5*ONE_4PI_EPS0;
375 n = 0;
377 for (i = 0; i < born->nr; i++)
379 born->gpol_still_work[i] = 0;
382 for (i = 0; i < nl->nri; i++)
384 ai = nl->iinr[i];
386 nj0 = nl->jindex[i];
387 nj1 = nl->jindex[i+1];
389 /* Load shifts for this list */
390 shift = nl->shift[i];
391 shX = fr->shift_vec[shift][0];
392 shY = fr->shift_vec[shift][1];
393 shZ = fr->shift_vec[shift][2];
395 gpi = 0;
397 rai = top->atomtypes.gb_radius[md->typeA[ai]];
398 vai = born->vsolv[ai];
399 prod_ai = STILL_P4*vai;
401 /* Load atom i coordinates, add shift vectors */
402 ix1 = shX + x[ai][0];
403 iy1 = shY + x[ai][1];
404 iz1 = shZ + x[ai][2];
406 for (k = nj0; k < nj1 && nl->jjnr[k] >= 0; k++)
408 aj = nl->jjnr[k];
409 jx1 = x[aj][0];
410 jy1 = x[aj][1];
411 jz1 = x[aj][2];
413 dx11 = ix1-jx1;
414 dy11 = iy1-jy1;
415 dz11 = iz1-jz1;
417 dr2 = dx11*dx11+dy11*dy11+dz11*dz11;
418 rinv = gmx::invsqrt(dr2);
419 idr2 = rinv*rinv;
420 idr4 = idr2*idr2;
421 idr6 = idr4*idr2;
423 raj = top->atomtypes.gb_radius[md->typeA[aj]];
425 rvdw = rai + raj;
427 ratio = dr2 / (rvdw * rvdw);
428 vaj = born->vsolv[aj];
430 if (ratio > STILL_P5INV)
432 ccf = 1.0;
433 dccf = 0.0;
435 else
437 theta = ratio*STILL_PIP5;
438 cosq = cos(theta);
439 term = 0.5*(1.0-cosq);
440 ccf = term*term;
441 sinq = 1.0 - cosq*cosq;
442 dccf = 2.0*term*sinq*gmx::invsqrt(sinq)*theta;
445 prod = STILL_P4*vaj;
446 icf4 = ccf*idr4;
447 icf6 = (4*ccf-dccf)*idr6;
448 born->gpol_still_work[aj] += prod_ai*icf4;
449 gpi = gpi+prod*icf4;
451 /* Save ai->aj and aj->ai chain rule terms */
452 fr->dadx[n++] = prod*icf6;
453 fr->dadx[n++] = prod_ai*icf6;
455 born->gpol_still_work[ai] += gpi;
458 /* Parallel summations */
459 if (DOMAINDECOMP(cr))
461 dd_atom_sum_real(cr->dd, born->gpol_still_work);
464 /* Calculate the radii */
465 for (i = 0; i < fr->natoms_force; i++) /* PELA born->nr */
467 if (born->use[i] != 0)
469 gpi = born->gpol[i]+born->gpol_still_work[i];
470 gpi2 = gpi * gpi;
471 born->bRad[i] = factor*gmx::invsqrt(gpi2);
472 fr->invsqrta[i] = gmx::invsqrt(born->bRad[i]);
476 /* Extra communication required for DD */
477 if (DOMAINDECOMP(cr))
479 dd_atom_spread_real(cr->dd, born->bRad);
480 dd_atom_spread_real(cr->dd, fr->invsqrta);
483 return 0;
488 static int
489 calc_gb_rad_hct(t_commrec *cr, t_forcerec *fr, gmx_localtop_t *top,
490 rvec x[], t_nblist *nl,
491 gmx_genborn_t *born, t_mdatoms *md)
493 int i, k, n, ai, aj, nj0, nj1;
494 int shift;
495 real shX, shY, shZ;
496 real rai, raj, dr2, dr, sk, sk_ai, sk2, sk2_ai, lij, uij, diff2, tmp, sum_ai;
497 real rad, min_rad, rinv, rai_inv;
498 real ix1, iy1, iz1, jx1, jy1, jz1, dx11, dy11, dz11;
499 real lij2, uij2, lij3, uij3, t1, t2, t3;
500 real lij_inv, dlij, sk2_rinv, prod, log_term;
501 real doffset, raj_inv, dadx_val;
502 real *gb_radius;
504 doffset = born->gb_doffset;
505 gb_radius = born->gb_radius;
507 for (i = 0; i < born->nr; i++)
509 born->gpol_hct_work[i] = 0;
512 /* Keep the compiler happy */
513 n = 0;
515 for (i = 0; i < nl->nri; i++)
517 ai = nl->iinr[i];
519 nj0 = nl->jindex[i];
520 nj1 = nl->jindex[i+1];
522 /* Load shifts for this list */
523 shift = nl->shift[i];
524 shX = fr->shift_vec[shift][0];
525 shY = fr->shift_vec[shift][1];
526 shZ = fr->shift_vec[shift][2];
528 rai = gb_radius[ai];
529 rai_inv = 1.0/rai;
531 sk_ai = born->param[ai];
532 sk2_ai = sk_ai*sk_ai;
534 /* Load atom i coordinates, add shift vectors */
535 ix1 = shX + x[ai][0];
536 iy1 = shY + x[ai][1];
537 iz1 = shZ + x[ai][2];
539 sum_ai = 0;
541 for (k = nj0; k < nj1 && nl->jjnr[k] >= 0; k++)
543 aj = nl->jjnr[k];
545 jx1 = x[aj][0];
546 jy1 = x[aj][1];
547 jz1 = x[aj][2];
549 dx11 = ix1 - jx1;
550 dy11 = iy1 - jy1;
551 dz11 = iz1 - jz1;
553 dr2 = dx11*dx11+dy11*dy11+dz11*dz11;
554 rinv = gmx::invsqrt(dr2);
555 dr = rinv*dr2;
557 sk = born->param[aj];
558 raj = gb_radius[aj];
560 /* aj -> ai interaction */
561 if (rai < dr+sk)
563 lij = 1.0/(dr-sk);
564 dlij = 1.0;
566 if (rai > dr-sk)
568 lij = rai_inv;
569 dlij = 0.0;
572 lij2 = lij*lij;
573 lij3 = lij2*lij;
575 uij = 1.0/(dr+sk);
576 uij2 = uij*uij;
577 uij3 = uij2*uij;
579 diff2 = uij2-lij2;
581 lij_inv = gmx::invsqrt(lij2);
582 sk2 = sk*sk;
583 sk2_rinv = sk2*rinv;
584 prod = 0.25*sk2_rinv;
586 log_term = std::log(uij*lij_inv);
588 tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term +
589 prod*(-diff2);
591 if (rai < sk-dr)
593 tmp = tmp + 2.0 * (rai_inv-lij);
596 t1 = 0.5*lij2 + prod*lij3 - 0.25*(lij*rinv+lij3*dr);
597 t2 = -0.5*uij2 - 0.25*sk2_rinv*uij3 + 0.25*(uij*rinv+uij3*dr);
598 t3 = 0.125*(1.0+sk2_rinv*rinv)*(-diff2)+0.25*log_term*rinv*rinv;
600 dadx_val = (dlij*t1+t2+t3)*rinv; /* rb2 is moved to chainrule */
601 /* fr->dadx[n++] = (dlij*t1+duij*t2+t3)*rinv; */
602 /* rb2 is moved to chainrule */
604 sum_ai += 0.5*tmp;
606 else
608 dadx_val = 0.0;
610 fr->dadx[n++] = dadx_val;
613 /* ai -> aj interaction */
614 if (raj < dr + sk_ai)
616 lij = 1.0/(dr-sk_ai);
617 dlij = 1.0;
618 raj_inv = 1.0/raj;
620 if (raj > dr-sk_ai)
622 lij = raj_inv;
623 dlij = 0.0;
626 lij2 = lij * lij;
627 lij3 = lij2 * lij;
629 uij = 1.0/(dr+sk_ai);
630 uij2 = uij * uij;
631 uij3 = uij2 * uij;
633 diff2 = uij2-lij2;
635 lij_inv = gmx::invsqrt(lij2);
636 sk2 = sk2_ai; /* sk2_ai = sk_ai * sk_ai in i loop above */
637 sk2_rinv = sk2*rinv;
638 prod = 0.25 * sk2_rinv;
640 /* log_term = table_log(uij*lij_inv,born->log_table,
641 LOG_TABLE_ACCURACY); */
642 log_term = std::log(uij*lij_inv);
644 tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term +
645 prod*(-diff2);
647 if (raj < sk_ai-dr)
649 tmp = tmp + 2.0 * (raj_inv-lij);
652 /* duij = 1.0 */
653 t1 = 0.5*lij2 + prod*lij3 - 0.25*(lij*rinv+lij3*dr);
654 t2 = -0.5*uij2 - 0.25*sk2_rinv*uij3 + 0.25*(uij*rinv+uij3*dr);
655 t3 = 0.125*(1.0+sk2_rinv*rinv)*(-diff2)+0.25*log_term*rinv*rinv;
657 dadx_val = (dlij*t1+t2+t3)*rinv; /* rb2 is moved to chainrule */
658 /* fr->dadx[n++] = (dlij*t1+duij*t2+t3)*rinv; */ /* rb2 is moved to chainrule */
660 born->gpol_hct_work[aj] += 0.5*tmp;
662 else
664 dadx_val = 0.0;
666 fr->dadx[n++] = dadx_val;
669 born->gpol_hct_work[ai] += sum_ai;
672 /* Parallel summations */
673 if (DOMAINDECOMP(cr))
675 dd_atom_sum_real(cr->dd, born->gpol_hct_work);
678 for (i = 0; i < fr->natoms_force; i++) /* PELA born->nr */
680 if (born->use[i] != 0)
682 rai = top->atomtypes.gb_radius[md->typeA[i]]-doffset;
683 sum_ai = 1.0/rai - born->gpol_hct_work[i];
684 min_rad = rai + doffset;
685 rad = 1.0/sum_ai;
687 born->bRad[i] = std::max(rad, min_rad);
688 fr->invsqrta[i] = gmx::invsqrt(born->bRad[i]);
692 /* Extra communication required for DD */
693 if (DOMAINDECOMP(cr))
695 dd_atom_spread_real(cr->dd, born->bRad);
696 dd_atom_spread_real(cr->dd, fr->invsqrta);
700 return 0;
703 static int
704 calc_gb_rad_obc(t_commrec *cr, t_forcerec *fr, gmx_localtop_t *top,
705 rvec x[], t_nblist *nl, gmx_genborn_t *born, t_mdatoms *md)
707 int i, k, ai, aj, nj0, nj1, n;
708 int shift;
709 real shX, shY, shZ;
710 real rai, raj, dr2, dr, sk, sk2, lij, uij, diff2, tmp, sum_ai;
711 real sum_ai2, sum_ai3, tsum, tchain, rinv, rai_inv, lij_inv, rai_inv2;
712 real log_term, prod, sk2_rinv, sk_ai, sk2_ai;
713 real ix1, iy1, iz1, jx1, jy1, jz1, dx11, dy11, dz11;
714 real lij2, uij2, lij3, uij3, dlij, t1, t2, t3;
715 real doffset, raj_inv, dadx_val;
716 real *gb_radius;
718 /* Keep the compiler happy */
719 n = 0;
721 doffset = born->gb_doffset;
722 gb_radius = born->gb_radius;
724 for (i = 0; i < born->nr; i++)
726 born->gpol_hct_work[i] = 0;
729 for (i = 0; i < nl->nri; i++)
731 ai = nl->iinr[i];
733 nj0 = nl->jindex[i];
734 nj1 = nl->jindex[i+1];
736 /* Load shifts for this list */
737 shift = nl->shift[i];
738 shX = fr->shift_vec[shift][0];
739 shY = fr->shift_vec[shift][1];
740 shZ = fr->shift_vec[shift][2];
742 rai = gb_radius[ai];
743 rai_inv = 1.0/rai;
745 sk_ai = born->param[ai];
746 sk2_ai = sk_ai*sk_ai;
748 /* Load atom i coordinates, add shift vectors */
749 ix1 = shX + x[ai][0];
750 iy1 = shY + x[ai][1];
751 iz1 = shZ + x[ai][2];
753 sum_ai = 0;
755 for (k = nj0; k < nj1 && nl->jjnr[k] >= 0; k++)
757 aj = nl->jjnr[k];
759 jx1 = x[aj][0];
760 jy1 = x[aj][1];
761 jz1 = x[aj][2];
763 dx11 = ix1 - jx1;
764 dy11 = iy1 - jy1;
765 dz11 = iz1 - jz1;
767 dr2 = dx11*dx11+dy11*dy11+dz11*dz11;
768 rinv = gmx::invsqrt(dr2);
769 dr = dr2*rinv;
771 /* sk is precalculated in init_gb() */
772 sk = born->param[aj];
773 raj = gb_radius[aj];
775 /* aj -> ai interaction */
776 if (rai < dr+sk)
778 lij = 1.0/(dr-sk);
779 dlij = 1.0;
781 if (rai > dr-sk)
783 lij = rai_inv;
784 dlij = 0.0;
787 uij = 1.0/(dr+sk);
788 lij2 = lij * lij;
789 lij3 = lij2 * lij;
790 uij2 = uij * uij;
791 uij3 = uij2 * uij;
793 diff2 = uij2-lij2;
795 lij_inv = gmx::invsqrt(lij2);
796 sk2 = sk*sk;
797 sk2_rinv = sk2*rinv;
798 prod = 0.25*sk2_rinv;
800 log_term = std::log(uij*lij_inv);
802 tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term + prod*(-diff2);
804 if (rai < sk-dr)
806 tmp = tmp + 2.0 * (rai_inv-lij);
809 /* duij = 1.0; */
810 t1 = 0.5*lij2 + prod*lij3 - 0.25*(lij*rinv+lij3*dr);
811 t2 = -0.5*uij2 - 0.25*sk2_rinv*uij3 + 0.25*(uij*rinv+uij3*dr);
812 t3 = 0.125*(1.0+sk2_rinv*rinv)*(-diff2)+0.25*log_term*rinv*rinv;
814 dadx_val = (dlij*t1+t2+t3)*rinv; /* rb2 is moved to chainrule */
816 sum_ai += 0.5*tmp;
818 else
820 dadx_val = 0.0;
822 fr->dadx[n++] = dadx_val;
824 /* ai -> aj interaction */
825 if (raj < dr + sk_ai)
827 lij = 1.0/(dr-sk_ai);
828 dlij = 1.0;
829 raj_inv = 1.0/raj;
831 if (raj > dr-sk_ai)
833 lij = raj_inv;
834 dlij = 0.0;
837 lij2 = lij * lij;
838 lij3 = lij2 * lij;
840 uij = 1.0/(dr+sk_ai);
841 uij2 = uij * uij;
842 uij3 = uij2 * uij;
844 diff2 = uij2-lij2;
846 lij_inv = gmx::invsqrt(lij2);
847 sk2 = sk2_ai; /* sk2_ai = sk_ai * sk_ai in i loop above */
848 sk2_rinv = sk2*rinv;
849 prod = 0.25 * sk2_rinv;
851 /* log_term = table_log(uij*lij_inv,born->log_table,LOG_TABLE_ACCURACY); */
852 log_term = std::log(uij*lij_inv);
854 tmp = lij-uij + 0.25*dr*diff2 + (0.5*rinv)*log_term + prod*(-diff2);
856 if (raj < sk_ai-dr)
858 tmp = tmp + 2.0 * (raj_inv-lij);
861 t1 = 0.5*lij2 + prod*lij3 - 0.25*(lij*rinv+lij3*dr);
862 t2 = -0.5*uij2 - 0.25*sk2_rinv*uij3 + 0.25*(uij*rinv+uij3*dr);
863 t3 = 0.125*(1.0+sk2_rinv*rinv)*(-diff2)+0.25*log_term*rinv*rinv;
865 dadx_val = (dlij*t1+t2+t3)*rinv; /* rb2 is moved to chainrule */
867 born->gpol_hct_work[aj] += 0.5*tmp;
870 else
872 dadx_val = 0.0;
874 fr->dadx[n++] = dadx_val;
877 born->gpol_hct_work[ai] += sum_ai;
881 /* Parallel summations */
882 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]];
892 rai_inv2 = 1.0/rai;
893 rai = rai-doffset;
894 rai_inv = 1.0/rai;
895 sum_ai = rai * born->gpol_hct_work[i];
896 sum_ai2 = sum_ai * sum_ai;
897 sum_ai3 = sum_ai2 * sum_ai;
899 tsum = tanh(born->obc_alpha*sum_ai-born->obc_beta*sum_ai2+born->obc_gamma*sum_ai3);
900 born->bRad[i] = rai_inv - tsum*rai_inv2;
901 born->bRad[i] = 1.0 / born->bRad[i];
903 fr->invsqrta[i] = gmx::invsqrt(born->bRad[i]);
905 tchain = rai * (born->obc_alpha-2*born->obc_beta*sum_ai+3*born->obc_gamma*sum_ai2);
906 born->drobc[i] = (1.0-tsum*tsum)*tchain*rai_inv2;
910 /* Extra (local) communication required for DD */
911 if (DOMAINDECOMP(cr))
913 dd_atom_spread_real(cr->dd, born->bRad);
914 dd_atom_spread_real(cr->dd, fr->invsqrta);
915 dd_atom_spread_real(cr->dd, born->drobc);
918 return 0;
924 int calc_gb_rad(t_commrec *cr, t_forcerec *fr, t_inputrec *ir, gmx_localtop_t *top,
925 rvec x[], t_nblist *nl, gmx_genborn_t *born, t_mdatoms *md, t_nrnb *nrnb)
927 int cnt;
928 int ndadx;
930 if (fr->bAllvsAll && fr->dadx == nullptr)
932 /* We might need up to 8 atoms of padding before and after,
933 * and another 4 units to guarantee SSE alignment.
935 fr->nalloc_dadx = 2*(md->homenr+12)*(md->nr/2+1+12);
936 snew(fr->dadx_rawptr, fr->nalloc_dadx);
937 fr->dadx = (real *) (((size_t) fr->dadx_rawptr + 16) & (~((size_t) 15)));
939 else
941 /* In the SSE-enabled gb-loops, when writing to dadx, we
942 * always write 2*4 elements at a time, even in the case with only
943 * 1-3 j particles, where we only really need to write 2*(1-3)
944 * elements. This is because we want dadx to be aligned to a 16-
945 * byte boundary, and being able to use _mm_store/load_ps
947 ndadx = 2 * (nl->nrj + 3*nl->nri);
949 /* First, reallocate the dadx array, we need 3 extra for SSE */
950 if (ndadx + 3 > fr->nalloc_dadx)
952 fr->nalloc_dadx = over_alloc_large(ndadx) + 3;
953 srenew(fr->dadx_rawptr, fr->nalloc_dadx);
954 fr->dadx = (real *) (((size_t) fr->dadx_rawptr + 16) & (~((size_t) 15)));
958 if (fr->bAllvsAll)
960 cnt = md->homenr*(md->nr/2+1);
962 if (ir->gb_algorithm == egbSTILL)
964 genborn_allvsall_calc_still_radii(fr, md, born, top, x[0], &fr->AllvsAll_workgb);
965 /* 13 flops in outer loop, 47 flops in inner loop */
966 inc_nrnb(nrnb, eNR_BORN_AVA_RADII_STILL, md->homenr*13+cnt*47);
968 else if (ir->gb_algorithm == egbHCT || ir->gb_algorithm == egbOBC)
970 genborn_allvsall_calc_hct_obc_radii(fr, md, born, ir->gb_algorithm, top, x[0], &fr->AllvsAll_workgb);
971 /* 24 flops in outer loop, 183 in inner */
972 inc_nrnb(nrnb, eNR_BORN_AVA_RADII_HCT_OBC, md->homenr*24+cnt*183);
974 else
976 gmx_fatal(FARGS, "Bad gb algorithm for all-vs-all interactions");
978 return 0;
981 /* Switch for determining which algorithm to use for Born radii calculation */
982 #if GMX_DOUBLE
984 switch (ir->gb_algorithm)
986 case egbSTILL:
987 calc_gb_rad_still(cr, fr, top, x, nl, born, md);
988 break;
989 case egbHCT:
990 calc_gb_rad_hct(cr, fr, top, x, nl, born, md);
991 break;
992 case egbOBC:
993 calc_gb_rad_obc(cr, fr, top, x, nl, born, md);
994 break;
996 default:
997 gmx_fatal(FARGS, "Unknown double precision algorithm for Born radii calculation: %d", ir->gb_algorithm);
1000 #else
1002 switch (ir->gb_algorithm)
1004 case egbSTILL:
1005 calc_gb_rad_still(cr, fr, top, x, nl, born, md);
1006 break;
1007 case egbHCT:
1008 calc_gb_rad_hct(cr, fr, top, x, nl, born, md);
1009 break;
1010 case egbOBC:
1011 calc_gb_rad_obc(cr, fr, top, x, nl, born, md);
1012 break;
1014 default:
1015 gmx_fatal(FARGS, "Unknown algorithm for Born radii calculation: %d", ir->gb_algorithm);
1018 #endif /* Double or single precision */
1020 if (fr->bAllvsAll == FALSE)
1022 switch (ir->gb_algorithm)
1024 case egbSTILL:
1025 /* 17 flops per outer loop iteration, 47 flops per inner loop */
1026 inc_nrnb(nrnb, eNR_BORN_RADII_STILL, nl->nri*17+nl->nrj*47);
1027 break;
1028 case egbHCT:
1029 case egbOBC:
1030 /* 61 (assuming 10 for tanh) flops for outer loop iteration, 183 flops per inner loop */
1031 inc_nrnb(nrnb, eNR_BORN_RADII_HCT_OBC, nl->nri*61+nl->nrj*183);
1032 break;
1034 default:
1035 break;
1039 return 0;
1044 real gb_bonds_tab(rvec x[], rvec f[], rvec fshift[], real *charge, real *p_gbtabscale,
1045 real *invsqrta, real *dvda, real *GBtab, t_idef *idef, real epsilon_r,
1046 real gb_epsilon_solvent, real facel, const t_pbc *pbc, const t_graph *graph)
1048 int i, j, n0, m, nnn, ai, aj;
1049 int ki;
1051 real isai, isaj;
1052 real r, rsq11;
1053 real rinv11, iq;
1054 real isaprod, qq, gbscale, gbtabscale, Y, F, Geps, Heps2, Fp, VV, FF, rt, eps, eps2;
1055 real vgb, fgb, fijC, dvdatmp, fscal;
1056 real vctot;
1058 rvec dx;
1059 ivec dt;
1061 t_iatom *forceatoms;
1063 /* Scale the electrostatics by gb_epsilon_solvent */
1064 facel = facel * ((1.0/epsilon_r) - 1.0/gb_epsilon_solvent);
1066 gbtabscale = *p_gbtabscale;
1067 vctot = 0.0;
1069 for (j = F_GB12; j <= F_GB14; j++)
1071 forceatoms = idef->il[j].iatoms;
1073 for (i = 0; i < idef->il[j].nr; )
1075 /* To avoid reading in the interaction type, we just increment i to pass over
1076 * the types in the forceatoms array, this saves some memory accesses
1078 i++;
1079 ai = forceatoms[i++];
1080 aj = forceatoms[i++];
1082 ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx);
1083 rsq11 = iprod(dx, dx);
1085 isai = invsqrta[ai];
1086 iq = (-1)*facel*charge[ai];
1088 rinv11 = gmx::invsqrt(rsq11);
1089 isaj = invsqrta[aj];
1090 isaprod = isai*isaj;
1091 qq = isaprod*iq*charge[aj];
1092 gbscale = isaprod*gbtabscale;
1093 r = rsq11*rinv11;
1094 rt = r*gbscale;
1095 n0 = static_cast<int>(rt);
1096 eps = rt-n0;
1097 eps2 = eps*eps;
1098 nnn = 4*n0;
1099 Y = GBtab[nnn];
1100 F = GBtab[nnn+1];
1101 Geps = eps*GBtab[nnn+2];
1102 Heps2 = eps2*GBtab[nnn+3];
1103 Fp = F+Geps+Heps2;
1104 VV = Y+eps*Fp;
1105 FF = Fp+Geps+2.0*Heps2;
1106 vgb = qq*VV;
1107 fijC = qq*FF*gbscale;
1108 dvdatmp = -(vgb+fijC*r)*0.5;
1109 dvda[aj] = dvda[aj] + dvdatmp*isaj*isaj;
1110 dvda[ai] = dvda[ai] + dvdatmp*isai*isai;
1111 vctot = vctot + vgb;
1112 fgb = -(fijC)*rinv11;
1114 if (graph)
1116 ivec_sub(SHIFT_IVEC(graph, ai), SHIFT_IVEC(graph, aj), dt);
1117 ki = IVEC2IS(dt);
1120 for (m = 0; (m < DIM); m++) /* 15 */
1122 fscal = fgb*dx[m];
1123 f[ai][m] += fscal;
1124 f[aj][m] -= fscal;
1125 fshift[ki][m] += fscal;
1126 fshift[CENTRAL][m] -= fscal;
1131 return vctot;
1134 static real calc_gb_selfcorrections(t_commrec *cr, int natoms,
1135 real *charge, gmx_genborn_t *born, real *dvda, double facel)
1137 int i, ai, at0, at1;
1138 real rai, e, derb, q, q2, fi, rai_inv, vtot;
1140 if (DOMAINDECOMP(cr))
1142 at0 = 0;
1143 at1 = cr->dd->nat_home;
1145 else
1147 at0 = 0;
1148 at1 = natoms;
1152 /* Scale the electrostatics by gb_epsilon_solvent */
1153 facel = facel * ((1.0/born->epsilon_r) - 1.0/born->gb_epsilon_solvent);
1155 vtot = 0.0;
1157 /* Apply self corrections */
1158 for (i = at0; i < at1; i++)
1160 ai = i;
1162 if (born->use[ai] == 1)
1164 rai = born->bRad[ai];
1165 rai_inv = 1.0/rai;
1166 q = charge[ai];
1167 q2 = q*q;
1168 fi = facel*q2;
1169 e = fi*rai_inv;
1170 derb = 0.5*e*rai_inv*rai_inv;
1171 dvda[ai] += derb*rai;
1172 vtot -= 0.5*e;
1176 return vtot;
1180 static real calc_gb_nonpolar(t_commrec *cr, t_forcerec *fr, int natoms, gmx_genborn_t *born, gmx_localtop_t *top,
1181 real *dvda, t_mdatoms *md)
1183 int ai, i, at0, at1;
1184 real e, es, rai, term, probe, tmp, factor;
1185 real rbi_inv, rbi_inv2;
1187 if (DOMAINDECOMP(cr))
1189 at0 = 0;
1190 at1 = cr->dd->nat_home;
1192 else
1194 at0 = 0;
1195 at1 = natoms;
1198 /* factor is the surface tension */
1199 factor = born->sa_surface_tension;
1201 es = 0;
1202 probe = 0.14;
1203 term = M_PI*4;
1205 for (i = at0; i < at1; i++)
1207 ai = i;
1209 if (born->use[ai] == 1)
1211 rai = top->atomtypes.gb_radius[md->typeA[ai]];
1212 rbi_inv = fr->invsqrta[ai];
1213 rbi_inv2 = rbi_inv * rbi_inv;
1214 tmp = (rai*rbi_inv2)*(rai*rbi_inv2);
1215 tmp = tmp*tmp*tmp;
1216 e = factor*term*(rai+probe)*(rai+probe)*tmp;
1217 dvda[ai] = dvda[ai] - 6*e*rbi_inv2;
1218 es = es + e;
1222 return es;
1227 static real calc_gb_chainrule(int natoms, t_nblist *nl, real *dadx, real *dvda, rvec x[], rvec t[], rvec fshift[],
1228 rvec shift_vec[], int gb_algorithm, gmx_genborn_t *born)
1230 int i, k, n, ai, aj, nj0, nj1, n0, n1;
1231 int shift;
1232 real shX, shY, shZ;
1233 real fgb, rbi, fix1, fiy1, fiz1;
1234 real ix1, iy1, iz1, jx1, jy1, jz1, dx11, dy11, dz11;
1235 real tx, ty, tz, rbai, rbaj, fgb_ai;
1236 real *rb;
1238 n = 0;
1239 rb = born->work;
1241 n0 = 0;
1242 n1 = natoms;
1244 if (gb_algorithm == egbSTILL)
1246 for (i = n0; i < n1; i++)
1248 rbi = born->bRad[i];
1249 rb[i] = (2 * rbi * rbi * dvda[i])/ONE_4PI_EPS0;
1252 else if (gb_algorithm == egbHCT)
1254 for (i = n0; i < n1; i++)
1256 rbi = born->bRad[i];
1257 rb[i] = rbi * rbi * dvda[i];
1260 else if (gb_algorithm == egbOBC)
1262 for (i = n0; i < n1; i++)
1264 rbi = born->bRad[i];
1265 rb[i] = rbi * rbi * born->drobc[i] * dvda[i];
1269 for (i = 0; i < nl->nri; i++)
1271 ai = nl->iinr[i];
1273 nj0 = nl->jindex[i];
1274 nj1 = nl->jindex[i+1];
1276 /* Load shifts for this list */
1277 shift = nl->shift[i];
1278 shX = shift_vec[shift][0];
1279 shY = shift_vec[shift][1];
1280 shZ = shift_vec[shift][2];
1282 /* Load atom i coordinates, add shift vectors */
1283 ix1 = shX + x[ai][0];
1284 iy1 = shY + x[ai][1];
1285 iz1 = shZ + x[ai][2];
1287 fix1 = 0;
1288 fiy1 = 0;
1289 fiz1 = 0;
1291 rbai = rb[ai];
1293 for (k = nj0; k < nj1 && nl->jjnr[k] >= 0; k++)
1295 aj = nl->jjnr[k];
1297 jx1 = x[aj][0];
1298 jy1 = x[aj][1];
1299 jz1 = x[aj][2];
1301 dx11 = ix1 - jx1;
1302 dy11 = iy1 - jy1;
1303 dz11 = iz1 - jz1;
1305 rbaj = rb[aj];
1307 fgb = rbai*dadx[n++];
1308 fgb_ai = rbaj*dadx[n++];
1310 /* Total force between ai and aj is the sum of ai->aj and aj->ai */
1311 fgb = fgb + fgb_ai;
1313 tx = fgb * dx11;
1314 ty = fgb * dy11;
1315 tz = fgb * dz11;
1317 fix1 = fix1 + tx;
1318 fiy1 = fiy1 + ty;
1319 fiz1 = fiz1 + tz;
1321 /* Update force on atom aj */
1322 t[aj][0] = t[aj][0] - tx;
1323 t[aj][1] = t[aj][1] - ty;
1324 t[aj][2] = t[aj][2] - tz;
1327 /* Update force and shift forces on atom ai */
1328 t[ai][0] = t[ai][0] + fix1;
1329 t[ai][1] = t[ai][1] + fiy1;
1330 t[ai][2] = t[ai][2] + fiz1;
1332 fshift[shift][0] = fshift[shift][0] + fix1;
1333 fshift[shift][1] = fshift[shift][1] + fiy1;
1334 fshift[shift][2] = fshift[shift][2] + fiz1;
1338 return 0;
1342 void
1343 calc_gb_forces(t_commrec *cr, t_mdatoms *md, gmx_genborn_t *born, gmx_localtop_t *top,
1344 rvec x[], rvec f[], t_forcerec *fr, t_idef *idef, int gb_algorithm, int sa_algorithm, t_nrnb *nrnb,
1345 const t_pbc *pbc, const t_graph *graph, gmx_enerdata_t *enerd)
1347 int cnt;
1349 /* PBC or not? */
1350 const t_pbc *pbc_null;
1352 if (fr->bMolPBC)
1354 pbc_null = pbc;
1356 else
1358 pbc_null = nullptr;
1361 if (sa_algorithm == esaAPPROX)
1363 /* Do a simple ACE type approximation for the non-polar solvation */
1364 enerd->term[F_NPSOLVATION] += calc_gb_nonpolar(cr, fr, born->nr, born, top, fr->dvda, md);
1367 /* Calculate the bonded GB-interactions using either table or analytical formula */
1368 enerd->term[F_GBPOL] += gb_bonds_tab(x, f, fr->fshift, md->chargeA, &(fr->gbtabscale),
1369 fr->invsqrta, fr->dvda, fr->gbtab->data, idef, born->epsilon_r, born->gb_epsilon_solvent, fr->ic->epsfac, pbc_null, graph);
1371 /* Calculate self corrections to the GB energies - currently only A state used! (FIXME) */
1372 enerd->term[F_GBPOL] += calc_gb_selfcorrections(cr, born->nr, md->chargeA, born, fr->dvda, fr->ic->epsfac);
1374 /* If parallel, sum the derivative of the potential w.r.t the born radii */
1375 if (DOMAINDECOMP(cr))
1377 dd_atom_sum_real(cr->dd, fr->dvda);
1378 dd_atom_spread_real(cr->dd, fr->dvda);
1381 if (fr->bAllvsAll)
1383 genborn_allvsall_calc_chainrule(fr, md, born, x[0], f[0], gb_algorithm, fr->AllvsAll_workgb);
1384 cnt = md->homenr*(md->nr/2+1);
1385 /* 9 flops for outer loop, 15 for inner */
1386 inc_nrnb(nrnb, eNR_BORN_AVA_CHAINRULE, md->homenr*9+cnt*15);
1387 return;
1390 calc_gb_chainrule(fr->natoms_force, fr->gblist, fr->dadx, fr->dvda,
1391 x, f, fr->fshift, fr->shift_vec, gb_algorithm, born);
1393 if (!fr->bAllvsAll)
1395 /* 9 flops for outer loop, 15 for inner */
1396 inc_nrnb(nrnb, eNR_BORN_CHAINRULE, fr->gblist->nri*9+fr->gblist->nrj*15);
1400 static void add_j_to_gblist(gbtmpnbl_t *list, int aj)
1402 if (list->naj >= list->aj_nalloc)
1404 list->aj_nalloc = over_alloc_large(list->naj+1);
1405 srenew(list->aj, list->aj_nalloc);
1408 list->aj[list->naj++] = aj;
1411 static gbtmpnbl_t *find_gbtmplist(struct gbtmpnbls *lists, int shift)
1413 int ind, i;
1415 /* Search the list with the same shift, if there is one */
1416 ind = 0;
1417 while (ind < lists->nlist && shift != lists->list[ind].shift)
1419 ind++;
1421 if (ind == lists->nlist)
1423 if (lists->nlist == lists->list_nalloc)
1425 lists->list_nalloc++;
1426 srenew(lists->list, lists->list_nalloc);
1427 for (i = lists->nlist; i < lists->list_nalloc; i++)
1429 lists->list[i].aj = nullptr;
1430 lists->list[i].aj_nalloc = 0;
1435 lists->list[lists->nlist].shift = shift;
1436 lists->list[lists->nlist].naj = 0;
1437 lists->nlist++;
1440 return &lists->list[ind];
1443 static void add_bondeds_to_gblist(t_ilist *il,
1444 gmx_bool bMolPBC, t_pbc *pbc, t_graph *g, rvec *x,
1445 struct gbtmpnbls *nls)
1447 int ind, j, ai, aj, found;
1448 rvec dx;
1449 ivec dt;
1450 gbtmpnbl_t *list;
1452 for (ind = 0; ind < il->nr; ind += 3)
1454 ai = il->iatoms[ind+1];
1455 aj = il->iatoms[ind+2];
1457 int shift = CENTRAL;
1458 if (g != nullptr)
1460 rvec_sub(x[ai], x[aj], dx);
1461 ivec_sub(SHIFT_IVEC(g, ai), SHIFT_IVEC(g, aj), dt);
1462 shift = IVEC2IS(dt);
1464 else if (bMolPBC)
1466 shift = pbc_dx_aiuc(pbc, x[ai], x[aj], dx);
1469 /* Find the list for this shift or create one */
1470 list = find_gbtmplist(&nls[ai], shift);
1472 found = 0;
1474 /* So that we do not add the same bond twice.
1475 * This happens with some constraints between 1-3 atoms
1476 * that are in the bond-list but should not be in the GB nb-list */
1477 for (j = 0; j < list->naj; j++)
1479 if (list->aj[j] == aj)
1481 found = 1;
1485 if (found == 0)
1487 if (ai == aj)
1489 gmx_incons("ai == aj");
1492 add_j_to_gblist(list, aj);
1498 int make_gb_nblist(t_commrec *cr, int gb_algorithm,
1499 rvec x[], matrix box,
1500 t_forcerec *fr, t_idef *idef, t_graph *graph, gmx_genborn_t *born)
1502 int i, j, k, n, nj0, nj1, ai, shift, s;
1503 t_nblist *nblist;
1504 t_pbc pbc;
1506 struct gbtmpnbls *nls;
1507 gbtmpnbl_t *list = nullptr;
1509 set_pbc(&pbc, fr->ePBC, box);
1510 nls = born->nblist_work;
1512 for (i = 0; i < born->nr; i++)
1514 nls[i].nlist = 0;
1517 if (fr->bMolPBC)
1519 set_pbc_dd(&pbc, fr->ePBC, cr->dd->nc, TRUE, box);
1522 switch (gb_algorithm)
1524 case egbHCT:
1525 case egbOBC:
1526 /* Loop over 1-2, 1-3 and 1-4 interactions */
1527 for (j = F_GB12; j <= F_GB14; j++)
1529 add_bondeds_to_gblist(&idef->il[j], fr->bMolPBC, &pbc, graph, x, nls);
1531 break;
1532 case egbSTILL:
1533 /* Loop over 1-4 interactions */
1534 add_bondeds_to_gblist(&idef->il[F_GB14], fr->bMolPBC, &pbc, graph, x, nls);
1535 break;
1536 default:
1537 gmx_incons("Unknown GB algorithm");
1540 /* Loop over the VDWQQ and VDW nblists to set up the nonbonded part of the GB list */
1541 for (n = 0; (n < fr->nnblists); n++)
1543 for (i = 0; (i < eNL_NR); i++)
1545 nblist = &(fr->nblists[n].nlist_sr[i]);
1547 if (nblist->nri > 0 && (i == eNL_VDWQQ || i == eNL_QQ))
1549 for (j = 0; j < nblist->nri; j++)
1551 ai = nblist->iinr[j];
1552 shift = nblist->shift[j];
1554 /* Find the list for this shift or create one */
1555 list = find_gbtmplist(&nls[ai], shift);
1557 nj0 = nblist->jindex[j];
1558 nj1 = nblist->jindex[j+1];
1560 /* Add all the j-atoms in the non-bonded list to the GB list */
1561 for (k = nj0; k < nj1; k++)
1563 add_j_to_gblist(list, nblist->jjnr[k]);
1570 /* Zero out some counters */
1571 fr->gblist->nri = 0;
1572 fr->gblist->nrj = 0;
1574 fr->gblist->jindex[0] = fr->gblist->nri;
1576 for (i = 0; i < fr->natoms_force; i++)
1578 for (s = 0; s < nls[i].nlist; s++)
1580 list = &nls[i].list[s];
1582 /* Only add those atoms that actually have neighbours */
1583 if (born->use[i] != 0)
1585 fr->gblist->iinr[fr->gblist->nri] = i;
1586 fr->gblist->shift[fr->gblist->nri] = list->shift;
1587 fr->gblist->nri++;
1589 for (k = 0; k < list->naj; k++)
1591 /* Memory allocation for jjnr */
1592 if (fr->gblist->nrj >= fr->gblist->maxnrj)
1594 fr->gblist->maxnrj += over_alloc_large(fr->gblist->maxnrj);
1596 if (debug)
1598 fprintf(debug, "Increasing GB neighbourlist j size to %d\n", fr->gblist->maxnrj);
1601 srenew(fr->gblist->jjnr, fr->gblist->maxnrj);
1604 /* Put in list */
1605 if (i == list->aj[k])
1607 gmx_incons("i == list->aj[k]");
1609 fr->gblist->jjnr[fr->gblist->nrj++] = list->aj[k];
1612 fr->gblist->jindex[fr->gblist->nri] = fr->gblist->nrj;
1617 return 0;
1620 void make_local_gb(const t_commrec *cr, gmx_genborn_t *born, int gb_algorithm)
1622 int i, at0, at1;
1623 gmx_domdec_t *dd = nullptr;
1625 if (DOMAINDECOMP(cr))
1627 dd = cr->dd;
1628 at0 = 0;
1629 at1 = dd->nat_tot;
1631 else
1633 /* Single node, just copy pointers and return */
1634 if (gb_algorithm == egbSTILL)
1636 born->gpol = born->gpol_globalindex;
1637 born->vsolv = born->vsolv_globalindex;
1638 born->gb_radius = born->gb_radius_globalindex;
1640 else
1642 born->param = born->param_globalindex;
1643 born->gb_radius = born->gb_radius_globalindex;
1646 born->use = born->use_globalindex;
1648 return;
1651 /* Reallocation of local arrays if necessary */
1652 /* fr->natoms_force is equal to dd->nat_tot */
1653 if (DOMAINDECOMP(cr) && dd->nat_tot > born->nalloc)
1655 int nalloc;
1657 nalloc = dd->nat_tot;
1659 /* Arrays specific to different gb algorithms */
1660 if (gb_algorithm == egbSTILL)
1662 srenew(born->gpol, nalloc+3);
1663 srenew(born->vsolv, nalloc+3);
1664 srenew(born->gb_radius, nalloc+3);
1665 for (i = born->nalloc; (i < nalloc+3); i++)
1667 born->gpol[i] = 0;
1668 born->vsolv[i] = 0;
1669 born->gb_radius[i] = 0;
1672 else
1674 srenew(born->param, nalloc+3);
1675 srenew(born->gb_radius, nalloc+3);
1676 for (i = born->nalloc; (i < nalloc+3); i++)
1678 born->param[i] = 0;
1679 born->gb_radius[i] = 0;
1683 /* All gb-algorithms use the array for vsites exclusions */
1684 srenew(born->use, nalloc+3);
1685 for (i = born->nalloc; (i < nalloc+3); i++)
1687 born->use[i] = 0;
1690 born->nalloc = nalloc;
1693 /* With dd, copy algorithm specific arrays */
1694 if (gb_algorithm == egbSTILL)
1696 for (i = at0; i < at1; i++)
1698 born->gpol[i] = born->gpol_globalindex[dd->gatindex[i]];
1699 born->vsolv[i] = born->vsolv_globalindex[dd->gatindex[i]];
1700 born->gb_radius[i] = born->gb_radius_globalindex[dd->gatindex[i]];
1701 born->use[i] = born->use_globalindex[dd->gatindex[i]];
1704 else
1706 for (i = at0; i < at1; i++)
1708 born->param[i] = born->param_globalindex[dd->gatindex[i]];
1709 born->gb_radius[i] = born->gb_radius_globalindex[dd->gatindex[i]];
1710 born->use[i] = born->use_globalindex[dd->gatindex[i]];