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/notset.h"
50 #include "gromacs/gmxpreprocess/resall.h"
51 #include "gromacs/gmxpreprocess/toputil.h"
52 #include "gromacs/math/units.h"
53 #include "gromacs/math/vec.h"
54 #include "gromacs/mdtypes/md_enums.h"
55 #include "gromacs/topology/ifunc.h"
56 #include "gromacs/topology/topology.h"
57 #include "gromacs/utility/cstringutil.h"
58 #include "gromacs/utility/fatalerror.h"
59 #include "gromacs/utility/gmxassert.h"
60 #include "gromacs/utility/smalloc.h"
61 #include "gromacs/utility/stringutil.h"
66 t_iatom
&ai() { return a
[0]; }
67 t_iatom
&aj() { return a
[1]; }
68 t_iatom
&ak() { return a
[2]; }
69 t_iatom
&al() { return a
[3]; }
80 vsitebondparam_t
*vsbp
;
88 static int vsite_bond_nrcheck(int ftype
)
92 if ((interaction_function
[ftype
].flags
& (IF_BTYPE
| IF_CONSTRAINT
| IF_ATYPE
)) || (ftype
== F_IDIHS
))
94 nrcheck
= NRAL(ftype
);
104 static void enter_bonded(int nratoms
, int *nrbonded
, t_mybonded
**bondeds
,
109 srenew(*bondeds
, *nrbonded
+1);
111 /* copy atom numbers */
112 for (j
= 0; j
< nratoms
; j
++)
114 (*bondeds
)[*nrbonded
].a
[j
] = param
->a
[j
];
117 (*bondeds
)[*nrbonded
].c
= param
->c0();
122 static void get_bondeds(int nrat
, t_iatom atoms
[],
123 at2vsitebond_t
*at2vb
,
124 int *nrbond
, t_mybonded
**bonds
,
125 int *nrang
, t_mybonded
**angles
,
126 int *nridih
, t_mybonded
**idihs
)
128 int k
, i
, ftype
, nrcheck
;
131 for (k
= 0; k
< nrat
; k
++)
133 for (i
= 0; i
< at2vb
[atoms
[k
]].nr
; i
++)
135 ftype
= at2vb
[atoms
[k
]].vsbp
[i
].ftype
;
136 param
= at2vb
[atoms
[k
]].vsbp
[i
].param
;
137 nrcheck
= vsite_bond_nrcheck(ftype
);
138 /* abuse nrcheck to see if we're adding bond, angle or idih */
141 case 2: enter_bonded(nrcheck
, nrbond
, bonds
, param
); break;
142 case 3: enter_bonded(nrcheck
, nrang
, angles
, param
); break;
143 case 4: enter_bonded(nrcheck
, nridih
, idihs
, param
); break;
149 static at2vsitebond_t
*make_at2vsitebond(int natoms
, t_params plist
[])
152 int ftype
, i
, j
, nrcheck
, nr
;
154 at2vsitebond_t
*at2vb
;
159 for (ftype
= 0; (ftype
< F_NRE
); ftype
++)
161 if ((interaction_function
[ftype
].flags
& IF_VSITE
) && ftype
!= F_VSITEN
)
163 for (i
= 0; (i
< plist
[ftype
].nr
); i
++)
165 for (j
= 0; j
< NRAL(ftype
); j
++)
167 bVSI
[plist
[ftype
].param
[i
].a
[j
]] = TRUE
;
173 for (ftype
= 0; (ftype
< F_NRE
); ftype
++)
175 nrcheck
= vsite_bond_nrcheck(ftype
);
178 for (i
= 0; (i
< plist
[ftype
].nr
); i
++)
180 aa
= plist
[ftype
].param
[i
].a
;
181 for (j
= 0; j
< nrcheck
; j
++)
185 nr
= at2vb
[aa
[j
]].nr
;
188 srenew(at2vb
[aa
[j
]].vsbp
, nr
+10);
190 at2vb
[aa
[j
]].vsbp
[nr
].ftype
= ftype
;
191 at2vb
[aa
[j
]].vsbp
[nr
].param
= &plist
[ftype
].param
[i
];
203 static void done_at2vsitebond(int natoms
, at2vsitebond_t
*at2vb
)
207 for (i
= 0; i
< natoms
; i
++)
211 sfree(at2vb
[i
].vsbp
);
217 static at2vsitecon_t
*make_at2vsitecon(int natoms
, t_params plist
[])
220 int ftype
, i
, j
, ai
, aj
, nr
;
221 at2vsitecon_t
*at2vc
;
226 for (ftype
= 0; (ftype
< F_NRE
); ftype
++)
228 if ((interaction_function
[ftype
].flags
& IF_VSITE
) && ftype
!= F_VSITEN
)
230 for (i
= 0; (i
< plist
[ftype
].nr
); i
++)
232 for (j
= 0; j
< NRAL(ftype
); j
++)
234 bVSI
[plist
[ftype
].param
[i
].a
[j
]] = TRUE
;
240 for (ftype
= 0; (ftype
< F_NRE
); ftype
++)
242 if (interaction_function
[ftype
].flags
& IF_CONSTRAINT
)
244 for (i
= 0; (i
< plist
[ftype
].nr
); i
++)
246 ai
= plist
[ftype
].param
[i
].ai();
247 aj
= plist
[ftype
].param
[i
].aj();
248 if (bVSI
[ai
] && bVSI
[aj
])
250 /* Store forward direction */
254 srenew(at2vc
[ai
].aj
, nr
+10);
256 at2vc
[ai
].aj
[nr
] = aj
;
258 /* Store backward direction */
262 srenew(at2vc
[aj
].aj
, nr
+10);
264 at2vc
[aj
].aj
[nr
] = ai
;
275 static void done_at2vsitecon(int natoms
, at2vsitecon_t
*at2vc
)
279 for (i
= 0; i
< natoms
; i
++)
290 static void print_bad(FILE *fp
,
291 int nrbond
, t_mybonded
*bonds
,
292 int nrang
, t_mybonded
*angles
,
293 int nridih
, t_mybonded
*idihs
)
299 fprintf(fp
, "bonds:");
300 for (i
= 0; i
< nrbond
; i
++)
302 fprintf(fp
, " %d-%d (%g)",
303 bonds
[i
].ai()+1, bonds
[i
].aj()+1, bonds
[i
].c
);
309 fprintf(fp
, "angles:");
310 for (i
= 0; i
< nrang
; i
++)
312 fprintf(fp
, " %d-%d-%d (%g)",
313 angles
[i
].ai()+1, angles
[i
].aj()+1,
314 angles
[i
].ak()+1, angles
[i
].c
);
320 fprintf(fp
, "idihs:");
321 for (i
= 0; i
< nridih
; i
++)
323 fprintf(fp
, " %d-%d-%d-%d (%g)",
324 idihs
[i
].ai()+1, idihs
[i
].aj()+1,
325 idihs
[i
].ak()+1, idihs
[i
].al()+1, idihs
[i
].c
);
331 static void print_param(FILE *fp
, int ftype
, int i
, t_param
*param
)
334 static int prev_ftype
= NOTSET
;
335 static int prev_i
= NOTSET
;
338 if ( (ftype
!= prev_ftype
) || (i
!= prev_i
) )
344 fprintf(fp
, "(%d) plist[%s].param[%d]",
345 pass
, interaction_function
[ftype
].name
, i
);
346 for (j
= 0; j
< NRFP(ftype
); j
++)
348 fprintf(fp
, ".c[%d]=%g ", j
, param
->c
[j
]);
354 static real
get_bond_length(int nrbond
, t_mybonded bonds
[],
355 t_iatom ai
, t_iatom aj
)
361 for (i
= 0; i
< nrbond
&& (bondlen
== NOTSET
); i
++)
363 /* check both ways */
364 if ( ( (ai
== bonds
[i
].ai()) && (aj
== bonds
[i
].aj()) ) ||
365 ( (ai
== bonds
[i
].aj()) && (aj
== bonds
[i
].ai()) ) )
367 bondlen
= bonds
[i
].c
; /* note: bonds[i].c might be NOTSET */
373 static real
get_angle(int nrang
, t_mybonded angles
[],
374 t_iatom ai
, t_iatom aj
, t_iatom ak
)
380 for (i
= 0; i
< nrang
&& (angle
== NOTSET
); i
++)
382 /* check both ways */
383 if ( ( (ai
== angles
[i
].ai()) && (aj
== angles
[i
].aj()) && (ak
== angles
[i
].ak()) ) ||
384 ( (ai
== angles
[i
].ak()) && (aj
== angles
[i
].aj()) && (ak
== angles
[i
].ai()) ) )
386 angle
= DEG2RAD
*angles
[i
].c
;
392 static char *get_atomtype_name_AB(t_atom
*atom
, gpp_atomtype_t atype
)
396 name
= get_atomtype_name(atom
->type
, atype
);
398 /* When using the decoupling option, atom types are changed
399 * to decoupled for the non-bonded interactions, but the virtual
400 * sites constructions should be based on the "normal" interactions.
401 * So we return the state B atom type name if the state A atom
402 * type is the decoupled one. We should actually check for the atom
403 * type number, but that's not passed here. So we check for
404 * the decoupled atom type name. This should not cause trouble
405 * as this code is only used for topologies with v-sites without
406 * parameters generated by pdb2gmx.
408 if (strcmp(name
, "decoupled") == 0)
410 name
= get_atomtype_name(atom
->typeB
, atype
);
416 static gmx_bool
calc_vsite3_param(gpp_atomtype_t atype
,
417 t_param
*param
, t_atoms
*at
,
418 int nrbond
, t_mybonded
*bonds
,
419 int nrang
, t_mybonded
*angles
)
421 /* i = virtual site | ,k
422 * j = 1st bonded heavy atom | i-j
423 * k,l = 2nd bonded atoms | `l
426 gmx_bool bXH3
, bError
;
427 real bjk
, bjl
, a
= -1, b
= -1;
428 /* check if this is part of a NH3 , NH2-umbrella or CH3 group,
429 * i.e. if atom k and l are dummy masses (MNH* or MCH3*) */
433 for (i
= 0; i
< 4; i
++)
435 fprintf(debug
, "atom %d type %s ",
437 get_atomtype_name_AB(&at
->atom
[param
->a
[i
]], atype
));
439 fprintf(debug
, "\n");
442 ( (gmx_strncasecmp(get_atomtype_name_AB(&at
->atom
[param
->ak()], atype
), "MNH", 3) == 0) &&
443 (gmx_strncasecmp(get_atomtype_name_AB(&at
->atom
[param
->al()], atype
), "MNH", 3) == 0) ) ||
444 ( (gmx_strncasecmp(get_atomtype_name_AB(&at
->atom
[param
->ak()], atype
), "MCH3", 4) == 0) &&
445 (gmx_strncasecmp(get_atomtype_name_AB(&at
->atom
[param
->al()], atype
), "MCH3", 4) == 0) );
447 bjk
= get_bond_length(nrbond
, bonds
, param
->aj(), param
->ak());
448 bjl
= get_bond_length(nrbond
, bonds
, param
->aj(), param
->al());
449 bError
= (bjk
== NOTSET
) || (bjl
== NOTSET
);
452 /* now we get some XH2/XH3 group specific construction */
453 /* note: we call the heavy atom 'C' and the X atom 'N' */
454 real bMM
, bCM
, bCN
, bNH
, aCNH
, dH
, rH
, dM
, rM
;
457 /* check if bonds from heavy atom (j) to dummy masses (k,l) are equal: */
458 bError
= bError
|| (bjk
!= bjl
);
460 /* the X atom (C or N) in the XH2/XH3 group is the first after the masses: */
461 aN
= std::max(param
->ak(), param
->al())+1;
463 /* get common bonds */
464 bMM
= get_bond_length(nrbond
, bonds
, param
->ak(), param
->al());
466 bCN
= get_bond_length(nrbond
, bonds
, param
->aj(), aN
);
467 bError
= bError
|| (bMM
== NOTSET
) || (bCN
== NOTSET
);
469 /* calculate common things */
471 dM
= std::sqrt( sqr(bCM
) - sqr(rM
) );
473 /* are we dealing with the X atom? */
474 if (param
->ai() == aN
)
476 /* this is trivial */
477 a
= b
= 0.5 * bCN
/dM
;
482 /* get other bondlengths and angles: */
483 bNH
= get_bond_length(nrbond
, bonds
, aN
, param
->ai());
484 aCNH
= get_angle (nrang
, angles
, param
->aj(), aN
, param
->ai());
485 bError
= bError
|| (bNH
== NOTSET
) || (aCNH
== NOTSET
);
488 dH
= bCN
- bNH
* cos(aCNH
);
489 rH
= bNH
* sin(aCNH
);
491 a
= 0.5 * ( dH
/dM
+ rH
/rM
);
492 b
= 0.5 * ( dH
/dM
- rH
/rM
);
497 gmx_fatal(FARGS
, "calc_vsite3_param not implemented for the general case "
498 "(atom %d)", param
->ai()+1);
506 fprintf(debug
, "params for vsite3 %d: %g %g\n",
507 param
->ai()+1, param
->c0(), param
->c1());
513 static gmx_bool
calc_vsite3fd_param(t_param
*param
,
514 int nrbond
, t_mybonded
*bonds
,
515 int nrang
, t_mybonded
*angles
)
517 /* i = virtual site | ,k
518 * j = 1st bonded heavy atom | i-j
519 * k,l = 2nd bonded atoms | `l
523 real bij
, bjk
, bjl
, aijk
, aijl
, rk
, rl
;
525 bij
= get_bond_length(nrbond
, bonds
, param
->ai(), param
->aj());
526 bjk
= get_bond_length(nrbond
, bonds
, param
->aj(), param
->ak());
527 bjl
= get_bond_length(nrbond
, bonds
, param
->aj(), param
->al());
528 aijk
= get_angle (nrang
, angles
, param
->ai(), param
->aj(), param
->ak());
529 aijl
= get_angle (nrang
, angles
, param
->ai(), param
->aj(), param
->al());
530 bError
= (bij
== NOTSET
) || (bjk
== NOTSET
) || (bjl
== NOTSET
) ||
531 (aijk
== NOTSET
) || (aijl
== NOTSET
);
533 rk
= bjk
* sin(aijk
);
534 rl
= bjl
* sin(aijl
);
535 param
->c0() = rk
/ (rk
+ rl
);
536 param
->c1() = -bij
; /* 'bond'-length for fixed distance vsite */
540 fprintf(debug
, "params for vsite3fd %d: %g %g\n",
541 param
->ai()+1, param
->c0(), param
->c1());
546 static gmx_bool
calc_vsite3fad_param(t_param
*param
,
547 int nrbond
, t_mybonded
*bonds
,
548 int nrang
, t_mybonded
*angles
)
550 /* i = virtual site |
551 * j = 1st bonded heavy atom | i-j
552 * k = 2nd bonded heavy atom | `k-l
553 * l = 3d bonded heavy atom |
556 gmx_bool bSwapParity
, bError
;
559 bSwapParity
= ( param
->c1() == -1 );
561 bij
= get_bond_length(nrbond
, bonds
, param
->ai(), param
->aj());
562 aijk
= get_angle (nrang
, angles
, param
->ai(), param
->aj(), param
->ak());
563 bError
= (bij
== NOTSET
) || (aijk
== NOTSET
);
565 param
->c1() = bij
; /* 'bond'-length for fixed distance vsite */
566 param
->c0() = RAD2DEG
*aijk
; /* 'bond'-angle for fixed angle vsite */
570 param
->c0() = 360 - param
->c0();
575 fprintf(debug
, "params for vsite3fad %d: %g %g\n",
576 param
->ai()+1, param
->c0(), param
->c1());
581 static gmx_bool
calc_vsite3out_param(gpp_atomtype_t atype
,
582 t_param
*param
, t_atoms
*at
,
583 int nrbond
, t_mybonded
*bonds
,
584 int nrang
, t_mybonded
*angles
)
586 /* i = virtual site | ,k
587 * j = 1st bonded heavy atom | i-j
588 * k,l = 2nd bonded atoms | `l
589 * NOTE: i is out of the j-k-l plane!
592 gmx_bool bXH3
, bError
, bSwapParity
;
593 real bij
, bjk
, bjl
, aijk
, aijl
, akjl
, pijk
, pijl
, a
, b
, c
;
595 /* check if this is part of a NH2-umbrella, NH3 or CH3 group,
596 * i.e. if atom k and l are dummy masses (MNH* or MCH3*) */
600 for (i
= 0; i
< 4; i
++)
602 fprintf(debug
, "atom %d type %s ",
603 param
->a
[i
]+1, get_atomtype_name_AB(&at
->atom
[param
->a
[i
]], atype
));
605 fprintf(debug
, "\n");
608 ( (gmx_strncasecmp(get_atomtype_name_AB(&at
->atom
[param
->ak()], atype
), "MNH", 3) == 0) &&
609 (gmx_strncasecmp(get_atomtype_name_AB(&at
->atom
[param
->al()], atype
), "MNH", 3) == 0) ) ||
610 ( (gmx_strncasecmp(get_atomtype_name_AB(&at
->atom
[param
->ak()], atype
), "MCH3", 4) == 0) &&
611 (gmx_strncasecmp(get_atomtype_name_AB(&at
->atom
[param
->al()], atype
), "MCH3", 4) == 0) );
613 /* check if construction parity must be swapped */
614 bSwapParity
= ( param
->c1() == -1 );
616 bjk
= get_bond_length(nrbond
, bonds
, param
->aj(), param
->ak());
617 bjl
= get_bond_length(nrbond
, bonds
, param
->aj(), param
->al());
618 bError
= (bjk
== NOTSET
) || (bjl
== NOTSET
);
621 /* now we get some XH3 group specific construction */
622 /* note: we call the heavy atom 'C' and the X atom 'N' */
623 real bMM
, bCM
, bCN
, bNH
, aCNH
, dH
, rH
, rHx
, rHy
, dM
, rM
;
626 /* check if bonds from heavy atom (j) to dummy masses (k,l) are equal: */
627 bError
= bError
|| (bjk
!= bjl
);
629 /* the X atom (C or N) in the XH3 group is the first after the masses: */
630 aN
= std::max(param
->ak(), param
->al())+1;
632 /* get all bondlengths and angles: */
633 bMM
= get_bond_length(nrbond
, bonds
, param
->ak(), param
->al());
635 bCN
= get_bond_length(nrbond
, bonds
, param
->aj(), aN
);
636 bNH
= get_bond_length(nrbond
, bonds
, aN
, param
->ai());
637 aCNH
= get_angle (nrang
, angles
, param
->aj(), aN
, param
->ai());
639 (bMM
== NOTSET
) || (bCN
== NOTSET
) || (bNH
== NOTSET
) || (aCNH
== NOTSET
);
642 dH
= bCN
- bNH
* cos(aCNH
);
643 rH
= bNH
* sin(aCNH
);
644 /* we assume the H's are symmetrically distributed */
645 rHx
= rH
*cos(DEG2RAD
*30);
646 rHy
= rH
*sin(DEG2RAD
*30);
648 dM
= std::sqrt( sqr(bCM
) - sqr(rM
) );
649 a
= 0.5*( (dH
/dM
) - (rHy
/rM
) );
650 b
= 0.5*( (dH
/dM
) + (rHy
/rM
) );
656 /* this is the general construction */
658 bij
= get_bond_length(nrbond
, bonds
, param
->ai(), param
->aj());
659 aijk
= get_angle (nrang
, angles
, param
->ai(), param
->aj(), param
->ak());
660 aijl
= get_angle (nrang
, angles
, param
->ai(), param
->aj(), param
->al());
661 akjl
= get_angle (nrang
, angles
, param
->ak(), param
->aj(), param
->al());
663 (bij
== NOTSET
) || (aijk
== NOTSET
) || (aijl
== NOTSET
) || (akjl
== NOTSET
);
665 pijk
= cos(aijk
)*bij
;
666 pijl
= cos(aijl
)*bij
;
667 a
= ( pijk
+ (pijk
*cos(akjl
)-pijl
) * cos(akjl
) / sqr(sin(akjl
)) ) / bjk
;
668 b
= ( pijl
+ (pijl
*cos(akjl
)-pijk
) * cos(akjl
) / sqr(sin(akjl
)) ) / bjl
;
669 c
= -std::sqrt( sqr(bij
) -
670 ( sqr(pijk
) - 2*pijk
*pijl
*cos(akjl
) + sqr(pijl
) )
672 / ( bjk
*bjl
*sin(akjl
) );
687 fprintf(debug
, "params for vsite3out %d: %g %g %g\n",
688 param
->ai()+1, param
->c0(), param
->c1(), param
->c2());
693 static gmx_bool
calc_vsite4fd_param(t_param
*param
,
694 int nrbond
, t_mybonded
*bonds
,
695 int nrang
, t_mybonded
*angles
)
697 /* i = virtual site | ,k
698 * j = 1st bonded heavy atom | i-j-m
699 * k,l,m = 2nd bonded atoms | `l
703 real bij
, bjk
, bjl
, bjm
, aijk
, aijl
, aijm
, akjm
, akjl
;
704 real pk
, pl
, pm
, cosakl
, cosakm
, sinakl
, sinakm
, cl
, cm
;
706 bij
= get_bond_length(nrbond
, bonds
, param
->ai(), param
->aj());
707 bjk
= get_bond_length(nrbond
, bonds
, param
->aj(), param
->ak());
708 bjl
= get_bond_length(nrbond
, bonds
, param
->aj(), param
->al());
709 bjm
= get_bond_length(nrbond
, bonds
, param
->aj(), param
->am());
710 aijk
= get_angle (nrang
, angles
, param
->ai(), param
->aj(), param
->ak());
711 aijl
= get_angle (nrang
, angles
, param
->ai(), param
->aj(), param
->al());
712 aijm
= get_angle (nrang
, angles
, param
->ai(), param
->aj(), param
->am());
713 akjm
= get_angle (nrang
, angles
, param
->ak(), param
->aj(), param
->am());
714 akjl
= get_angle (nrang
, angles
, param
->ak(), param
->aj(), param
->al());
715 bError
= (bij
== NOTSET
) || (bjk
== NOTSET
) || (bjl
== NOTSET
) || (bjm
== NOTSET
) ||
716 (aijk
== NOTSET
) || (aijl
== NOTSET
) || (aijm
== NOTSET
) || (akjm
== NOTSET
) ||
724 cosakl
= (cos(akjl
) - cos(aijk
)*cos(aijl
)) / (sin(aijk
)*sin(aijl
));
725 cosakm
= (cos(akjm
) - cos(aijk
)*cos(aijm
)) / (sin(aijk
)*sin(aijm
));
726 if (cosakl
< -1 || cosakl
> 1 || cosakm
< -1 || cosakm
> 1)
728 fprintf(stderr
, "virtual site %d: angle ijk = %f, angle ijl = %f, angle ijm = %f\n",
729 param
->ai()+1, RAD2DEG
*aijk
, RAD2DEG
*aijl
, RAD2DEG
*aijm
);
730 gmx_fatal(FARGS
, "invalid construction in calc_vsite4fd for atom %d: "
731 "cosakl=%f, cosakm=%f\n", param
->ai()+1, cosakl
, cosakm
);
733 sinakl
= std::sqrt(1-sqr(cosakl
));
734 sinakm
= std::sqrt(1-sqr(cosakm
));
736 /* note: there is a '+' because of the way the sines are calculated */
737 cl
= -pk
/ ( pl
*cosakl
- pk
+ pl
*sinakl
*(pm
*cosakm
-pk
)/(pm
*sinakm
) );
738 cm
= -pk
/ ( pm
*cosakm
- pk
+ pm
*sinakm
*(pl
*cosakl
-pk
)/(pl
*sinakl
) );
745 fprintf(debug
, "params for vsite4fd %d: %g %g %g\n",
746 param
->ai()+1, param
->c0(), param
->c1(), param
->c2());
755 calc_vsite4fdn_param(t_param
*param
,
756 int nrbond
, t_mybonded
*bonds
,
757 int nrang
, t_mybonded
*angles
)
759 /* i = virtual site | ,k
760 * j = 1st bonded heavy atom | i-j-m
761 * k,l,m = 2nd bonded atoms | `l
765 real bij
, bjk
, bjl
, bjm
, aijk
, aijl
, aijm
;
766 real pk
, pl
, pm
, a
, b
;
768 bij
= get_bond_length(nrbond
, bonds
, param
->ai(), param
->aj());
769 bjk
= get_bond_length(nrbond
, bonds
, param
->aj(), param
->ak());
770 bjl
= get_bond_length(nrbond
, bonds
, param
->aj(), param
->al());
771 bjm
= get_bond_length(nrbond
, bonds
, param
->aj(), param
->am());
772 aijk
= get_angle (nrang
, angles
, param
->ai(), param
->aj(), param
->ak());
773 aijl
= get_angle (nrang
, angles
, param
->ai(), param
->aj(), param
->al());
774 aijm
= get_angle (nrang
, angles
, param
->ai(), param
->aj(), param
->am());
776 bError
= (bij
== NOTSET
) || (bjk
== NOTSET
) || (bjl
== NOTSET
) || (bjm
== NOTSET
) ||
777 (aijk
== NOTSET
) || (aijl
== NOTSET
) || (aijm
== NOTSET
);
782 /* Calculate component of bond j-k along the direction i-j */
785 /* Calculate component of bond j-l along the direction i-j */
788 /* Calculate component of bond j-m along the direction i-j */
791 if (fabs(pl
) < 1000*GMX_REAL_MIN
|| fabs(pm
) < 1000*GMX_REAL_MIN
)
793 fprintf(stderr
, "virtual site %d: angle ijk = %f, angle ijl = %f, angle ijm = %f\n",
794 param
->ai()+1, RAD2DEG
*aijk
, RAD2DEG
*aijl
, RAD2DEG
*aijm
);
795 gmx_fatal(FARGS
, "invalid construction in calc_vsite4fdn for atom %d: "
796 "pl=%f, pm=%f\n", param
->ai()+1, pl
, pm
);
808 fprintf(debug
, "params for vsite4fdn %d: %g %g %g\n",
809 param
->ai()+1, param
->c0(), param
->c1(), param
->c2());
818 int set_vsites(gmx_bool bVerbose
, t_atoms
*atoms
, gpp_atomtype_t atype
,
822 int nvsite
, nrbond
, nrang
, nridih
, nrset
;
823 gmx_bool bFirst
, bSet
, bERROR
;
824 at2vsitebond_t
*at2vb
;
833 fprintf(debug
, "\nCalculating parameters for virtual sites\n");
836 /* Make a reverse list to avoid ninteractions^2 operations */
837 at2vb
= make_at2vsitebond(atoms
->nr
, plist
);
839 for (ftype
= 0; (ftype
< F_NRE
); ftype
++)
841 if (interaction_function
[ftype
].flags
& IF_VSITE
)
843 nvsite
+= plist
[ftype
].nr
;
845 if (ftype
== F_VSITEN
)
847 /* We don't calculate parameters for VSITEN */
852 for (i
= 0; (i
< plist
[ftype
].nr
); i
++)
854 /* check if all parameters are set */
856 for (j
= 0; j
< NRFP(ftype
) && bSet
; j
++)
858 bSet
= plist
[ftype
].param
[i
].c
[j
] != NOTSET
;
863 fprintf(debug
, "bSet=%s ", gmx::boolToString(bSet
));
864 print_param(debug
, ftype
, i
, &plist
[ftype
].param
[i
]);
868 if (bVerbose
&& bFirst
)
870 fprintf(stderr
, "Calculating parameters for virtual sites\n");
874 nrbond
= nrang
= nridih
= 0;
879 /* now set the vsite parameters: */
880 get_bondeds(NRAL(ftype
), plist
[ftype
].param
[i
].a
, at2vb
,
881 &nrbond
, &bonds
, &nrang
, &angles
, &nridih
, &idihs
);
884 fprintf(debug
, "Found %d bonds, %d angles and %d idihs "
885 "for virtual site %d (%s)\n", nrbond
, nrang
, nridih
,
886 plist
[ftype
].param
[i
].ai()+1,
887 interaction_function
[ftype
].longname
);
888 print_bad(debug
, nrbond
, bonds
, nrang
, angles
, nridih
, idihs
);
894 calc_vsite3_param(atype
, &(plist
[ftype
].param
[i
]), atoms
,
895 nrbond
, bonds
, nrang
, angles
);
899 calc_vsite3fd_param(&(plist
[ftype
].param
[i
]),
900 nrbond
, bonds
, nrang
, angles
);
904 calc_vsite3fad_param(&(plist
[ftype
].param
[i
]),
905 nrbond
, bonds
, nrang
, angles
);
909 calc_vsite3out_param(atype
, &(plist
[ftype
].param
[i
]), atoms
,
910 nrbond
, bonds
, nrang
, angles
);
914 calc_vsite4fd_param(&(plist
[ftype
].param
[i
]),
915 nrbond
, bonds
, nrang
, angles
);
919 calc_vsite4fdn_param(&(plist
[ftype
].param
[i
]),
920 nrbond
, bonds
, nrang
, angles
);
923 gmx_fatal(FARGS
, "Automatic parameter generation not supported "
925 interaction_function
[ftype
].longname
,
926 plist
[ftype
].param
[i
].ai()+1);
931 gmx_fatal(FARGS
, "Automatic parameter generation not supported "
932 "for %s atom %d for this bonding configuration",
933 interaction_function
[ftype
].longname
,
934 plist
[ftype
].param
[i
].ai()+1);
941 if (debug
&& plist
[ftype
].nr
)
943 fprintf(stderr
, "Calculated parameters for %d out of %d %s atoms\n",
944 nrset
, plist
[ftype
].nr
, interaction_function
[ftype
].longname
);
949 done_at2vsitebond(atoms
->nr
, at2vb
);
954 void set_vsites_ptype(gmx_bool bVerbose
, gmx_moltype_t
*molt
)
963 fprintf(stderr
, "Setting particle type to V for virtual sites\n");
967 fprintf(stderr
, "checking %d functypes\n", F_NRE
);
969 for (ftype
= 0; ftype
< F_NRE
; ftype
++)
971 il
= &molt
->ilist
[ftype
];
972 if (interaction_function
[ftype
].flags
& IF_VSITE
)
974 nra
= interaction_function
[ftype
].nratoms
;
980 fprintf(stderr
, "doing %d %s virtual sites\n",
981 (nrd
/ (nra
+1)), interaction_function
[ftype
].longname
);
984 for (i
= 0; (i
< nrd
); )
986 /* The virtual site */
988 molt
->atoms
.atom
[avsite
].ptype
= eptVSite
;
1002 static void check_vsite_constraints(t_params
*plist
,
1003 int cftype
, int vsite_type
[])
1010 ps
= &(plist
[cftype
]);
1011 for (i
= 0; (i
< ps
->nr
); i
++)
1013 for (k
= 0; k
< 2; k
++)
1015 atom
= ps
->param
[i
].a
[k
];
1016 if (vsite_type
[atom
] != NOTSET
)
1018 fprintf(stderr
, "ERROR: Cannot have constraint (%d-%d) with virtual site (%d)\n",
1019 ps
->param
[i
].ai()+1, ps
->param
[i
].aj()+1, atom
+1);
1026 gmx_fatal(FARGS
, "There were %d virtual sites involved in constraints", n
);
1030 static void clean_vsite_bonds(t_params
*plist
, t_pindex pindex
[],
1031 int cftype
, int vsite_type
[])
1033 int ftype
, i
, j
, k
, m
, n
, nvsite
, nOut
, kept_i
;
1034 int nconverted
, nremoved
;
1035 int atom
, oatom
, at1
, at2
;
1036 gmx_bool bKeep
, bRemove
, bUsed
, bPresent
, bThisFD
, bThisOUT
, bAllFD
, bFirstTwo
;
1039 if (cftype
== F_CONNBONDS
)
1044 ps
= &(plist
[cftype
]);
1049 for (i
= 0; (i
< ps
->nr
); i
++) /* for all bonds in the plist */
1052 const int *first_atoms
= NULL
;
1057 /* check if all virtual sites are constructed from the same atoms */
1061 fprintf(debug
, "constr %d %d:", ps
->param
[i
].ai()+1, ps
->param
[i
].aj()+1);
1063 for (k
= 0; (k
< 2) && !bKeep
&& !bRemove
; k
++)
1065 /* for all atoms in the bond */
1066 atom
= ps
->param
[i
].a
[k
];
1067 if (vsite_type
[atom
] != NOTSET
&& vsite_type
[atom
] != F_VSITEN
)
1070 bThisFD
= ( (pindex
[atom
].ftype
== F_VSITE3FD
) ||
1071 (pindex
[atom
].ftype
== F_VSITE3FAD
) ||
1072 (pindex
[atom
].ftype
== F_VSITE4FD
) ||
1073 (pindex
[atom
].ftype
== F_VSITE4FDN
) );
1074 bThisOUT
= ( (pindex
[atom
].ftype
== F_VSITE3OUT
) &&
1075 (interaction_function
[cftype
].flags
& IF_CONSTRAINT
) );
1076 bAllFD
= bAllFD
&& bThisFD
;
1077 if (bThisFD
|| bThisOUT
)
1081 fprintf(debug
, " %s", bThisOUT
? "out" : "fd");
1083 oatom
= ps
->param
[i
].a
[1-k
]; /* the other atom */
1084 if (vsite_type
[oatom
] == NOTSET
&&
1085 vsite_type
[oatom
] != F_VSITEN
&&
1086 oatom
== plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].aj())
1088 /* if the other atom isn't a vsite, and it is AI */
1096 fprintf(debug
, " D-AI");
1102 /* TODO This fragment, and corresponding logic in
1103 clean_vsite_angles and clean_vsite_dihs should
1104 be refactored into a common function */
1107 /* if this is the first vsite we encounter then
1108 store construction atoms */
1109 /* TODO This would be nicer to implement with
1110 a C++ "vector view" class" with an
1111 STL-container-like interface. */
1112 vsnral
= NRAL(pindex
[atom
].ftype
) - 1;
1113 first_atoms
= plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].a
+ 1;
1117 GMX_ASSERT(vsnral
!= 0, "nvsite > 1 must have vsnral != 0");
1118 GMX_ASSERT(first_atoms
!= NULL
, "nvsite > 1 must have first_atoms != NULL");
1119 /* if it is not the first then
1120 check if this vsite is constructed from the same atoms */
1121 if (vsnral
== NRAL(pindex
[atom
].ftype
)-1)
1123 for (m
= 0; (m
< vsnral
) && !bKeep
; m
++)
1128 atoms
= plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].a
+ 1;
1129 for (n
= 0; (n
< vsnral
) && !bPresent
; n
++)
1131 if (atoms
[m
] == first_atoms
[n
])
1141 fprintf(debug
, " !present");
1151 fprintf(debug
, " !same#at");
1165 /* if we have no virtual sites in this bond, keep it */
1170 fprintf(debug
, " no vsite");
1175 /* TODO This loop and the corresponding loop in
1176 check_vsite_angles should be refactored into a common
1178 /* check if all non-vsite atoms are used in construction: */
1180 for (k
= 0; (k
< 2) && !bKeep
; k
++) /* for all atoms in the bond */
1182 atom
= ps
->param
[i
].a
[k
];
1183 if (vsite_type
[atom
] == NOTSET
&& vsite_type
[atom
] != F_VSITEN
)
1186 for (m
= 0; (m
< vsnral
) && !bUsed
; m
++)
1188 GMX_ASSERT(first_atoms
!= NULL
, "If we've seen a vsite before, we know what its first atom index was");
1190 if (atom
== first_atoms
[m
])
1193 bFirstTwo
= bFirstTwo
&& m
< 2;
1201 fprintf(debug
, " !used");
1207 if (!( bAllFD
&& bFirstTwo
) )
1209 /* Two atom bonded interactions include constraints.
1210 * We need to remove constraints between vsite pairs that have
1211 * a fixed distance due to being constructed from the same
1212 * atoms, since this can be numerically unstable.
1214 for (m
= 0; m
< vsnral
&& !bKeep
; m
++) /* all constr. atoms */
1216 at1
= first_atoms
[m
];
1217 at2
= first_atoms
[(m
+1) % vsnral
];
1219 for (ftype
= 0; ftype
< F_NRE
; ftype
++)
1221 if (interaction_function
[ftype
].flags
& IF_CONSTRAINT
)
1223 for (j
= 0; (j
< plist
[ftype
].nr
) && !bPresent
; j
++)
1225 /* all constraints until one matches */
1226 bPresent
= ( ( (plist
[ftype
].param
[j
].ai() == at1
) &&
1227 (plist
[ftype
].param
[j
].aj() == at2
) ) ||
1228 ( (plist
[ftype
].param
[j
].ai() == at2
) &&
1229 (plist
[ftype
].param
[j
].aj() == at1
) ) );
1238 fprintf(debug
, " !bonded");
1249 fprintf(debug
, " keeping");
1251 /* now copy the bond to the new array */
1252 ps
->param
[kept_i
] = ps
->param
[i
];
1255 else if (IS_CHEMBOND(cftype
))
1257 srenew(plist
[F_CONNBONDS
].param
, plist
[F_CONNBONDS
].nr
+1);
1258 plist
[F_CONNBONDS
].param
[plist
[F_CONNBONDS
].nr
] = ps
->param
[i
];
1259 plist
[F_CONNBONDS
].nr
++;
1268 fprintf(debug
, "\n");
1274 fprintf(stderr
, "Removed %4d %15ss with virtual sites, %5d left\n",
1275 nremoved
, interaction_function
[cftype
].longname
, kept_i
);
1279 fprintf(stderr
, "Converted %4d %15ss with virtual sites to connections, %5d left\n",
1280 nconverted
, interaction_function
[cftype
].longname
, kept_i
);
1284 fprintf(stderr
, "Warning: removed %d %ss with vsite with %s construction\n"
1285 " This vsite construction does not guarantee constant "
1287 " If the constructions were generated by pdb2gmx ignore "
1289 nOut
, interaction_function
[cftype
].longname
,
1290 interaction_function
[F_VSITE3OUT
].longname
);
1295 static void clean_vsite_angles(t_params
*plist
, t_pindex pindex
[],
1296 int cftype
, int vsite_type
[],
1297 at2vsitecon_t
*at2vc
)
1299 int i
, j
, k
, m
, n
, nvsite
, kept_i
;
1301 gmx_bool bKeep
, bUsed
, bPresent
, bAll3FAD
, bFirstTwo
;
1304 ps
= &(plist
[cftype
]);
1306 for (i
= 0; (i
< ps
->nr
); i
++) /* for all angles in the plist */
1309 const int *first_atoms
= NULL
;
1313 /* check if all virtual sites are constructed from the same atoms */
1315 for (k
= 0; (k
< 3) && !bKeep
; k
++) /* for all atoms in the angle */
1317 atom
= ps
->param
[i
].a
[k
];
1318 if (vsite_type
[atom
] != NOTSET
&& vsite_type
[atom
] != F_VSITEN
)
1321 bAll3FAD
= bAll3FAD
&& (pindex
[atom
].ftype
== F_VSITE3FAD
);
1324 /* store construction atoms of first vsite */
1325 vsnral
= NRAL(pindex
[atom
].ftype
) - 1;
1326 first_atoms
= plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].a
+ 1;
1330 GMX_ASSERT(vsnral
!= 0, "If we've seen a vsite before, we know how many constructing atoms it had");
1331 GMX_ASSERT(first_atoms
!= NULL
, "If we've seen a vsite before, we know what its first atom index was");
1332 /* check if this vsite is constructed from the same atoms */
1333 if (vsnral
== NRAL(pindex
[atom
].ftype
)-1)
1335 for (m
= 0; (m
< vsnral
) && !bKeep
; m
++)
1340 atoms
= plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].a
+ 1;
1341 for (n
= 0; (n
< vsnral
) && !bPresent
; n
++)
1343 if (atoms
[m
] == first_atoms
[n
])
1362 /* keep all angles with no virtual sites in them or
1363 with virtual sites with more than 3 constr. atoms */
1364 if (nvsite
== 0 && vsnral
> 3)
1369 /* check if all non-vsite atoms are used in construction: */
1371 for (k
= 0; (k
< 3) && !bKeep
; k
++) /* for all atoms in the angle */
1373 atom
= ps
->param
[i
].a
[k
];
1374 if (vsite_type
[atom
] == NOTSET
&& vsite_type
[atom
] != F_VSITEN
)
1377 for (m
= 0; (m
< vsnral
) && !bUsed
; m
++)
1379 GMX_ASSERT(first_atoms
!= NULL
, "If we've seen a vsite before, we know what its first atom index was");
1381 if (atom
== first_atoms
[m
])
1384 bFirstTwo
= bFirstTwo
&& m
< 2;
1394 if (!( bAll3FAD
&& bFirstTwo
) )
1396 /* check if all constructing atoms are constrained together */
1397 for (m
= 0; m
< vsnral
&& !bKeep
; m
++) /* all constr. atoms */
1399 at1
= first_atoms
[m
];
1400 at2
= first_atoms
[(m
+1) % vsnral
];
1402 for (j
= 0; j
< at2vc
[at1
].nr
; j
++)
1404 if (at2vc
[at1
].aj
[j
] == at2
)
1418 /* now copy the angle to the new array */
1419 ps
->param
[kept_i
] = ps
->param
[i
];
1424 if (ps
->nr
!= kept_i
)
1426 fprintf(stderr
, "Removed %4d %15ss with virtual sites, %5d left\n",
1427 ps
->nr
-kept_i
, interaction_function
[cftype
].longname
, kept_i
);
1432 static void clean_vsite_dihs(t_params
*plist
, t_pindex pindex
[],
1433 int cftype
, int vsite_type
[])
1438 ps
= &(plist
[cftype
]);
1441 for (i
= 0; (i
< ps
->nr
); i
++) /* for all dihedrals in the plist */
1443 int k
, m
, n
, nvsite
;
1445 const int *first_atoms
= NULL
;
1447 gmx_bool bKeep
, bUsed
, bPresent
;
1451 /* check if all virtual sites are constructed from the same atoms */
1453 for (k
= 0; (k
< 4) && !bKeep
; k
++) /* for all atoms in the dihedral */
1455 atom
= ps
->param
[i
].a
[k
];
1456 if (vsite_type
[atom
] != NOTSET
&& vsite_type
[atom
] != F_VSITEN
)
1460 /* store construction atoms of first vsite */
1461 vsnral
= NRAL(pindex
[atom
].ftype
) - 1;
1462 first_atoms
= plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].a
+ 1;
1465 fprintf(debug
, "dih w. vsite: %d %d %d %d\n",
1466 ps
->param
[i
].ai()+1, ps
->param
[i
].aj()+1,
1467 ps
->param
[i
].ak()+1, ps
->param
[i
].al()+1);
1468 fprintf(debug
, "vsite %d from: %d %d %d\n",
1469 atom
+1, first_atoms
[0]+1, first_atoms
[1]+1, first_atoms
[2]+1);
1474 GMX_ASSERT(vsnral
!= 0, "If we've seen a vsite before, we know how many constructing atoms it had");
1475 GMX_ASSERT(first_atoms
!= NULL
, "If we've seen a vsite before, we know what its first atom index was");
1476 /* check if this vsite is constructed from the same atoms */
1477 if (vsnral
== NRAL(pindex
[atom
].ftype
)-1)
1479 for (m
= 0; (m
< vsnral
) && !bKeep
; m
++)
1484 atoms
= plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].a
+ 1;
1485 for (n
= 0; (n
< vsnral
) && !bPresent
; n
++)
1487 if (atoms
[m
] == first_atoms
[n
])
1499 /* TODO clean_site_bonds and _angles do this increment
1500 at the top of the loop. Refactor this for
1506 /* keep all dihedrals with no virtual sites in them */
1512 /* check if all atoms in dihedral are either virtual sites, or used in
1513 construction of virtual sites. If so, keep it, if not throw away: */
1514 for (k
= 0; (k
< 4) && !bKeep
; k
++) /* for all atoms in the dihedral */
1516 GMX_ASSERT(vsnral
!= 0, "If we've seen a vsite before, we know how many constructing atoms it had");
1517 GMX_ASSERT(first_atoms
!= NULL
, "If we've seen a vsite before, we know what its first atom index was");
1518 atom
= ps
->param
[i
].a
[k
];
1519 if (vsite_type
[atom
] == NOTSET
&& vsite_type
[atom
] != F_VSITEN
)
1521 /* vsnral will be set here, we don't get here with nvsite==0 */
1523 for (m
= 0; (m
< vsnral
) && !bUsed
; m
++)
1525 if (atom
== first_atoms
[m
])
1535 fprintf(debug
, "unused atom in dih: %d\n", atom
+1);
1543 ps
->param
[kept_i
] = ps
->param
[i
];
1548 if (ps
->nr
!= kept_i
)
1550 fprintf(stderr
, "Removed %4d %15ss with virtual sites, %5d left\n",
1551 ps
->nr
-kept_i
, interaction_function
[cftype
].longname
, kept_i
);
1556 void clean_vsite_bondeds(t_params
*plist
, int natoms
, gmx_bool bRmVSiteBds
)
1558 int i
, k
, nvsite
, ftype
, vsite
, parnr
;
1561 at2vsitecon_t
*at2vc
;
1563 pindex
= 0; /* avoid warnings */
1564 /* make vsite_type array */
1565 snew(vsite_type
, natoms
);
1566 for (i
= 0; i
< natoms
; i
++)
1568 vsite_type
[i
] = NOTSET
;
1571 for (ftype
= 0; ftype
< F_NRE
; ftype
++)
1573 if (interaction_function
[ftype
].flags
& IF_VSITE
)
1575 nvsite
+= plist
[ftype
].nr
;
1577 while (i
< plist
[ftype
].nr
)
1579 vsite
= plist
[ftype
].param
[i
].ai();
1580 if (vsite_type
[vsite
] == NOTSET
)
1582 vsite_type
[vsite
] = ftype
;
1586 gmx_fatal(FARGS
, "multiple vsite constructions for atom %d", vsite
+1);
1588 if (ftype
== F_VSITEN
)
1590 while (i
< plist
[ftype
].nr
&& plist
[ftype
].param
[i
].ai() == vsite
)
1603 /* the rest only if we have virtual sites: */
1606 fprintf(stderr
, "Cleaning up constraints %swith virtual sites\n",
1607 bRmVSiteBds
? "and constant bonded interactions " : "");
1609 /* Make a reverse list to avoid ninteractions^2 operations */
1610 at2vc
= make_at2vsitecon(natoms
, plist
);
1612 snew(pindex
, natoms
);
1613 for (ftype
= 0; ftype
< F_NRE
; ftype
++)
1615 /* Here we skip VSITEN. In neary all practical use cases this
1616 * is not an issue, since VSITEN is intended for constructing
1617 * additional interaction sites, not for replacing normal atoms
1618 * with bonded interactions. Thus we do not expect constant
1619 * bonded interactions. If VSITEN does get used with constant
1620 * bonded interactions, these are not removed which only leads
1621 * to very minor extra computation and constant energy.
1622 * The only problematic case is onstraints between VSITEN
1623 * constructions with fixed distance (which is anyhow useless).
1624 * This will generate a fatal error in check_vsite_constraints.
1626 if ((interaction_function
[ftype
].flags
& IF_VSITE
) &&
1629 for (parnr
= 0; (parnr
< plist
[ftype
].nr
); parnr
++)
1631 k
= plist
[ftype
].param
[parnr
].ai();
1632 pindex
[k
].ftype
= ftype
;
1633 pindex
[k
].parnr
= parnr
;
1640 for (i
= 0; i
< natoms
; i
++)
1642 fprintf(debug
, "atom %d vsite_type %s\n", i
,
1643 vsite_type
[i
] == NOTSET
? "NOTSET" :
1644 interaction_function
[vsite_type
[i
]].name
);
1648 /* remove interactions that include virtual sites */
1649 for (ftype
= 0; ftype
< F_NRE
; ftype
++)
1651 if ( ( ( interaction_function
[ftype
].flags
& IF_BOND
) && bRmVSiteBds
) ||
1652 ( interaction_function
[ftype
].flags
& IF_CONSTRAINT
) )
1654 if (interaction_function
[ftype
].flags
& (IF_BTYPE
| IF_CONSTRAINT
) )
1656 clean_vsite_bonds (plist
, pindex
, ftype
, vsite_type
);
1658 else if (interaction_function
[ftype
].flags
& IF_ATYPE
)
1660 clean_vsite_angles(plist
, pindex
, ftype
, vsite_type
, at2vc
);
1662 else if ( (ftype
== F_PDIHS
) || (ftype
== F_IDIHS
) )
1664 clean_vsite_dihs (plist
, pindex
, ftype
, vsite_type
);
1668 /* check that no remaining constraints include virtual sites */
1669 for (ftype
= 0; ftype
< F_NRE
; ftype
++)
1671 if (interaction_function
[ftype
].flags
& IF_CONSTRAINT
)
1673 check_vsite_constraints(plist
, ftype
, vsite_type
);
1677 done_at2vsitecon(natoms
, at2vc
);