4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * GRowing Old MAkes el Chrono Sweat
29 static char *SRCID_topshake_c
= "$Id$";
44 static void copy_bond (t_params
*pr
, int to
, int from
)
45 /* copies an entry in a bond list to another position.
46 * does no allocing or freeing of memory
49 memcpy((char*) &(pr
->param
[to
]),(char*) &(pr
->param
[from
]),
50 (size_t)sizeof(pr
->param
[from
]));
53 static int count_hydrogens (char ***atomname
, int nra
, atom_id a
[])
58 fatal_error(0,"Cannot call count_hydrogens with no atomname (%s %d)",
62 for (i
=0; (i
<nra
); i
++)
63 if (toupper(**(atomname
[a
[i
]]))=='H')
69 void make_shake (t_params plist
[],t_atoms
*atoms
,t_atomtype
*at
,int nshake
)
71 char ***info
=atoms
->atomname
;
79 if (nshake
!= eshNONE
) {
82 printf("turning H bonds into constraints...\n");
85 printf("turning all bonds into constraints...\n");
88 printf("turning all bonds and H angles into constraints...\n");
91 printf("turning all bonds and angles into constraints...\n");
94 fatal_error(0,"Invalid option for make_shake (%d)",nshake
);
97 /* Add all the angles with hydrogens to the shake list
98 * and remove them from the bond list
100 for(ftype
= 0; (ftype
< F_NRE
); ftype
++) {
101 if (interaction_function
[ftype
].flags
& IF_BTYPE
) {
102 bonds
=&(plist
[ftype
]);
104 if ((nshake
== eshHANGLES
) || (nshake
== eshALLANGLES
)) {
105 /* horrible shortcut */
106 pr
= &(plist
[F_ANGLES
]);
107 for (i
=0; (i
< pr
->nr
); ) {
110 printf("Angle: %d-%d-%d\n",ang
->AI
,ang
->AJ
,ang
->AK
);
112 if ((nshake
== eshALLANGLES
) ||
113 (count_hydrogens(info
,3,ang
->a
) > 0)) {
114 /* Can only add hydrogen angle shake, if the two bonds
116 * append this angle to the shake list
121 /* Calculate length of constraint */
124 for (j
=0; !bFound
&& (j
<bonds
->nr
); j
++) {
125 bond
=&(bonds
->param
[j
]);
126 if (((bond
->AI
==ang
->AI
) &&
127 (bond
->AJ
==ang
->AJ
)) ||
128 ((bond
->AI
==ang
->AJ
) &&
129 (bond
->AJ
==ang
->AI
)))
131 if (((bond
->AI
==ang
->AK
) &&
132 (bond
->AJ
==ang
->AJ
)) ||
133 ((bond
->AI
==ang
->AJ
) &&
134 (bond
->AJ
==ang
->AK
)))
136 bFound
= (b_ij
!=0.0) && (b_jk
!=0.0);
139 fatal_error(0,"No bond information for bond %s-%s or %s-%s",
140 *info
[ang
->AI
],*info
[ang
->AJ
],
141 *info
[ang
->AJ
],*info
[ang
->AK
]);
142 /* apply law of cosines */
143 p
.C0
= sqrt( b_ij
*b_ij
+ b_jk
*b_jk
-
144 2.0*b_ij
*b_jk
*cos(DEG2RAD
*ang
->C0
) );
147 printf("p: %d, q: %d, dist: %12.5e\n",p
.AI
,p
.AJ
,p
.C0
);
149 push_bondnow (&(plist
[F_SHAKE
]),&p
);
150 /* move the last bond to this position */
151 copy_bond (pr
,i
,pr
->nr
-1);
152 /* should free memory here!! */
158 } /* if nshake == ANGLES or ALLANGLES */
161 } /* nshake != NONE */
163 /* Add all the bonds with hydrogens to the shake list
164 * and remove them from the bond list
166 if ( (nshake
== eshHBONDS
) || (nshake
== eshALLBONDS
) ||
167 (nshake
== eshALLANGLES
) || (nshake
== eshHANGLES
) ) {
168 for (ftype
=0; (ftype
< F_NRE
); ftype
++) {
169 if (interaction_function
[ftype
].flags
& IF_BTYPE
) {
170 pr
= &(plist
[ftype
]);
171 for (i
=0; (i
< pr
->nr
); ) {
172 if ( (nshake
!= eshHBONDS
) ||
173 (count_hydrogens (info
,2,pr
->param
[i
].a
) > 0) ) {
174 /* append this bond to the shake list */
175 p
.AI
= pr
->param
[i
].AI
;
176 p
.AJ
= pr
->param
[i
].AJ
;
177 p
.C0
= pr
->param
[i
].C0
;
178 p
.C1
= pr
->param
[i
].C2
;
179 push_bondnow (&(plist
[F_SHAKE
]),&p
);
181 /* move the last bond to this position */
182 copy_bond (pr
,i
,pr
->nr
-1);
184 /* should free memory here!! */
194 /* Add all non-connecting shakes to the shake list and throw away
196 for (i
=0; i
<plist
[F_SHAKENC
].nr
; i
++)
197 push_bondnow(&(plist
[F_SHAKE
]), &(plist
[F_SHAKENC
].param
[i
]));
198 plist
[F_SHAKENC
].nr
=0;
199 sfree(plist
[F_SHAKENC
].param
);
200 plist
[F_SHAKENC
].param
=NULL
;