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-2004, The GROMACS development team.
6 * Copyright (c) 2013,2014,2015, 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.
39 #include "vsite_parm.h"
48 #include "gromacs/gmxpreprocess/add_par.h"
49 #include "gromacs/gmxpreprocess/resall.h"
50 #include "gromacs/gmxpreprocess/toputil.h"
51 #include "gromacs/legacyheaders/macros.h"
52 #include "gromacs/legacyheaders/names.h"
53 #include "gromacs/math/units.h"
54 #include "gromacs/math/vec.h"
55 #include "gromacs/utility/cstringutil.h"
56 #include "gromacs/utility/fatalerror.h"
57 #include "gromacs/utility/gmxassert.h"
58 #include "gromacs/utility/smalloc.h"
73 vsitebondparam_t *vsbp;
81 static int vsite_bond_nrcheck(int ftype)
85 if ((interaction_function[ftype].flags & (IF_BTYPE | IF_CONSTRAINT | IF_ATYPE)) || (ftype == F_IDIHS))
87 nrcheck = NRAL(ftype);
97 static void enter_bonded(int nratoms, int *nrbonded, t_mybonded **bondeds,
102 srenew(*bondeds, *nrbonded+1);
104 /* copy atom numbers */
105 for (j = 0; j < nratoms; j++)
107 (*bondeds)[*nrbonded].a[j] = param->a[j];
110 (*bondeds)[*nrbonded].c = param->C0;
115 static void get_bondeds(int nrat, t_iatom atoms[],
116 at2vsitebond_t *at2vb,
117 int *nrbond, t_mybonded **bonds,
118 int *nrang, t_mybonded **angles,
119 int *nridih, t_mybonded **idihs )
121 int k, i, ftype, nrcheck;
124 for (k = 0; k < nrat; k++)
126 for (i = 0; i < at2vb[atoms[k]].nr; i++)
128 ftype = at2vb[atoms[k]].vsbp[i].ftype;
129 param = at2vb[atoms[k]].vsbp[i].param;
130 nrcheck = vsite_bond_nrcheck(ftype);
131 /* abuse nrcheck to see if we're adding bond, angle or idih */
134 case 2: enter_bonded(nrcheck, nrbond, bonds, param); break;
135 case 3: enter_bonded(nrcheck, nrang, angles, param); break;
136 case 4: enter_bonded(nrcheck, nridih, idihs, param); break;
142 static at2vsitebond_t *make_at2vsitebond(int natoms, t_params plist[])
145 int ftype, i, j, nrcheck, nr;
147 at2vsitebond_t *at2vb;
152 for (ftype = 0; (ftype < F_NRE); ftype++)
154 if ((interaction_function[ftype].flags & IF_VSITE) && ftype != F_VSITEN)
156 for (i = 0; (i < plist[ftype].nr); i++)
158 for (j = 0; j < NRAL(ftype); j++)
160 bVSI[plist[ftype].param[i].a[j]] = TRUE;
166 for (ftype = 0; (ftype < F_NRE); ftype++)
168 nrcheck = vsite_bond_nrcheck(ftype);
171 for (i = 0; (i < plist[ftype].nr); i++)
173 aa = plist[ftype].param[i].a;
174 for (j = 0; j < nrcheck; j++)
178 nr = at2vb[aa[j]].nr;
181 srenew(at2vb[aa[j]].vsbp, nr+10);
183 at2vb[aa[j]].vsbp[nr].ftype = ftype;
184 at2vb[aa[j]].vsbp[nr].param = &plist[ftype].param[i];
196 static void done_at2vsitebond(int natoms, at2vsitebond_t *at2vb)
200 for (i = 0; i < natoms; i++)
204 sfree(at2vb[i].vsbp);
210 static at2vsitecon_t *make_at2vsitecon(int natoms, t_params plist[])
213 int ftype, i, j, ai, aj, nr;
214 at2vsitecon_t *at2vc;
219 for (ftype = 0; (ftype < F_NRE); ftype++)
221 if ((interaction_function[ftype].flags & IF_VSITE) && ftype != F_VSITEN)
223 for (i = 0; (i < plist[ftype].nr); i++)
225 for (j = 0; j < NRAL(ftype); j++)
227 bVSI[plist[ftype].param[i].a[j]] = TRUE;
233 for (ftype = 0; (ftype < F_NRE); ftype++)
235 if (interaction_function[ftype].flags & IF_CONSTRAINT)
237 for (i = 0; (i < plist[ftype].nr); i++)
239 ai = plist[ftype].param[i].AI;
240 aj = plist[ftype].param[i].AJ;
241 if (bVSI[ai] && bVSI[aj])
243 /* Store forward direction */
247 srenew(at2vc[ai].aj, nr+10);
249 at2vc[ai].aj[nr] = aj;
251 /* Store backward direction */
255 srenew(at2vc[aj].aj, nr+10);
257 at2vc[aj].aj[nr] = ai;
268 static void done_at2vsitecon(int natoms, at2vsitecon_t *at2vc)
272 for (i = 0; i < natoms; i++)
283 static void print_bad(FILE *fp,
284 int nrbond, t_mybonded *bonds,
285 int nrang, t_mybonded *angles,
286 int nridih, t_mybonded *idihs )
292 fprintf(fp, "bonds:");
293 for (i = 0; i < nrbond; i++)
295 fprintf(fp, " %d-%d (%g)",
296 bonds[i].AI+1, bonds[i].AJ+1, bonds[i].c);
302 fprintf(fp, "angles:");
303 for (i = 0; i < nrang; i++)
305 fprintf(fp, " %d-%d-%d (%g)",
306 angles[i].AI+1, angles[i].AJ+1,
307 angles[i].AK+1, angles[i].c);
313 fprintf(fp, "idihs:");
314 for (i = 0; i < nridih; i++)
316 fprintf(fp, " %d-%d-%d-%d (%g)",
317 idihs[i].AI+1, idihs[i].AJ+1,
318 idihs[i].AK+1, idihs[i].AL+1, idihs[i].c);
324 static void print_param(FILE *fp, int ftype, int i, t_param *param)
327 static int prev_ftype = NOTSET;
328 static int prev_i = NOTSET;
331 if ( (ftype != prev_ftype) || (i != prev_i) )
337 fprintf(fp, "(%d) plist[%s].param[%d]",
338 pass, interaction_function[ftype].name, i);
339 for (j = 0; j < NRFP(ftype); j++)
341 fprintf(fp, ".c[%d]=%g ", j, param->c[j]);
347 static real get_bond_length(int nrbond, t_mybonded bonds[],
348 t_iatom ai, t_iatom aj)
354 for (i = 0; i < nrbond && (bondlen == NOTSET); i++)
356 /* check both ways */
357 if ( ( (ai == bonds[i].AI) && (aj == bonds[i].AJ) ) ||
358 ( (ai == bonds[i].AJ) && (aj == bonds[i].AI) ) )
360 bondlen = bonds[i].c; /* note: bonds[i].c might be NOTSET */
366 static real get_angle(int nrang, t_mybonded angles[],
367 t_iatom ai, t_iatom aj, t_iatom ak)
373 for (i = 0; i < nrang && (angle == NOTSET); i++)
375 /* check both ways */
376 if ( ( (ai == angles[i].AI) && (aj == angles[i].AJ) && (ak == angles[i].AK) ) ||
377 ( (ai == angles[i].AK) && (aj == angles[i].AJ) && (ak == angles[i].AI) ) )
379 angle = DEG2RAD*angles[i].c;
385 static char *get_atomtype_name_AB(t_atom *atom, gpp_atomtype_t atype)
389 name = get_atomtype_name(atom->type, atype);
391 /* When using the decoupling option, atom types are changed
392 * to decoupled for the non-bonded interactions, but the virtual
393 * sites constructions should be based on the "normal" interactions.
394 * So we return the state B atom type name if the state A atom
395 * type is the decoupled one. We should actually check for the atom
396 * type number, but that's not passed here. So we check for
397 * the decoupled atom type name. This should not cause trouble
398 * as this code is only used for topologies with v-sites without
399 * parameters generated by pdb2gmx.
401 if (strcmp(name, "decoupled") == 0)
403 name = get_atomtype_name(atom->typeB, atype);
409 static gmx_bool calc_vsite3_param(gpp_atomtype_t atype,
410 t_param *param, t_atoms *at,
411 int nrbond, t_mybonded *bonds,
412 int nrang, t_mybonded *angles )
414 /* i = virtual site | ,k
415 * j = 1st bonded heavy atom | i-j
416 * k,l = 2nd bonded atoms | `l
419 gmx_bool bXH3, bError;
420 real bjk, bjl, a = -1, b = -1;
421 /* check if this is part of a NH3 , NH2-umbrella or CH3 group,
422 * i.e. if atom k and l are dummy masses (MNH* or MCH3*) */
426 for (i = 0; i < 4; i++)
428 fprintf(debug, "atom %d type %s ",
430 get_atomtype_name_AB(&at->atom[param->a[i]], atype));
432 fprintf(debug, "\n");
435 ( (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AK], atype), "MNH", 3) == 0) &&
436 (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AL], atype), "MNH", 3) == 0) ) ||
437 ( (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AK], atype), "MCH3", 4) == 0) &&
438 (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AL], atype), "MCH3", 4) == 0) );
440 bjk = get_bond_length(nrbond, bonds, param->AJ, param->AK);
441 bjl = get_bond_length(nrbond, bonds, param->AJ, param->AL);
442 bError = (bjk == NOTSET) || (bjl == NOTSET);
445 /* now we get some XH2/XH3 group specific construction */
446 /* note: we call the heavy atom 'C' and the X atom 'N' */
447 real bMM, bCM, bCN, bNH, aCNH, dH, rH, dM, rM;
450 /* check if bonds from heavy atom (j) to dummy masses (k,l) are equal: */
451 bError = bError || (bjk != bjl);
453 /* the X atom (C or N) in the XH2/XH3 group is the first after the masses: */
454 aN = std::max(param->AK, param->AL)+1;
456 /* get common bonds */
457 bMM = get_bond_length(nrbond, bonds, param->AK, param->AL);
459 bCN = get_bond_length(nrbond, bonds, param->AJ, aN);
460 bError = bError || (bMM == NOTSET) || (bCN == NOTSET);
462 /* calculate common things */
464 dM = std::sqrt( sqr(bCM) - sqr(rM) );
466 /* are we dealing with the X atom? */
469 /* this is trivial */
470 a = b = 0.5 * bCN/dM;
475 /* get other bondlengths and angles: */
476 bNH = get_bond_length(nrbond, bonds, aN, param->AI);
477 aCNH = get_angle (nrang, angles, param->AJ, aN, param->AI);
478 bError = bError || (bNH == NOTSET) || (aCNH == NOTSET);
481 dH = bCN - bNH * cos(aCNH);
482 rH = bNH * sin(aCNH);
484 a = 0.5 * ( dH/dM + rH/rM );
485 b = 0.5 * ( dH/dM - rH/rM );
490 gmx_fatal(FARGS, "calc_vsite3_param not implemented for the general case "
491 "(atom %d)", param->AI+1);
499 fprintf(debug, "params for vsite3 %d: %g %g\n",
500 param->AI+1, param->C0, param->C1);
506 static gmx_bool calc_vsite3fd_param(t_param *param,
507 int nrbond, t_mybonded *bonds,
508 int nrang, t_mybonded *angles)
510 /* i = virtual site | ,k
511 * j = 1st bonded heavy atom | i-j
512 * k,l = 2nd bonded atoms | `l
516 real bij, bjk, bjl, aijk, aijl, rk, rl;
518 bij = get_bond_length(nrbond, bonds, param->AI, param->AJ);
519 bjk = get_bond_length(nrbond, bonds, param->AJ, param->AK);
520 bjl = get_bond_length(nrbond, bonds, param->AJ, param->AL);
521 aijk = get_angle (nrang, angles, param->AI, param->AJ, param->AK);
522 aijl = get_angle (nrang, angles, param->AI, param->AJ, param->AL);
523 bError = (bij == NOTSET) || (bjk == NOTSET) || (bjl == NOTSET) ||
524 (aijk == NOTSET) || (aijl == NOTSET);
526 rk = bjk * sin(aijk);
527 rl = bjl * sin(aijl);
528 param->C0 = rk / (rk + rl);
529 param->C1 = -bij; /* 'bond'-length for fixed distance vsite */
533 fprintf(debug, "params for vsite3fd %d: %g %g\n",
534 param->AI+1, param->C0, param->C1);
539 static gmx_bool calc_vsite3fad_param(t_param *param,
540 int nrbond, t_mybonded *bonds,
541 int nrang, t_mybonded *angles)
543 /* i = virtual site |
544 * j = 1st bonded heavy atom | i-j
545 * k = 2nd bonded heavy atom | `k-l
546 * l = 3d bonded heavy atom |
549 gmx_bool bSwapParity, bError;
552 bSwapParity = ( param->C1 == -1 );
554 bij = get_bond_length(nrbond, bonds, param->AI, param->AJ);
555 aijk = get_angle (nrang, angles, param->AI, param->AJ, param->AK);
556 bError = (bij == NOTSET) || (aijk == NOTSET);
558 param->C1 = bij; /* 'bond'-length for fixed distance vsite */
559 param->C0 = RAD2DEG*aijk; /* 'bond'-angle for fixed angle vsite */
563 param->C0 = 360 - param->C0;
568 fprintf(debug, "params for vsite3fad %d: %g %g\n",
569 param->AI+1, param->C0, param->C1);
574 static gmx_bool calc_vsite3out_param(gpp_atomtype_t atype,
575 t_param *param, t_atoms *at,
576 int nrbond, t_mybonded *bonds,
577 int nrang, t_mybonded *angles)
579 /* i = virtual site | ,k
580 * j = 1st bonded heavy atom | i-j
581 * k,l = 2nd bonded atoms | `l
582 * NOTE: i is out of the j-k-l plane!
585 gmx_bool bXH3, bError, bSwapParity;
586 real bij, bjk, bjl, aijk, aijl, akjl, pijk, pijl, a, b, c;
588 /* check if this is part of a NH2-umbrella, NH3 or CH3 group,
589 * i.e. if atom k and l are dummy masses (MNH* or MCH3*) */
593 for (i = 0; i < 4; i++)
595 fprintf(debug, "atom %d type %s ",
596 param->a[i]+1, get_atomtype_name_AB(&at->atom[param->a[i]], atype));
598 fprintf(debug, "\n");
601 ( (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AK], atype), "MNH", 3) == 0) &&
602 (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AL], atype), "MNH", 3) == 0) ) ||
603 ( (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AK], atype), "MCH3", 4) == 0) &&
604 (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AL], atype), "MCH3", 4) == 0) );
606 /* check if construction parity must be swapped */
607 bSwapParity = ( param->C1 == -1 );
609 bjk = get_bond_length(nrbond, bonds, param->AJ, param->AK);
610 bjl = get_bond_length(nrbond, bonds, param->AJ, param->AL);
611 bError = (bjk == NOTSET) || (bjl == NOTSET);
614 /* now we get some XH3 group specific construction */
615 /* note: we call the heavy atom 'C' and the X atom 'N' */
616 real bMM, bCM, bCN, bNH, aCNH, dH, rH, rHx, rHy, dM, rM;
619 /* check if bonds from heavy atom (j) to dummy masses (k,l) are equal: */
620 bError = bError || (bjk != bjl);
622 /* the X atom (C or N) in the XH3 group is the first after the masses: */
623 aN = std::max(param->AK, param->AL)+1;
625 /* get all bondlengths and angles: */
626 bMM = get_bond_length(nrbond, bonds, param->AK, param->AL);
628 bCN = get_bond_length(nrbond, bonds, param->AJ, aN);
629 bNH = get_bond_length(nrbond, bonds, aN, param->AI);
630 aCNH = get_angle (nrang, angles, param->AJ, aN, param->AI);
632 (bMM == NOTSET) || (bCN == NOTSET) || (bNH == NOTSET) || (aCNH == NOTSET);
635 dH = bCN - bNH * cos(aCNH);
636 rH = bNH * sin(aCNH);
637 /* we assume the H's are symmetrically distributed */
638 rHx = rH*cos(DEG2RAD*30);
639 rHy = rH*sin(DEG2RAD*30);
641 dM = std::sqrt( sqr(bCM) - sqr(rM) );
642 a = 0.5*( (dH/dM) - (rHy/rM) );
643 b = 0.5*( (dH/dM) + (rHy/rM) );
649 /* this is the general construction */
651 bij = get_bond_length(nrbond, bonds, param->AI, param->AJ);
652 aijk = get_angle (nrang, angles, param->AI, param->AJ, param->AK);
653 aijl = get_angle (nrang, angles, param->AI, param->AJ, param->AL);
654 akjl = get_angle (nrang, angles, param->AK, param->AJ, param->AL);
656 (bij == NOTSET) || (aijk == NOTSET) || (aijl == NOTSET) || (akjl == NOTSET);
658 pijk = cos(aijk)*bij;
659 pijl = cos(aijl)*bij;
660 a = ( pijk + (pijk*cos(akjl)-pijl) * cos(akjl) / sqr(sin(akjl)) ) / bjk;
661 b = ( pijl + (pijl*cos(akjl)-pijk) * cos(akjl) / sqr(sin(akjl)) ) / bjl;
662 c = -std::sqrt( sqr(bij) -
663 ( sqr(pijk) - 2*pijk*pijl*cos(akjl) + sqr(pijl) )
665 / ( bjk*bjl*sin(akjl) );
680 fprintf(debug, "params for vsite3out %d: %g %g %g\n",
681 param->AI+1, param->C0, param->C1, param->C2);
686 static gmx_bool calc_vsite4fd_param(t_param *param,
687 int nrbond, t_mybonded *bonds,
688 int nrang, t_mybonded *angles)
690 /* i = virtual site | ,k
691 * j = 1st bonded heavy atom | i-j-m
692 * k,l,m = 2nd bonded atoms | `l
696 real bij, bjk, bjl, bjm, aijk, aijl, aijm, akjm, akjl;
697 real pk, pl, pm, cosakl, cosakm, sinakl, sinakm, cl, cm;
699 bij = get_bond_length(nrbond, bonds, param->AI, param->AJ);
700 bjk = get_bond_length(nrbond, bonds, param->AJ, param->AK);
701 bjl = get_bond_length(nrbond, bonds, param->AJ, param->AL);
702 bjm = get_bond_length(nrbond, bonds, param->AJ, param->AM);
703 aijk = get_angle (nrang, angles, param->AI, param->AJ, param->AK);
704 aijl = get_angle (nrang, angles, param->AI, param->AJ, param->AL);
705 aijm = get_angle (nrang, angles, param->AI, param->AJ, param->AM);
706 akjm = get_angle (nrang, angles, param->AK, param->AJ, param->AM);
707 akjl = get_angle (nrang, angles, param->AK, param->AJ, param->AL);
708 bError = (bij == NOTSET) || (bjk == NOTSET) || (bjl == NOTSET) || (bjm == NOTSET) ||
709 (aijk == NOTSET) || (aijl == NOTSET) || (aijm == NOTSET) || (akjm == NOTSET) ||
717 cosakl = (cos(akjl) - cos(aijk)*cos(aijl)) / (sin(aijk)*sin(aijl));
718 cosakm = (cos(akjm) - cos(aijk)*cos(aijm)) / (sin(aijk)*sin(aijm));
719 if (cosakl < -1 || cosakl > 1 || cosakm < -1 || cosakm > 1)
721 fprintf(stderr, "virtual site %d: angle ijk = %f, angle ijl = %f, angle ijm = %f\n",
722 param->AI+1, RAD2DEG*aijk, RAD2DEG*aijl, RAD2DEG*aijm);
723 gmx_fatal(FARGS, "invalid construction in calc_vsite4fd for atom %d: "
724 "cosakl=%f, cosakm=%f\n", param->AI+1, cosakl, cosakm);
726 sinakl = std::sqrt(1-sqr(cosakl));
727 sinakm = std::sqrt(1-sqr(cosakm));
729 /* note: there is a '+' because of the way the sines are calculated */
730 cl = -pk / ( pl*cosakl - pk + pl*sinakl*(pm*cosakm-pk)/(pm*sinakm) );
731 cm = -pk / ( pm*cosakm - pk + pm*sinakm*(pl*cosakl-pk)/(pl*sinakl) );
738 fprintf(debug, "params for vsite4fd %d: %g %g %g\n",
739 param->AI+1, param->C0, param->C1, param->C2);
748 calc_vsite4fdn_param(t_param *param,
749 int nrbond, t_mybonded *bonds,
750 int nrang, t_mybonded *angles)
752 /* i = virtual site | ,k
753 * j = 1st bonded heavy atom | i-j-m
754 * k,l,m = 2nd bonded atoms | `l
758 real bij, bjk, bjl, bjm, aijk, aijl, aijm;
759 real pk, pl, pm, a, b;
761 bij = get_bond_length(nrbond, bonds, param->AI, param->AJ);
762 bjk = get_bond_length(nrbond, bonds, param->AJ, param->AK);
763 bjl = get_bond_length(nrbond, bonds, param->AJ, param->AL);
764 bjm = get_bond_length(nrbond, bonds, param->AJ, param->AM);
765 aijk = get_angle (nrang, angles, param->AI, param->AJ, param->AK);
766 aijl = get_angle (nrang, angles, param->AI, param->AJ, param->AL);
767 aijm = get_angle (nrang, angles, param->AI, param->AJ, param->AM);
769 bError = (bij == NOTSET) || (bjk == NOTSET) || (bjl == NOTSET) || (bjm == NOTSET) ||
770 (aijk == NOTSET) || (aijl == NOTSET) || (aijm == NOTSET);
775 /* Calculate component of bond j-k along the direction i-j */
778 /* Calculate component of bond j-l along the direction i-j */
781 /* Calculate component of bond j-m along the direction i-j */
784 if (fabs(pl) < 1000*GMX_REAL_MIN || fabs(pm) < 1000*GMX_REAL_MIN)
786 fprintf(stderr, "virtual site %d: angle ijk = %f, angle ijl = %f, angle ijm = %f\n",
787 param->AI+1, RAD2DEG*aijk, RAD2DEG*aijl, RAD2DEG*aijm);
788 gmx_fatal(FARGS, "invalid construction in calc_vsite4fdn for atom %d: "
789 "pl=%f, pm=%f\n", param->AI+1, pl, pm);
801 fprintf(debug, "params for vsite4fdn %d: %g %g %g\n",
802 param->AI+1, param->C0, param->C1, param->C2);
811 int set_vsites(gmx_bool bVerbose, t_atoms *atoms, gpp_atomtype_t atype,
815 int nvsite, nrbond, nrang, nridih, nrset;
816 gmx_bool bFirst, bSet, bERROR;
817 at2vsitebond_t *at2vb;
826 fprintf(debug, "\nCalculating parameters for virtual sites\n");
829 /* Make a reverse list to avoid ninteractions^2 operations */
830 at2vb = make_at2vsitebond(atoms->nr, plist);
832 for (ftype = 0; (ftype < F_NRE); ftype++)
834 if (interaction_function[ftype].flags & IF_VSITE)
836 nvsite += plist[ftype].nr;
838 if (ftype == F_VSITEN)
840 /* We don't calculate parameters for VSITEN */
845 for (i = 0; (i < plist[ftype].nr); i++)
847 /* check if all parameters are set */
849 for (j = 0; j < NRFP(ftype) && bSet; j++)
851 bSet = plist[ftype].param[i].c[j] != NOTSET;
856 fprintf(debug, "bSet=%s ", bool_names[bSet]);
857 print_param(debug, ftype, i, &plist[ftype].param[i]);
861 if (bVerbose && bFirst)
863 fprintf(stderr, "Calculating parameters for virtual sites\n");
867 nrbond = nrang = nridih = 0;
872 /* now set the vsite parameters: */
873 get_bondeds(NRAL(ftype), plist[ftype].param[i].a, at2vb,
874 &nrbond, &bonds, &nrang, &angles, &nridih, &idihs);
877 fprintf(debug, "Found %d bonds, %d angles and %d idihs "
878 "for virtual site %d (%s)\n", nrbond, nrang, nridih,
879 plist[ftype].param[i].AI+1,
880 interaction_function[ftype].longname);
881 print_bad(debug, nrbond, bonds, nrang, angles, nridih, idihs);
887 calc_vsite3_param(atype, &(plist[ftype].param[i]), atoms,
888 nrbond, bonds, nrang, angles);
892 calc_vsite3fd_param(&(plist[ftype].param[i]),
893 nrbond, bonds, nrang, angles);
897 calc_vsite3fad_param(&(plist[ftype].param[i]),
898 nrbond, bonds, nrang, angles);
902 calc_vsite3out_param(atype, &(plist[ftype].param[i]), atoms,
903 nrbond, bonds, nrang, angles);
907 calc_vsite4fd_param(&(plist[ftype].param[i]),
908 nrbond, bonds, nrang, angles);
912 calc_vsite4fdn_param(&(plist[ftype].param[i]),
913 nrbond, bonds, nrang, angles);
916 gmx_fatal(FARGS, "Automatic parameter generation not supported "
918 interaction_function[ftype].longname,
919 plist[ftype].param[i].AI+1);
924 gmx_fatal(FARGS, "Automatic parameter generation not supported "
925 "for %s atom %d for this bonding configuration",
926 interaction_function[ftype].longname,
927 plist[ftype].param[i].AI+1);
934 if (debug && plist[ftype].nr)
936 fprintf(stderr, "Calculated parameters for %d out of %d %s atoms\n",
937 nrset, plist[ftype].nr, interaction_function[ftype].longname);
942 done_at2vsitebond(atoms->nr, at2vb);
947 void set_vsites_ptype(gmx_bool bVerbose, gmx_moltype_t *molt)
956 fprintf(stderr, "Setting particle type to V for virtual sites\n");
960 fprintf(stderr, "checking %d functypes\n", F_NRE);
962 for (ftype = 0; ftype < F_NRE; ftype++)
964 il = &molt->ilist[ftype];
965 if (interaction_function[ftype].flags & IF_VSITE)
967 nra = interaction_function[ftype].nratoms;
973 fprintf(stderr, "doing %d %s virtual sites\n",
974 (nrd / (nra+1)), interaction_function[ftype].longname);
977 for (i = 0; (i < nrd); )
979 /* The virtual site */
981 molt->atoms.atom[avsite].ptype = eptVSite;
995 static void check_vsite_constraints(t_params *plist,
996 int cftype, int vsite_type[])
1003 ps = &(plist[cftype]);
1004 for (i = 0; (i < ps->nr); i++)
1006 for (k = 0; k < 2; k++)
1008 atom = ps->param[i].a[k];
1009 if (vsite_type[atom] != NOTSET)
1011 fprintf(stderr, "ERROR: Cannot have constraint (%d-%d) with virtual site (%d)\n",
1012 ps->param[i].AI+1, ps->param[i].AJ+1, atom+1);
1019 gmx_fatal(FARGS, "There were %d virtual sites involved in constraints", n);
1023 static void clean_vsite_bonds(t_params *plist, t_pindex pindex[],
1024 int cftype, int vsite_type[])
1026 int ftype, i, j, k, m, n, nvsite, nOut, kept_i;
1027 int nconverted, nremoved;
1028 atom_id atom, oatom, at1, at2;
1029 gmx_bool bKeep, bRemove, bUsed, bPresent, bThisFD, bThisOUT, bAllFD, bFirstTwo;
1032 if (cftype == F_CONNBONDS)
1037 ps = &(plist[cftype]);
1042 for (i = 0; (i < ps->nr); i++) /* for all bonds in the plist */
1045 const atom_id *first_atoms = NULL;
1050 /* check if all virtual sites are constructed from the same atoms */
1054 fprintf(debug, "constr %d %d:", ps->param[i].AI+1, ps->param[i].AJ+1);
1056 for (k = 0; (k < 2) && !bKeep && !bRemove; k++)
1058 /* for all atoms in the bond */
1059 atom = ps->param[i].a[k];
1060 if (vsite_type[atom] != NOTSET && vsite_type[atom] != F_VSITEN)
1063 bThisFD = ( (pindex[atom].ftype == F_VSITE3FD ) ||
1064 (pindex[atom].ftype == F_VSITE3FAD) ||
1065 (pindex[atom].ftype == F_VSITE4FD ) ||
1066 (pindex[atom].ftype == F_VSITE4FDN ) );
1067 bThisOUT = ( (pindex[atom].ftype == F_VSITE3OUT) &&
1068 (interaction_function[cftype].flags & IF_CONSTRAINT) );
1069 bAllFD = bAllFD && bThisFD;
1070 if (bThisFD || bThisOUT)
1074 fprintf(debug, " %s", bThisOUT ? "out" : "fd");
1076 oatom = ps->param[i].a[1-k]; /* the other atom */
1077 if (vsite_type[oatom] == NOTSET &&
1078 vsite_type[oatom] != F_VSITEN &&
1079 oatom == plist[pindex[atom].ftype].param[pindex[atom].parnr].AJ)
1081 /* if the other atom isn't a vsite, and it is AI */
1089 fprintf(debug, " D-AI");
1095 /* TODO This fragment, and corresponding logic in
1096 clean_vsite_angles and clean_vsite_dihs should
1097 be refactored into a common function */
1100 /* if this is the first vsite we encounter then
1101 store construction atoms */
1102 /* TODO This would be nicer to implement with
1103 a C++ "vector view" class" with an
1104 STL-container-like interface. */
1105 vsnral = NRAL(pindex[atom].ftype) - 1;
1106 first_atoms = plist[pindex[atom].ftype].param[pindex[atom].parnr].a + 1;
1110 GMX_ASSERT(vsnral != 0, "nvsite > 1 must have vsnral != 0");
1111 GMX_ASSERT(first_atoms != NULL, "nvsite > 1 must have first_atoms != NULL");
1112 /* if it is not the first then
1113 check if this vsite is constructed from the same atoms */
1114 if (vsnral == NRAL(pindex[atom].ftype)-1)
1116 for (m = 0; (m < vsnral) && !bKeep; m++)
1118 const atom_id *atoms;
1121 atoms = plist[pindex[atom].ftype].param[pindex[atom].parnr].a + 1;
1122 for (n = 0; (n < vsnral) && !bPresent; n++)
1124 if (atoms[m] == first_atoms[n])
1134 fprintf(debug, " !present");
1144 fprintf(debug, " !same#at");
1158 /* if we have no virtual sites in this bond, keep it */
1163 fprintf(debug, " no vsite");
1168 /* TODO This loop and the corresponding loop in
1169 check_vsite_angles should be refactored into a common
1171 /* check if all non-vsite atoms are used in construction: */
1173 for (k = 0; (k < 2) && !bKeep; k++) /* for all atoms in the bond */
1175 atom = ps->param[i].a[k];
1176 if (vsite_type[atom] == NOTSET && vsite_type[atom] != F_VSITEN)
1179 for (m = 0; (m < vsnral) && !bUsed; m++)
1181 GMX_ASSERT(first_atoms != NULL, "If we've seen a vsite before, we know what its first atom index was");
1183 if (atom == first_atoms[m])
1186 bFirstTwo = bFirstTwo && m < 2;
1194 fprintf(debug, " !used");
1200 if (!( bAllFD && bFirstTwo ) )
1202 /* Two atom bonded interactions include constraints.
1203 * We need to remove constraints between vsite pairs that have
1204 * a fixed distance due to being constructed from the same
1205 * atoms, since this can be numerically unstable.
1207 for (m = 0; m < vsnral && !bKeep; m++) /* all constr. atoms */
1209 at1 = first_atoms[m];
1210 at2 = first_atoms[(m+1) % vsnral];
1212 for (ftype = 0; ftype < F_NRE; ftype++)
1214 if (interaction_function[ftype].flags & IF_CONSTRAINT)
1216 for (j = 0; (j < plist[ftype].nr) && !bPresent; j++)
1218 /* all constraints until one matches */
1219 bPresent = ( ( (plist[ftype].param[j].AI == at1) &&
1220 (plist[ftype].param[j].AJ == at2) ) ||
1221 ( (plist[ftype].param[j].AI == at2) &&
1222 (plist[ftype].param[j].AJ == at1) ) );
1231 fprintf(debug, " !bonded");
1242 fprintf(debug, " keeping");
1244 /* now copy the bond to the new array */
1245 ps->param[kept_i] = ps->param[i];
1248 else if (IS_CHEMBOND(cftype))
1250 srenew(plist[F_CONNBONDS].param, plist[F_CONNBONDS].nr+1);
1251 plist[F_CONNBONDS].param[plist[F_CONNBONDS].nr] = ps->param[i];
1252 plist[F_CONNBONDS].nr++;
1261 fprintf(debug, "\n");
1267 fprintf(stderr, "Removed %4d %15ss with virtual sites, %5d left\n",
1268 nremoved, interaction_function[cftype].longname, kept_i);
1272 fprintf(stderr, "Converted %4d %15ss with virtual sites to connections, %5d left\n",
1273 nconverted, interaction_function[cftype].longname, kept_i);
1277 fprintf(stderr, "Warning: removed %d %ss with vsite with %s construction\n"
1278 " This vsite construction does not guarantee constant "
1280 " If the constructions were generated by pdb2gmx ignore "
1282 nOut, interaction_function[cftype].longname,
1283 interaction_function[F_VSITE3OUT].longname );
1288 static void clean_vsite_angles(t_params *plist, t_pindex pindex[],
1289 int cftype, int vsite_type[],
1290 at2vsitecon_t *at2vc)
1292 int i, j, k, m, n, nvsite, kept_i;
1293 atom_id atom, at1, at2;
1294 gmx_bool bKeep, bUsed, bPresent, bAll3FAD, bFirstTwo;
1297 ps = &(plist[cftype]);
1299 for (i = 0; (i < ps->nr); i++) /* for all angles in the plist */
1302 const atom_id *first_atoms = NULL;
1306 /* check if all virtual sites are constructed from the same atoms */
1308 for (k = 0; (k < 3) && !bKeep; k++) /* for all atoms in the angle */
1310 atom = ps->param[i].a[k];
1311 if (vsite_type[atom] != NOTSET && vsite_type[atom] != F_VSITEN)
1314 bAll3FAD = bAll3FAD && (pindex[atom].ftype == F_VSITE3FAD);
1317 /* store construction atoms of first vsite */
1318 vsnral = NRAL(pindex[atom].ftype) - 1;
1319 first_atoms = plist[pindex[atom].ftype].param[pindex[atom].parnr].a + 1;
1323 GMX_ASSERT(vsnral != 0, "If we've seen a vsite before, we know how many constructing atoms it had");
1324 GMX_ASSERT(first_atoms != NULL, "If we've seen a vsite before, we know what its first atom index was");
1325 /* check if this vsite is constructed from the same atoms */
1326 if (vsnral == NRAL(pindex[atom].ftype)-1)
1328 for (m = 0; (m < vsnral) && !bKeep; m++)
1330 const atom_id *atoms;
1333 atoms = plist[pindex[atom].ftype].param[pindex[atom].parnr].a + 1;
1334 for (n = 0; (n < vsnral) && !bPresent; n++)
1336 if (atoms[m] == first_atoms[n])
1355 /* keep all angles with no virtual sites in them or
1356 with virtual sites with more than 3 constr. atoms */
1357 if (nvsite == 0 && vsnral > 3)
1362 /* check if all non-vsite atoms are used in construction: */
1364 for (k = 0; (k < 3) && !bKeep; k++) /* for all atoms in the angle */
1366 atom = ps->param[i].a[k];
1367 if (vsite_type[atom] == NOTSET && vsite_type[atom] != F_VSITEN)
1370 for (m = 0; (m < vsnral) && !bUsed; m++)
1372 GMX_ASSERT(first_atoms != NULL, "If we've seen a vsite before, we know what its first atom index was");
1374 if (atom == first_atoms[m])
1377 bFirstTwo = bFirstTwo && m < 2;
1387 if (!( bAll3FAD && bFirstTwo ) )
1389 /* check if all constructing atoms are constrained together */
1390 for (m = 0; m < vsnral && !bKeep; m++) /* all constr. atoms */
1392 at1 = first_atoms[m];
1393 at2 = first_atoms[(m+1) % vsnral];
1395 for (j = 0; j < at2vc[at1].nr; j++)
1397 if (at2vc[at1].aj[j] == at2)
1411 /* now copy the angle to the new array */
1412 ps->param[kept_i] = ps->param[i];
1417 if (ps->nr != kept_i)
1419 fprintf(stderr, "Removed %4d %15ss with virtual sites, %5d left\n",
1420 ps->nr-kept_i, interaction_function[cftype].longname, kept_i);
1425 static void clean_vsite_dihs(t_params *plist, t_pindex pindex[],
1426 int cftype, int vsite_type[])
1431 ps = &(plist[cftype]);
1434 for (i = 0; (i < ps->nr); i++) /* for all dihedrals in the plist */
1436 int k, m, n, nvsite;
1438 const atom_id *first_atoms = NULL;
1440 gmx_bool bKeep, bUsed, bPresent;
1444 /* check if all virtual sites are constructed from the same atoms */
1446 for (k = 0; (k < 4) && !bKeep; k++) /* for all atoms in the dihedral */
1448 atom = ps->param[i].a[k];
1449 if (vsite_type[atom] != NOTSET && vsite_type[atom] != F_VSITEN)
1453 /* store construction atoms of first vsite */
1454 vsnral = NRAL(pindex[atom].ftype) - 1;
1455 first_atoms = plist[pindex[atom].ftype].param[pindex[atom].parnr].a + 1;
1458 fprintf(debug, "dih w. vsite: %d %d %d %d\n",
1459 ps->param[i].AI+1, ps->param[i].AJ+1,
1460 ps->param[i].AK+1, ps->param[i].AL+1);
1461 fprintf(debug, "vsite %d from: %d %d %d\n",
1462 atom+1, first_atoms[0]+1, first_atoms[1]+1, first_atoms[2]+1);
1467 GMX_ASSERT(vsnral != 0, "If we've seen a vsite before, we know how many constructing atoms it had");
1468 GMX_ASSERT(first_atoms != NULL, "If we've seen a vsite before, we know what its first atom index was");
1469 /* check if this vsite is constructed from the same atoms */
1470 if (vsnral == NRAL(pindex[atom].ftype)-1)
1472 for (m = 0; (m < vsnral) && !bKeep; m++)
1474 const atom_id *atoms;
1477 atoms = plist[pindex[atom].ftype].param[pindex[atom].parnr].a + 1;
1478 for (n = 0; (n < vsnral) && !bPresent; n++)
1480 if (atoms[m] == first_atoms[n])
1492 /* TODO clean_site_bonds and _angles do this increment
1493 at the top of the loop. Refactor this for
1499 /* keep all dihedrals with no virtual sites in them */
1505 /* check if all atoms in dihedral are either virtual sites, or used in
1506 construction of virtual sites. If so, keep it, if not throw away: */
1507 for (k = 0; (k < 4) && !bKeep; k++) /* for all atoms in the dihedral */
1509 GMX_ASSERT(vsnral != 0, "If we've seen a vsite before, we know how many constructing atoms it had");
1510 GMX_ASSERT(first_atoms != NULL, "If we've seen a vsite before, we know what its first atom index was");
1511 atom = ps->param[i].a[k];
1512 if (vsite_type[atom] == NOTSET && vsite_type[atom] != F_VSITEN)
1514 /* vsnral will be set here, we don't get here with nvsite==0 */
1516 for (m = 0; (m < vsnral) && !bUsed; m++)
1518 if (atom == first_atoms[m])
1528 fprintf(debug, "unused atom in dih: %d\n", atom+1);
1536 ps->param[kept_i] = ps->param[i];
1541 if (ps->nr != kept_i)
1543 fprintf(stderr, "Removed %4d %15ss with virtual sites, %5d left\n",
1544 ps->nr-kept_i, interaction_function[cftype].longname, kept_i);
1549 void clean_vsite_bondeds(t_params *plist, int natoms, gmx_bool bRmVSiteBds)
1551 int i, k, nvsite, ftype, vsite, parnr;
1554 at2vsitecon_t *at2vc;
1556 pindex = 0; /* avoid warnings */
1557 /* make vsite_type array */
1558 snew(vsite_type, natoms);
1559 for (i = 0; i < natoms; i++)
1561 vsite_type[i] = NOTSET;
1564 for (ftype = 0; ftype < F_NRE; ftype++)
1566 if (interaction_function[ftype].flags & IF_VSITE)
1568 nvsite += plist[ftype].nr;
1570 while (i < plist[ftype].nr)
1572 vsite = plist[ftype].param[i].AI;
1573 if (vsite_type[vsite] == NOTSET)
1575 vsite_type[vsite] = ftype;
1579 gmx_fatal(FARGS, "multiple vsite constructions for atom %d", vsite+1);
1581 if (ftype == F_VSITEN)
1583 while (i < plist[ftype].nr && plist[ftype].param[i].AI == vsite)
1596 /* the rest only if we have virtual sites: */
1599 fprintf(stderr, "Cleaning up constraints %swith virtual sites\n",
1600 bRmVSiteBds ? "and constant bonded interactions " : "");
1602 /* Make a reverse list to avoid ninteractions^2 operations */
1603 at2vc = make_at2vsitecon(natoms, plist);
1605 snew(pindex, natoms);
1606 for (ftype = 0; ftype < F_NRE; ftype++)
1608 /* Here we skip VSITEN. In neary all practical use cases this
1609 * is not an issue, since VSITEN is intended for constructing
1610 * additional interaction sites, not for replacing normal atoms
1611 * with bonded interactions. Thus we do not expect constant
1612 * bonded interactions. If VSITEN does get used with constant
1613 * bonded interactions, these are not removed which only leads
1614 * to very minor extra computation and constant energy.
1615 * The only problematic case is onstraints between VSITEN
1616 * constructions with fixed distance (which is anyhow useless).
1617 * This will generate a fatal error in check_vsite_constraints.
1619 if ((interaction_function[ftype].flags & IF_VSITE) &&
1622 for (parnr = 0; (parnr < plist[ftype].nr); parnr++)
1624 k = plist[ftype].param[parnr].AI;
1625 pindex[k].ftype = ftype;
1626 pindex[k].parnr = parnr;
1633 for (i = 0; i < natoms; i++)
1635 fprintf(debug, "atom %d vsite_type %s\n", i,
1636 vsite_type[i] == NOTSET ? "NOTSET" :
1637 interaction_function[vsite_type[i]].name);
1641 /* remove interactions that include virtual sites */
1642 for (ftype = 0; ftype < F_NRE; ftype++)
1644 if ( ( ( interaction_function[ftype].flags & IF_BOND ) && bRmVSiteBds ) ||
1645 ( interaction_function[ftype].flags & IF_CONSTRAINT ) )
1647 if (interaction_function[ftype].flags & (IF_BTYPE | IF_CONSTRAINT) )
1649 clean_vsite_bonds (plist, pindex, ftype, vsite_type);
1651 else if (interaction_function[ftype].flags & IF_ATYPE)
1653 clean_vsite_angles(plist, pindex, ftype, vsite_type, at2vc);
1655 else if ( (ftype == F_PDIHS) || (ftype == F_IDIHS) )
1657 clean_vsite_dihs (plist, pindex, ftype, vsite_type);
1661 /* check that no remaining constraints include virtual sites */
1662 for (ftype = 0; ftype < F_NRE; ftype++)
1664 if (interaction_function[ftype].flags & IF_CONSTRAINT)
1666 check_vsite_constraints(plist, ftype, vsite_type);
1670 done_at2vsitecon(natoms, at2vc);