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, 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.
46 #include "vsite_parm.h"
47 #include "gromacs/utility/smalloc.h"
50 #include "gromacs/math/vec.h"
52 #include "gromacs/math/units.h"
53 #include "gromacs/legacyheaders/names.h"
54 #include "gromacs/utility/fatalerror.h"
55 #include "gromacs/utility/cstringutil.h"
56 #include "gromacs/legacyheaders/macros.h"
71 vsitebondparam_t *vsbp;
79 static int vsite_bond_nrcheck(int ftype)
83 if ((interaction_function[ftype].flags & (IF_BTYPE | IF_CONSTRAINT | IF_ATYPE)) || (ftype == F_IDIHS))
85 nrcheck = NRAL(ftype);
95 static void enter_bonded(int nratoms, int *nrbonded, t_mybonded **bondeds,
100 srenew(*bondeds, *nrbonded+1);
102 /* copy atom numbers */
103 for (j = 0; j < nratoms; j++)
105 (*bondeds)[*nrbonded].a[j] = param->a[j];
108 (*bondeds)[*nrbonded].c = param->C0;
113 static void get_bondeds(int nrat, t_iatom atoms[],
114 at2vsitebond_t *at2vb,
115 int *nrbond, t_mybonded **bonds,
116 int *nrang, t_mybonded **angles,
117 int *nridih, t_mybonded **idihs )
119 int k, i, ftype, nrcheck;
122 for (k = 0; k < nrat; k++)
124 for (i = 0; i < at2vb[atoms[k]].nr; i++)
126 ftype = at2vb[atoms[k]].vsbp[i].ftype;
127 param = at2vb[atoms[k]].vsbp[i].param;
128 nrcheck = vsite_bond_nrcheck(ftype);
129 /* abuse nrcheck to see if we're adding bond, angle or idih */
132 case 2: enter_bonded(nrcheck, nrbond, bonds, param); break;
133 case 3: enter_bonded(nrcheck, nrang, angles, param); break;
134 case 4: enter_bonded(nrcheck, nridih, idihs, param); break;
140 static at2vsitebond_t *make_at2vsitebond(int natoms, t_params plist[])
143 int ftype, i, j, nrcheck, nr;
145 at2vsitebond_t *at2vb;
150 for (ftype = 0; (ftype < F_NRE); ftype++)
152 if ((interaction_function[ftype].flags & IF_VSITE) && ftype != F_VSITEN)
154 for (i = 0; (i < plist[ftype].nr); i++)
156 for (j = 0; j < NRAL(ftype); j++)
158 bVSI[plist[ftype].param[i].a[j]] = TRUE;
164 for (ftype = 0; (ftype < F_NRE); ftype++)
166 nrcheck = vsite_bond_nrcheck(ftype);
169 for (i = 0; (i < plist[ftype].nr); i++)
171 aa = plist[ftype].param[i].a;
172 for (j = 0; j < nrcheck; j++)
176 nr = at2vb[aa[j]].nr;
179 srenew(at2vb[aa[j]].vsbp, nr+10);
181 at2vb[aa[j]].vsbp[nr].ftype = ftype;
182 at2vb[aa[j]].vsbp[nr].param = &plist[ftype].param[i];
194 static void done_at2vsitebond(int natoms, at2vsitebond_t *at2vb)
198 for (i = 0; i < natoms; i++)
202 sfree(at2vb[i].vsbp);
208 static at2vsitecon_t *make_at2vsitecon(int natoms, t_params plist[])
211 int ftype, i, j, ai, aj, nr;
212 at2vsitecon_t *at2vc;
217 for (ftype = 0; (ftype < F_NRE); ftype++)
219 if ((interaction_function[ftype].flags & IF_VSITE) && ftype != F_VSITEN)
221 for (i = 0; (i < plist[ftype].nr); i++)
223 for (j = 0; j < NRAL(ftype); j++)
225 bVSI[plist[ftype].param[i].a[j]] = TRUE;
231 for (ftype = 0; (ftype < F_NRE); ftype++)
233 if (interaction_function[ftype].flags & IF_CONSTRAINT)
235 for (i = 0; (i < plist[ftype].nr); i++)
237 ai = plist[ftype].param[i].AI;
238 aj = plist[ftype].param[i].AJ;
239 if (bVSI[ai] && bVSI[aj])
241 /* Store forward direction */
245 srenew(at2vc[ai].aj, nr+10);
247 at2vc[ai].aj[nr] = aj;
249 /* Store backward direction */
253 srenew(at2vc[aj].aj, nr+10);
255 at2vc[aj].aj[nr] = ai;
266 static void done_at2vsitecon(int natoms, at2vsitecon_t *at2vc)
270 for (i = 0; i < natoms; i++)
281 static void print_bad(FILE *fp,
282 int nrbond, t_mybonded *bonds,
283 int nrang, t_mybonded *angles,
284 int nridih, t_mybonded *idihs )
290 fprintf(fp, "bonds:");
291 for (i = 0; i < nrbond; i++)
293 fprintf(fp, " %u-%u (%g)",
294 bonds[i].AI+1, bonds[i].AJ+1, bonds[i].c);
300 fprintf(fp, "angles:");
301 for (i = 0; i < nrang; i++)
303 fprintf(fp, " %u-%u-%u (%g)",
304 angles[i].AI+1, angles[i].AJ+1,
305 angles[i].AK+1, angles[i].c);
311 fprintf(fp, "idihs:");
312 for (i = 0; i < nridih; i++)
314 fprintf(fp, " %u-%u-%u-%u (%g)",
315 idihs[i].AI+1, idihs[i].AJ+1,
316 idihs[i].AK+1, idihs[i].AL+1, idihs[i].c);
322 static void print_param(FILE *fp, int ftype, int i, t_param *param)
325 static int prev_ftype = NOTSET;
326 static int prev_i = NOTSET;
329 if ( (ftype != prev_ftype) || (i != prev_i) )
335 fprintf(fp, "(%d) plist[%s].param[%d]",
336 pass, interaction_function[ftype].name, i);
337 for (j = 0; j < NRFP(ftype); j++)
339 fprintf(fp, ".c[%d]=%g ", j, param->c[j]);
345 static real get_bond_length(int nrbond, t_mybonded bonds[],
346 t_iatom ai, t_iatom aj)
352 for (i = 0; i < nrbond && (bondlen == NOTSET); i++)
354 /* check both ways */
355 if ( ( (ai == bonds[i].AI) && (aj == bonds[i].AJ) ) ||
356 ( (ai == bonds[i].AJ) && (aj == bonds[i].AI) ) )
358 bondlen = bonds[i].c; /* note: bonds[i].c might be NOTSET */
364 static real get_angle(int nrang, t_mybonded angles[],
365 t_iatom ai, t_iatom aj, t_iatom ak)
371 for (i = 0; i < nrang && (angle == NOTSET); i++)
373 /* check both ways */
374 if ( ( (ai == angles[i].AI) && (aj == angles[i].AJ) && (ak == angles[i].AK) ) ||
375 ( (ai == angles[i].AK) && (aj == angles[i].AJ) && (ak == angles[i].AI) ) )
377 angle = DEG2RAD*angles[i].c;
383 static char *get_atomtype_name_AB(t_atom *atom, gpp_atomtype_t atype)
387 name = get_atomtype_name(atom->type, atype);
389 /* When using the decoupling option, atom types are changed
390 * to decoupled for the non-bonded interactions, but the virtual
391 * sites constructions should be based on the "normal" interactions.
392 * So we return the state B atom type name if the state A atom
393 * type is the decoupled one. We should actually check for the atom
394 * type number, but that's not passed here. So we check for
395 * the decoupled atom type name. This should not cause trouble
396 * as this code is only used for topologies with v-sites without
397 * parameters generated by pdb2gmx.
399 if (strcmp(name, "decoupled") == 0)
401 name = get_atomtype_name(atom->typeB, atype);
407 static gmx_bool calc_vsite3_param(gpp_atomtype_t atype,
408 t_param *param, t_atoms *at,
409 int nrbond, t_mybonded *bonds,
410 int nrang, t_mybonded *angles )
412 /* i = virtual site | ,k
413 * j = 1st bonded heavy atom | i-j
414 * k,l = 2nd bonded atoms | `l
417 gmx_bool bXH3, bError;
418 real bjk, bjl, a = -1, b = -1;
419 /* check if this is part of a NH3 , NH2-umbrella or CH3 group,
420 * i.e. if atom k and l are dummy masses (MNH* or MCH3*) */
424 for (i = 0; i < 4; i++)
426 fprintf(debug, "atom %u type %s ",
428 get_atomtype_name_AB(&at->atom[param->a[i]], atype));
430 fprintf(debug, "\n");
433 ( (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AK], atype), "MNH", 3) == 0) &&
434 (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AL], atype), "MNH", 3) == 0) ) ||
435 ( (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AK], atype), "MCH3", 4) == 0) &&
436 (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AL], atype), "MCH3", 4) == 0) );
438 bjk = get_bond_length(nrbond, bonds, param->AJ, param->AK);
439 bjl = get_bond_length(nrbond, bonds, param->AJ, param->AL);
440 bError = (bjk == NOTSET) || (bjl == NOTSET);
443 /* now we get some XH2/XH3 group specific construction */
444 /* note: we call the heavy atom 'C' and the X atom 'N' */
445 real bMM, bCM, bCN, bNH, aCNH, dH, rH, dM, rM;
448 /* check if bonds from heavy atom (j) to dummy masses (k,l) are equal: */
449 bError = bError || (bjk != bjl);
451 /* the X atom (C or N) in the XH2/XH3 group is the first after the masses: */
452 aN = max(param->AK, param->AL)+1;
454 /* get common bonds */
455 bMM = get_bond_length(nrbond, bonds, param->AK, param->AL);
457 bCN = get_bond_length(nrbond, bonds, param->AJ, aN);
458 bError = bError || (bMM == NOTSET) || (bCN == NOTSET);
460 /* calculate common things */
462 dM = sqrt( sqr(bCM) - sqr(rM) );
464 /* are we dealing with the X atom? */
467 /* this is trivial */
468 a = b = 0.5 * bCN/dM;
473 /* get other bondlengths and angles: */
474 bNH = get_bond_length(nrbond, bonds, aN, param->AI);
475 aCNH = get_angle (nrang, angles, param->AJ, aN, param->AI);
476 bError = bError || (bNH == NOTSET) || (aCNH == NOTSET);
479 dH = bCN - bNH * cos(aCNH);
480 rH = bNH * sin(aCNH);
482 a = 0.5 * ( dH/dM + rH/rM );
483 b = 0.5 * ( dH/dM - rH/rM );
488 gmx_fatal(FARGS, "calc_vsite3_param not implemented for the general case "
489 "(atom %d)", param->AI+1);
497 fprintf(debug, "params for vsite3 %u: %g %g\n",
498 param->AI+1, param->C0, param->C1);
504 static gmx_bool calc_vsite3fd_param(t_param *param,
505 int nrbond, t_mybonded *bonds,
506 int nrang, t_mybonded *angles)
508 /* i = virtual site | ,k
509 * j = 1st bonded heavy atom | i-j
510 * k,l = 2nd bonded atoms | `l
514 real bij, bjk, bjl, aijk, aijl, rk, rl;
516 bij = get_bond_length(nrbond, bonds, param->AI, param->AJ);
517 bjk = get_bond_length(nrbond, bonds, param->AJ, param->AK);
518 bjl = get_bond_length(nrbond, bonds, param->AJ, param->AL);
519 aijk = get_angle (nrang, angles, param->AI, param->AJ, param->AK);
520 aijl = get_angle (nrang, angles, param->AI, param->AJ, param->AL);
521 bError = (bij == NOTSET) || (bjk == NOTSET) || (bjl == NOTSET) ||
522 (aijk == NOTSET) || (aijl == NOTSET);
524 rk = bjk * sin(aijk);
525 rl = bjl * sin(aijl);
526 param->C0 = rk / (rk + rl);
527 param->C1 = -bij; /* 'bond'-length for fixed distance vsite */
531 fprintf(debug, "params for vsite3fd %u: %g %g\n",
532 param->AI+1, param->C0, param->C1);
537 static gmx_bool calc_vsite3fad_param(t_param *param,
538 int nrbond, t_mybonded *bonds,
539 int nrang, t_mybonded *angles)
541 /* i = virtual site |
542 * j = 1st bonded heavy atom | i-j
543 * k = 2nd bonded heavy atom | `k-l
544 * l = 3d bonded heavy atom |
547 gmx_bool bSwapParity, bError;
550 bSwapParity = ( param->C1 == -1 );
552 bij = get_bond_length(nrbond, bonds, param->AI, param->AJ);
553 aijk = get_angle (nrang, angles, param->AI, param->AJ, param->AK);
554 bError = (bij == NOTSET) || (aijk == NOTSET);
556 param->C1 = bij; /* 'bond'-length for fixed distance vsite */
557 param->C0 = RAD2DEG*aijk; /* 'bond'-angle for fixed angle vsite */
561 param->C0 = 360 - param->C0;
566 fprintf(debug, "params for vsite3fad %u: %g %g\n",
567 param->AI+1, param->C0, param->C1);
572 static gmx_bool calc_vsite3out_param(gpp_atomtype_t atype,
573 t_param *param, t_atoms *at,
574 int nrbond, t_mybonded *bonds,
575 int nrang, t_mybonded *angles)
577 /* i = virtual site | ,k
578 * j = 1st bonded heavy atom | i-j
579 * k,l = 2nd bonded atoms | `l
580 * NOTE: i is out of the j-k-l plane!
583 gmx_bool bXH3, bError, bSwapParity;
584 real bij, bjk, bjl, aijk, aijl, akjl, pijk, pijl, a, b, c;
586 /* check if this is part of a NH2-umbrella, NH3 or CH3 group,
587 * i.e. if atom k and l are dummy masses (MNH* or MCH3*) */
591 for (i = 0; i < 4; i++)
593 fprintf(debug, "atom %u type %s ",
594 param->a[i]+1, get_atomtype_name_AB(&at->atom[param->a[i]], atype));
596 fprintf(debug, "\n");
599 ( (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AK], atype), "MNH", 3) == 0) &&
600 (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AL], atype), "MNH", 3) == 0) ) ||
601 ( (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AK], atype), "MCH3", 4) == 0) &&
602 (gmx_strncasecmp(get_atomtype_name_AB(&at->atom[param->AL], atype), "MCH3", 4) == 0) );
604 /* check if construction parity must be swapped */
605 bSwapParity = ( param->C1 == -1 );
607 bjk = get_bond_length(nrbond, bonds, param->AJ, param->AK);
608 bjl = get_bond_length(nrbond, bonds, param->AJ, param->AL);
609 bError = (bjk == NOTSET) || (bjl == NOTSET);
612 /* now we get some XH3 group specific construction */
613 /* note: we call the heavy atom 'C' and the X atom 'N' */
614 real bMM, bCM, bCN, bNH, aCNH, dH, rH, rHx, rHy, dM, rM;
617 /* check if bonds from heavy atom (j) to dummy masses (k,l) are equal: */
618 bError = bError || (bjk != bjl);
620 /* the X atom (C or N) in the XH3 group is the first after the masses: */
621 aN = max(param->AK, param->AL)+1;
623 /* get all bondlengths and angles: */
624 bMM = get_bond_length(nrbond, bonds, param->AK, param->AL);
626 bCN = get_bond_length(nrbond, bonds, param->AJ, aN);
627 bNH = get_bond_length(nrbond, bonds, aN, param->AI);
628 aCNH = get_angle (nrang, angles, param->AJ, aN, param->AI);
630 (bMM == NOTSET) || (bCN == NOTSET) || (bNH == NOTSET) || (aCNH == NOTSET);
633 dH = bCN - bNH * cos(aCNH);
634 rH = bNH * sin(aCNH);
635 /* we assume the H's are symmetrically distributed */
636 rHx = rH*cos(DEG2RAD*30);
637 rHy = rH*sin(DEG2RAD*30);
639 dM = sqrt( sqr(bCM) - sqr(rM) );
640 a = 0.5*( (dH/dM) - (rHy/rM) );
641 b = 0.5*( (dH/dM) + (rHy/rM) );
647 /* this is the general construction */
649 bij = get_bond_length(nrbond, bonds, param->AI, param->AJ);
650 aijk = get_angle (nrang, angles, param->AI, param->AJ, param->AK);
651 aijl = get_angle (nrang, angles, param->AI, param->AJ, param->AL);
652 akjl = get_angle (nrang, angles, param->AK, param->AJ, param->AL);
654 (bij == NOTSET) || (aijk == NOTSET) || (aijl == NOTSET) || (akjl == NOTSET);
656 pijk = cos(aijk)*bij;
657 pijl = cos(aijl)*bij;
658 a = ( pijk + (pijk*cos(akjl)-pijl) * cos(akjl) / sqr(sin(akjl)) ) / bjk;
659 b = ( pijl + (pijl*cos(akjl)-pijk) * cos(akjl) / sqr(sin(akjl)) ) / bjl;
660 c = -sqrt( sqr(bij) -
661 ( sqr(pijk) - 2*pijk*pijl*cos(akjl) + sqr(pijl) )
663 / ( bjk*bjl*sin(akjl) );
678 fprintf(debug, "params for vsite3out %u: %g %g %g\n",
679 param->AI+1, param->C0, param->C1, param->C2);
684 static gmx_bool calc_vsite4fd_param(t_param *param,
685 int nrbond, t_mybonded *bonds,
686 int nrang, t_mybonded *angles)
688 /* i = virtual site | ,k
689 * j = 1st bonded heavy atom | i-j-m
690 * k,l,m = 2nd bonded atoms | `l
694 real bij, bjk, bjl, bjm, aijk, aijl, aijm, akjm, akjl;
695 real pk, pl, pm, cosakl, cosakm, sinakl, sinakm, cl, cm;
697 bij = get_bond_length(nrbond, bonds, param->AI, param->AJ);
698 bjk = get_bond_length(nrbond, bonds, param->AJ, param->AK);
699 bjl = get_bond_length(nrbond, bonds, param->AJ, param->AL);
700 bjm = get_bond_length(nrbond, bonds, param->AJ, param->AM);
701 aijk = get_angle (nrang, angles, param->AI, param->AJ, param->AK);
702 aijl = get_angle (nrang, angles, param->AI, param->AJ, param->AL);
703 aijm = get_angle (nrang, angles, param->AI, param->AJ, param->AM);
704 akjm = get_angle (nrang, angles, param->AK, param->AJ, param->AM);
705 akjl = get_angle (nrang, angles, param->AK, param->AJ, param->AL);
706 bError = (bij == NOTSET) || (bjk == NOTSET) || (bjl == NOTSET) || (bjm == NOTSET) ||
707 (aijk == NOTSET) || (aijl == NOTSET) || (aijm == NOTSET) || (akjm == NOTSET) ||
715 cosakl = (cos(akjl) - cos(aijk)*cos(aijl)) / (sin(aijk)*sin(aijl));
716 cosakm = (cos(akjm) - cos(aijk)*cos(aijm)) / (sin(aijk)*sin(aijm));
717 if (cosakl < -1 || cosakl > 1 || cosakm < -1 || cosakm > 1)
719 fprintf(stderr, "virtual site %d: angle ijk = %f, angle ijl = %f, angle ijm = %f\n",
720 param->AI+1, RAD2DEG*aijk, RAD2DEG*aijl, RAD2DEG*aijm);
721 gmx_fatal(FARGS, "invalid construction in calc_vsite4fd for atom %d: "
722 "cosakl=%f, cosakm=%f\n", param->AI+1, cosakl, cosakm);
724 sinakl = sqrt(1-sqr(cosakl));
725 sinakm = sqrt(1-sqr(cosakm));
727 /* note: there is a '+' because of the way the sines are calculated */
728 cl = -pk / ( pl*cosakl - pk + pl*sinakl*(pm*cosakm-pk)/(pm*sinakm) );
729 cm = -pk / ( pm*cosakm - pk + pm*sinakm*(pl*cosakl-pk)/(pl*sinakl) );
736 fprintf(debug, "params for vsite4fd %u: %g %g %g\n",
737 param->AI+1, param->C0, param->C1, param->C2);
746 calc_vsite4fdn_param(t_param *param,
747 int nrbond, t_mybonded *bonds,
748 int nrang, t_mybonded *angles)
750 /* i = virtual site | ,k
751 * j = 1st bonded heavy atom | i-j-m
752 * k,l,m = 2nd bonded atoms | `l
756 real bij, bjk, bjl, bjm, aijk, aijl, aijm;
757 real pk, pl, pm, a, b;
759 bij = get_bond_length(nrbond, bonds, param->AI, param->AJ);
760 bjk = get_bond_length(nrbond, bonds, param->AJ, param->AK);
761 bjl = get_bond_length(nrbond, bonds, param->AJ, param->AL);
762 bjm = get_bond_length(nrbond, bonds, param->AJ, param->AM);
763 aijk = get_angle (nrang, angles, param->AI, param->AJ, param->AK);
764 aijl = get_angle (nrang, angles, param->AI, param->AJ, param->AL);
765 aijm = get_angle (nrang, angles, param->AI, param->AJ, param->AM);
767 bError = (bij == NOTSET) || (bjk == NOTSET) || (bjl == NOTSET) || (bjm == NOTSET) ||
768 (aijk == NOTSET) || (aijl == NOTSET) || (aijm == NOTSET);
773 /* Calculate component of bond j-k along the direction i-j */
776 /* Calculate component of bond j-l along the direction i-j */
779 /* Calculate component of bond j-m along the direction i-j */
782 if (fabs(pl) < 1000*GMX_REAL_MIN || fabs(pm) < 1000*GMX_REAL_MIN)
784 fprintf(stderr, "virtual site %d: angle ijk = %f, angle ijl = %f, angle ijm = %f\n",
785 param->AI+1, RAD2DEG*aijk, RAD2DEG*aijl, RAD2DEG*aijm);
786 gmx_fatal(FARGS, "invalid construction in calc_vsite4fdn for atom %d: "
787 "pl=%f, pm=%f\n", param->AI+1, pl, pm);
799 fprintf(debug, "params for vsite4fdn %u: %g %g %g\n",
800 param->AI+1, param->C0, param->C1, param->C2);
809 int set_vsites(gmx_bool bVerbose, t_atoms *atoms, gpp_atomtype_t atype,
813 int nvsite, nrbond, nrang, nridih, nrset;
814 gmx_bool bFirst, bSet, bERROR;
815 at2vsitebond_t *at2vb;
825 fprintf(debug, "\nCalculating parameters for virtual sites\n");
828 /* Make a reverse list to avoid ninteractions^2 operations */
829 at2vb = make_at2vsitebond(atoms->nr, plist);
831 for (ftype = 0; (ftype < F_NRE); ftype++)
833 if ((interaction_function[ftype].flags & IF_VSITE) && ftype != F_VSITEN)
836 nvsite += plist[ftype].nr;
837 for (i = 0; (i < plist[ftype].nr); i++)
839 /* check if all parameters are set */
841 for (j = 0; j < NRFP(ftype) && bSet; j++)
843 bSet = plist[ftype].param[i].c[j] != NOTSET;
848 fprintf(debug, "bSet=%s ", bool_names[bSet]);
849 print_param(debug, ftype, i, &plist[ftype].param[i]);
853 if (bVerbose && bFirst)
855 fprintf(stderr, "Calculating parameters for virtual sites\n");
859 nrbond = nrang = nridih = 0;
864 /* now set the vsite parameters: */
865 get_bondeds(NRAL(ftype), plist[ftype].param[i].a, at2vb,
866 &nrbond, &bonds, &nrang, &angles, &nridih, &idihs);
869 fprintf(debug, "Found %d bonds, %d angles and %d idihs "
870 "for virtual site %u (%s)\n", nrbond, nrang, nridih,
871 plist[ftype].param[i].AI+1,
872 interaction_function[ftype].longname);
873 print_bad(debug, nrbond, bonds, nrang, angles, nridih, idihs);
879 calc_vsite3_param(atype, &(plist[ftype].param[i]), atoms,
880 nrbond, bonds, nrang, angles);
884 calc_vsite3fd_param(&(plist[ftype].param[i]),
885 nrbond, bonds, nrang, angles);
889 calc_vsite3fad_param(&(plist[ftype].param[i]),
890 nrbond, bonds, nrang, angles);
894 calc_vsite3out_param(atype, &(plist[ftype].param[i]), atoms,
895 nrbond, bonds, nrang, angles);
899 calc_vsite4fd_param(&(plist[ftype].param[i]),
900 nrbond, bonds, nrang, angles);
904 calc_vsite4fdn_param(&(plist[ftype].param[i]),
905 nrbond, bonds, nrang, angles);
908 gmx_fatal(FARGS, "Automatic parameter generation not supported "
910 interaction_function[ftype].longname,
911 plist[ftype].param[i].AI+1);
915 gmx_fatal(FARGS, "Automatic parameter generation not supported "
916 "for %s atom %d for this bonding configuration",
917 interaction_function[ftype].longname,
918 plist[ftype].param[i].AI+1);
925 if (debug && plist[ftype].nr)
927 fprintf(stderr, "Calculated parameters for %d out of %d %s atoms\n",
928 nrset, plist[ftype].nr, interaction_function[ftype].longname);
933 done_at2vsitebond(atoms->nr, at2vb);
938 void set_vsites_ptype(gmx_bool bVerbose, gmx_moltype_t *molt)
947 fprintf(stderr, "Setting particle type to V for virtual sites\n");
951 fprintf(stderr, "checking %d functypes\n", F_NRE);
953 for (ftype = 0; ftype < F_NRE; ftype++)
955 il = &molt->ilist[ftype];
956 if (interaction_function[ftype].flags & IF_VSITE)
958 nra = interaction_function[ftype].nratoms;
964 fprintf(stderr, "doing %d %s virtual sites\n",
965 (nrd / (nra+1)), interaction_function[ftype].longname);
968 for (i = 0; (i < nrd); )
970 /* The virtual site */
972 molt->atoms.atom[avsite].ptype = eptVSite;
986 static void check_vsite_constraints(t_params *plist,
987 int cftype, int vsite_type[])
994 ps = &(plist[cftype]);
995 for (i = 0; (i < ps->nr); i++)
997 for (k = 0; k < 2; k++)
999 atom = ps->param[i].a[k];
1000 if (vsite_type[atom] != NOTSET)
1002 fprintf(stderr, "ERROR: Cannot have constraint (%u-%u) with virtual site (%u)\n",
1003 ps->param[i].AI+1, ps->param[i].AJ+1, atom+1);
1010 gmx_fatal(FARGS, "There were %d virtual sites involved in constraints", n);
1014 static void clean_vsite_bonds(t_params *plist, t_pindex pindex[],
1015 int cftype, int vsite_type[])
1017 int ftype, i, j, parnr, k, l, m, n, nvsite, nOut, kept_i, vsnral, vsitetype;
1018 int nconverted, nremoved;
1019 atom_id atom, oatom, constr, at1, at2;
1020 atom_id vsiteatoms[MAXATOMLIST];
1021 gmx_bool bKeep, bRemove, bUsed, bPresent, bThisFD, bThisOUT, bAllFD, bFirstTwo;
1024 if (cftype == F_CONNBONDS)
1029 ps = &(plist[cftype]);
1035 for (i = 0; (i < ps->nr); i++) /* for all bonds in the plist */
1040 /* check if all virtual sites are constructed from the same atoms */
1044 fprintf(debug, "constr %u %u:", ps->param[i].AI+1, ps->param[i].AJ+1);
1046 for (k = 0; (k < 2) && !bKeep && !bRemove; k++)
1048 /* for all atoms in the bond */
1049 atom = ps->param[i].a[k];
1050 if (vsite_type[atom] != NOTSET)
1054 fprintf(debug, " d%d[%d: %d %d %d]", k, atom+1,
1055 plist[pindex[atom].ftype].param[pindex[atom].parnr].AJ+1,
1056 plist[pindex[atom].ftype].param[pindex[atom].parnr].AK+1,
1057 plist[pindex[atom].ftype].param[pindex[atom].parnr].AL+1);
1060 bThisFD = ( (pindex[atom].ftype == F_VSITE3FD ) ||
1061 (pindex[atom].ftype == F_VSITE3FAD) ||
1062 (pindex[atom].ftype == F_VSITE4FD ) ||
1063 (pindex[atom].ftype == F_VSITE4FDN ) );
1064 bThisOUT = ( (pindex[atom].ftype == F_VSITE3OUT) &&
1065 (interaction_function[cftype].flags & IF_CONSTRAINT) );
1066 bAllFD = bAllFD && bThisFD;
1067 if (bThisFD || bThisOUT)
1071 fprintf(debug, " %s", bThisOUT ? "out" : "fd");
1073 oatom = ps->param[i].a[1-k]; /* the other atom */
1074 if (vsite_type[oatom] == NOTSET &&
1075 oatom == plist[pindex[atom].ftype].param[pindex[atom].parnr].AJ)
1077 /* if the other atom isn't a vsite, and it is AI */
1085 fprintf(debug, " D-AI");
1093 /* if this is the first vsite we encounter then
1094 store construction atoms */
1095 vsnral = NRAL(pindex[atom].ftype)-1;
1096 for (m = 0; (m < vsnral); m++)
1099 plist[pindex[atom].ftype].param[pindex[atom].parnr].a[m+1];
1104 /* if it is not the first then
1105 check if this vsite is constructed from the same atoms */
1106 if (vsnral == NRAL(pindex[atom].ftype)-1)
1108 for (m = 0; (m < vsnral) && !bKeep; m++)
1112 plist[pindex[atom].ftype].param[pindex[atom].parnr].a[m+1];
1113 for (n = 0; (n < vsnral) && !bPresent; n++)
1115 if (constr == vsiteatoms[n])
1125 fprintf(debug, " !present");
1135 fprintf(debug, " !same#at");
1149 /* if we have no virtual sites in this bond, keep it */
1154 fprintf(debug, " no vsite");
1159 /* check if all non-vsite atoms are used in construction: */
1161 for (k = 0; (k < 2) && !bKeep; k++) /* for all atoms in the bond */
1163 atom = ps->param[i].a[k];
1164 if (vsite_type[atom] == NOTSET)
1167 for (m = 0; (m < vsnral) && !bUsed; m++)
1169 if (atom == vsiteatoms[m])
1172 bFirstTwo = bFirstTwo && m < 2;
1180 fprintf(debug, " !used");
1186 if (!( bAllFD && bFirstTwo ) )
1188 /* check if all constructing atoms are constrained together */
1189 for (m = 0; m < vsnral && !bKeep; m++) /* all constr. atoms */
1191 at1 = vsiteatoms[m];
1192 at2 = vsiteatoms[(m+1) % vsnral];
1194 for (ftype = 0; ftype < F_NRE; ftype++)
1196 if (interaction_function[ftype].flags & IF_CONSTRAINT)
1198 for (j = 0; (j < plist[ftype].nr) && !bPresent; j++)
1200 /* all constraints until one matches */
1201 bPresent = ( ( (plist[ftype].param[j].AI == at1) &&
1202 (plist[ftype].param[j].AJ == at2) ) ||
1203 ( (plist[ftype].param[j].AI == at2) &&
1204 (plist[ftype].param[j].AJ == at1) ) );
1213 fprintf(debug, " !bonded");
1224 fprintf(debug, " keeping");
1226 /* now copy the bond to the new array */
1227 ps->param[kept_i] = ps->param[i];
1230 else if (IS_CHEMBOND(cftype))
1232 srenew(plist[F_CONNBONDS].param, plist[F_CONNBONDS].nr+1);
1233 plist[F_CONNBONDS].param[plist[F_CONNBONDS].nr] = ps->param[i];
1234 plist[F_CONNBONDS].nr++;
1243 fprintf(debug, "\n");
1249 fprintf(stderr, "Removed %4d %15ss with virtual sites, %5d left\n",
1250 nremoved, interaction_function[cftype].longname, kept_i);
1254 fprintf(stderr, "Converted %4d %15ss with virtual sites to connections, %5d left\n",
1255 nconverted, interaction_function[cftype].longname, kept_i);
1259 fprintf(stderr, "Warning: removed %d %ss with vsite with %s construction\n"
1260 " This vsite construction does not guarantee constant "
1262 " If the constructions were generated by pdb2gmx ignore "
1264 nOut, interaction_function[cftype].longname,
1265 interaction_function[F_VSITE3OUT].longname );
1270 static void clean_vsite_angles(t_params *plist, t_pindex pindex[],
1271 int cftype, int vsite_type[],
1272 at2vsitecon_t *at2vc)
1274 int i, j, parnr, k, l, m, n, nvsite, kept_i, vsnral, vsitetype;
1275 atom_id atom, constr, at1, at2;
1276 atom_id vsiteatoms[MAXATOMLIST];
1277 gmx_bool bKeep, bUsed, bPresent, bAll3FAD, bFirstTwo;
1280 ps = &(plist[cftype]);
1283 for (i = 0; (i < ps->nr); i++) /* for all angles in the plist */
1287 /* check if all virtual sites are constructed from the same atoms */
1289 for (k = 0; (k < 3) && !bKeep; k++) /* for all atoms in the angle */
1291 atom = ps->param[i].a[k];
1292 if (vsite_type[atom] != NOTSET)
1295 bAll3FAD = bAll3FAD && (pindex[atom].ftype == F_VSITE3FAD);
1298 /* store construction atoms of first vsite */
1299 vsnral = NRAL(pindex[atom].ftype)-1;
1300 for (m = 0; (m < vsnral); m++)
1303 plist[pindex[atom].ftype].param[pindex[atom].parnr].a[m+1];
1307 /* check if this vsite is constructed from the same atoms */
1308 if (vsnral == NRAL(pindex[atom].ftype)-1)
1310 for (m = 0; (m < vsnral) && !bKeep; m++)
1314 plist[pindex[atom].ftype].param[pindex[atom].parnr].a[m+1];
1315 for (n = 0; (n < vsnral) && !bPresent; n++)
1317 if (constr == vsiteatoms[n])
1335 /* keep all angles with no virtual sites in them or
1336 with virtual sites with more than 3 constr. atoms */
1337 if (nvsite == 0 && vsnral > 3)
1342 /* check if all non-vsite atoms are used in construction: */
1344 for (k = 0; (k < 3) && !bKeep; k++) /* for all atoms in the angle */
1346 atom = ps->param[i].a[k];
1347 if (vsite_type[atom] == NOTSET)
1350 for (m = 0; (m < vsnral) && !bUsed; m++)
1352 if (atom == vsiteatoms[m])
1355 bFirstTwo = bFirstTwo && m < 2;
1365 if (!( bAll3FAD && bFirstTwo ) )
1367 /* check if all constructing atoms are constrained together */
1368 for (m = 0; m < vsnral && !bKeep; m++) /* all constr. atoms */
1370 at1 = vsiteatoms[m];
1371 at2 = vsiteatoms[(m+1) % vsnral];
1373 for (j = 0; j < at2vc[at1].nr; j++)
1375 if (at2vc[at1].aj[j] == at2)
1389 /* now copy the angle to the new array */
1390 ps->param[kept_i] = ps->param[i];
1395 if (ps->nr != kept_i)
1397 fprintf(stderr, "Removed %4d %15ss with virtual sites, %5d left\n",
1398 ps->nr-kept_i, interaction_function[cftype].longname, kept_i);
1403 static void clean_vsite_dihs(t_params *plist, t_pindex pindex[],
1404 int cftype, int vsite_type[])
1409 ps = &(plist[cftype]);
1412 for (i = 0; (i < ps->nr); i++) /* for all dihedrals in the plist */
1414 int ftype, parnr, k, l, m, n, nvsite;
1415 int vsnral = 0; /* keep the compiler happy */
1416 atom_id atom, constr;
1417 atom_id vsiteatoms[4] = { 0 }; /* init to zero to make gcc4.8 happy */
1418 gmx_bool bKeep, bUsed, bPresent;
1422 /* check if all virtual sites are constructed from the same atoms */
1424 for (k = 0; (k < 4) && !bKeep; k++) /* for all atoms in the dihedral */
1426 atom = ps->param[i].a[k];
1427 if (vsite_type[atom] != NOTSET)
1431 /* store construction atoms of first vsite */
1432 vsnral = NRAL(pindex[atom].ftype)-1;
1433 assert(vsnral <= 4);
1434 for (m = 0; (m < vsnral); m++)
1437 plist[pindex[atom].ftype].param[pindex[atom].parnr].a[m+1];
1441 fprintf(debug, "dih w. vsite: %u %u %u %u\n",
1442 ps->param[i].AI+1, ps->param[i].AJ+1,
1443 ps->param[i].AK+1, ps->param[i].AL+1);
1444 fprintf(debug, "vsite %u from: %u %u %u\n",
1445 atom+1, vsiteatoms[0]+1, vsiteatoms[1]+1, vsiteatoms[2]+1);
1450 /* check if this vsite is constructed from the same atoms */
1451 if (vsnral == NRAL(pindex[atom].ftype)-1)
1453 for (m = 0; (m < vsnral) && !bKeep; m++)
1457 plist[pindex[atom].ftype].param[pindex[atom].parnr].a[m+1];
1458 for (n = 0; (n < vsnral) && !bPresent; n++)
1460 if (constr == vsiteatoms[n])
1476 /* keep all dihedrals with no virtual sites in them */
1482 /* check if all atoms in dihedral are either virtual sites, or used in
1483 construction of virtual sites. If so, keep it, if not throw away: */
1484 for (k = 0; (k < 4) && !bKeep; k++) /* for all atoms in the dihedral */
1486 atom = ps->param[i].a[k];
1487 if (vsite_type[atom] == NOTSET)
1489 /* vsnral will be set here, we don't get here with nvsite==0 */
1491 for (m = 0; (m < vsnral) && !bUsed; m++)
1493 if (atom == vsiteatoms[m])
1503 fprintf(debug, "unused atom in dih: %u\n", atom+1);
1511 ps->param[kept_i] = ps->param[i];
1516 if (ps->nr != kept_i)
1518 fprintf(stderr, "Removed %4d %15ss with virtual sites, %5d left\n",
1519 ps->nr-kept_i, interaction_function[cftype].longname, kept_i);
1524 void clean_vsite_bondeds(t_params *plist, int natoms, gmx_bool bRmVSiteBds)
1526 int i, k, nvsite, ftype, vsite, parnr;
1529 at2vsitecon_t *at2vc;
1531 pindex = 0; /* avoid warnings */
1532 /* make vsite_type array */
1533 snew(vsite_type, natoms);
1534 for (i = 0; i < natoms; i++)
1536 vsite_type[i] = NOTSET;
1539 for (ftype = 0; ftype < F_NRE; ftype++)
1541 if (interaction_function[ftype].flags & IF_VSITE)
1543 nvsite += plist[ftype].nr;
1545 while (i < plist[ftype].nr)
1547 vsite = plist[ftype].param[i].AI;
1548 if (vsite_type[vsite] == NOTSET)
1550 vsite_type[vsite] = ftype;
1554 gmx_fatal(FARGS, "multiple vsite constructions for atom %d", vsite+1);
1556 if (ftype == F_VSITEN)
1558 while (i < plist[ftype].nr && plist[ftype].param[i].AI == vsite)
1571 /* the rest only if we have virtual sites: */
1574 fprintf(stderr, "Cleaning up constraints %swith virtual sites\n",
1575 bRmVSiteBds ? "and constant bonded interactions " : "");
1577 /* Make a reverse list to avoid ninteractions^2 operations */
1578 at2vc = make_at2vsitecon(natoms, plist);
1580 snew(pindex, natoms);
1581 for (ftype = 0; ftype < F_NRE; ftype++)
1583 if ((interaction_function[ftype].flags & IF_VSITE) &&
1586 for (parnr = 0; (parnr < plist[ftype].nr); parnr++)
1588 k = plist[ftype].param[parnr].AI;
1589 pindex[k].ftype = ftype;
1590 pindex[k].parnr = parnr;
1597 for (i = 0; i < natoms; i++)
1599 fprintf(debug, "atom %d vsite_type %s\n", i,
1600 vsite_type[i] == NOTSET ? "NOTSET" :
1601 interaction_function[vsite_type[i]].name);
1605 /* remove things with vsite atoms */
1606 for (ftype = 0; ftype < F_NRE; ftype++)
1608 if ( ( ( interaction_function[ftype].flags & IF_BOND ) && bRmVSiteBds ) ||
1609 ( interaction_function[ftype].flags & IF_CONSTRAINT ) )
1611 if (interaction_function[ftype].flags & (IF_BTYPE | IF_CONSTRAINT) )
1613 clean_vsite_bonds (plist, pindex, ftype, vsite_type);
1615 else if (interaction_function[ftype].flags & IF_ATYPE)
1617 clean_vsite_angles(plist, pindex, ftype, vsite_type, at2vc);
1619 else if ( (ftype == F_PDIHS) || (ftype == F_IDIHS) )
1621 clean_vsite_dihs (plist, pindex, ftype, vsite_type);
1625 /* check if we have constraints left with virtual sites in them */
1626 for (ftype = 0; ftype < F_NRE; ftype++)
1628 if (interaction_function[ftype].flags & IF_CONSTRAINT)
1630 check_vsite_constraints(plist, ftype, vsite_type);
1634 done_at2vsitecon(natoms, at2vc);