4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * GROningen Mixture of Alchemy and Childrens' Stories
36 /* This file is completely threadsafe - keep it that way! */
48 static void m_op(matrix mat
,rvec x
)
53 for(m
=0; (m
<DIM
); m
++)
54 xp
[m
]=mat
[m
][XX
]*x
[XX
]+mat
[m
][YY
]*x
[YY
]+mat
[m
][ZZ
]*x
[ZZ
];
55 fprintf(stderr
,"x %8.3f %8.3f %8.3f\n",x
[XX
],x
[YY
],x
[ZZ
]);
56 fprintf(stderr
,"xp %8.3f %8.3f %8.3f\n",xp
[XX
],xp
[YY
],xp
[ZZ
]);
57 fprintf(stderr
,"fac %8.3f %8.3f %8.3f\n",xp
[XX
]/x
[XX
],xp
[YY
]/x
[YY
],
64 static void ptrans(char *s
,real
**inten
,real d
[],real e
[])
68 for(m
=1; (m
<NDIM
); m
++) {
73 fprintf(stderr
,"%8s %8.3f %8.3f %8.3f, norm:%8.3f, d:%8.3f, e:%8.3f\n",
74 s
,x
,y
,z
,sqrt(n
),d
[m
],e
[m
]);
79 void t_trans(matrix trans
,real d
[],real
**ev
)
83 for(j
=0; (j
<DIM
); j
++) {
88 fprintf(stderr
,"d[%d]=%g\n",j
,d
[j
+1]);
93 void principal_comp(int n
,atom_id index
[],t_atom atom
[],rvec x
[],
98 double **inten
,dd
[NDIM
],tvec
[NDIM
],**ev
;
106 for(i
=0; (i
<NDIM
); i
++) {
115 for(i
=0; (i
<NDIM
); i
++)
116 for(m
=0; (m
<NDIM
); m
++)
118 for(i
=0; (i
<n
); i
++) {
124 inten
[0][0]+=mm
*(sqr(ry
)+sqr(rz
));
125 inten
[1][1]+=mm
*(sqr(rx
)+sqr(rz
));
126 inten
[2][2]+=mm
*(sqr(rx
)+sqr(ry
));
127 inten
[1][0]-=mm
*(ry
*rx
);
128 inten
[2][0]-=mm
*(rx
*rz
);
129 inten
[2][1]-=mm
*(rz
*ry
);
131 inten
[0][1]=inten
[1][0];
132 inten
[0][2]=inten
[2][0];
133 inten
[1][2]=inten
[2][1];
135 ptrans("initial",inten
,dd
,e
);
138 for(i
=0; (i
<DIM
); i
++) {
139 for(m
=0; (m
<DIM
); m
++)
140 trans
[i
][m
]=inten
[i
][m
];
143 /* Call numerical recipe routines */
144 jacobi(inten
,3,dd
,ev
,&nrot
);
146 ptrans("jacobi",ev
,dd
,e
);
149 /* Sort eigenvalues in descending order */
151 if (fabs(dd[i+1]) > fabs(dd[i])) { \
153 for(j=0; (j<NDIM); j++) tvec[j]=ev[j][i];\
155 for(j=0; (j<NDIM); j++) ev[j][i]=ev[j][i+1]; \
157 for(j=0; (j<NDIM); j++) ev[j][i+1]=tvec[j]; \
163 ptrans("swap",ev
,dd
,e
);
164 t_trans(trans
,dd
,ev
);
167 for(i
=0; (i
<DIM
); i
++) {
169 for(m
=0; (m
<DIM
); m
++)
170 trans
[i
][m
]=ev
[m
][i
];
173 for(i
=0; (i
<NDIM
); i
++) {
181 void rotate_atoms(int gnx
,atom_id
*index
,rvec x
[],matrix trans
)
186 for(i
=0; (i
<gnx
); i
++) {
187 ii
=index
? index
[i
] : i
;
191 x
[ii
][XX
]=trans
[XX
][XX
]*xt
+trans
[XX
][YY
]*yt
+trans
[XX
][ZZ
]*zt
;
192 x
[ii
][YY
]=trans
[YY
][XX
]*xt
+trans
[YY
][YY
]*yt
+trans
[YY
][ZZ
]*zt
;
193 x
[ii
][ZZ
]=trans
[ZZ
][XX
]*xt
+trans
[ZZ
][YY
]*yt
+trans
[ZZ
][ZZ
]*zt
;
197 real
calc_xcm(rvec x
[],int gnx
,atom_id
*index
,t_atom
*atom
,rvec xcm
,
205 for(i
=0; (i
<gnx
); i
++) {
206 ii
=index
? index
[i
] : i
;
216 for(m
=0; (m
<DIM
); m
++)
219 for(m
=0; (m
<DIM
); m
++)
225 real
sub_xcm(rvec x
[],int gnx
,atom_id
*index
,t_atom atom
[],rvec xcm
,
231 tm
=calc_xcm(x
,gnx
,index
,atom
,xcm
,bQ
);
232 for(i
=0; (i
<gnx
); i
++) {
233 ii
=index
? index
[i
] : i
;
239 void add_xcm(rvec x
[],int gnx
,atom_id
*index
,rvec xcm
)
243 for(i
=0; (i
<gnx
); i
++) {
244 ii
=index
? index
[i
] : i
;
249 static void dump_shit(FILE *out
,matrix trans
,rvec prcomp
,real totmass
)
251 /* print principal component data */
252 pr_rvecs(out
,0,"Rot Matrix",trans
,DIM
);
253 fprintf(out
,"Det(trans) = %g\n",det(trans
));
255 fprintf(out
,"Norm of principal axes: %.3f, %.3f, %.3f\n",
256 prcomp
[XX
],prcomp
[YY
],prcomp
[ZZ
]);
257 fprintf(out
,"Totmass = %g\n",totmass
);
261 void orient_princ(t_atoms
*atoms
,int isize
,atom_id
*index
,
262 int natoms
, rvec x
[], rvec
*v
, rvec d
)
268 principal_comp(isize
,index
,atoms
->atom
,x
,trans
,prcomp
);
270 copy_rvec(prcomp
, d
);
272 /* Check whether this trans matrix mirrors the molecule */
273 if (det(trans
) < 0) {
274 for(m
=0; (m
<DIM
); m
++)
275 trans
[ZZ
][m
] = -trans
[ZZ
][m
];
277 rotate_atoms(natoms
,NULL
,x
,trans
);
278 if (v
) rotate_atoms(natoms
,NULL
,v
,trans
);
280 add_xcm(x
,natoms
,NULL
,xcm
);