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_g_nmeig_c
= "$Id$";
51 int main(int argc
,char *argv
[])
53 static char *desc
[] = {
54 "g_nmeig calculates the eigenvectors/values of a (Hessian) matrix,",
55 "which can be calculated with [TT]nmrun[tt].",
56 "The eigenvectors are written to a trajectory file ([TT]-v[tt]).",
57 "The structure is written first with t=0. The eigenvectors",
58 "are written as frames with the eigenvector number as timestamp.",
59 "The eigenvectors can be analyzed with [TT]g_anaeig[tt].",
60 "An ensemble of structures can be generated from the eigenvectors with",
64 static int begin
=1,end
=100;
66 { "-m", FALSE
, etBOOL
, {&bM
},
67 "Divide elements of Hessian by product of sqrt(mass) of involved atoms prior to diagonalization. This should be used for 'Normal Modes' analyses" },
68 { "-first", FALSE
, etINT
, {&begin
},
69 "First eigenvector to write away" },
70 { "-last", FALSE
, etINT
, {&end
},
71 "Last eigenvector to write away" }
79 real t
,*hess
,*eigv
,rdum
,mass_fac
;
80 int natoms
,ndim
,count
;
81 char *grpname
,title
[256];
86 { efMTX
, "-f", "hessian", ffREAD
},
87 { efTPS
, NULL
, NULL
, ffREAD
},
88 { efXVG
, NULL
, "eigenval", ffWRITE
},
89 { efTRN
, "-v", "eigenvec", ffWRITE
}
91 #define NFILE asize(fnm)
93 CopyRight(stderr
,argv
[0]);
94 parse_common_args(&argc
,argv
,PCA_SET_NPRI
,TRUE
,
95 NFILE
,fnm
,asize(pa
),pa
,asize(desc
),desc
,0,NULL
);
97 read_tps_conf(ftp2fn(efTPS
,NFILE
,fnm
),title
,&top
,&top_x
,NULL
,box
,bM
);
99 /*open Hessian matrix and read first 'line' */
101 natoms
=read_first_x(&status
,ftp2fn(efMTX
,NFILE
,fnm
),&t
,&x
,box
);
104 fprintf(stderr
,"Dimensionality of matrix: %d\n",ndim
);
106 /* store two dimensional Hessian matrix in one dimensional array
107 * to facilitate communication with fortran */
109 snew(hess
,ndim
*ndim
);
113 for (i
=0; (i
<natoms
); i
++) {
114 for (j
=0; (j
<DIM
); j
++) {
115 hess
[i
*DIM
+j
]=0.0-x
[i
][j
];
119 /* read in rest of Hessian */
121 for (i
=1; (i
<ndim
); i
++) {
122 if (read_next_x(status
,&t
,natoms
,x
,box
)) {
123 for (j
=0; (j
<natoms
); j
++) {
124 for (k
=0; (k
<DIM
); k
++) {
125 hess
[i
*ndim
+j
*DIM
+k
]=0.0-x
[j
][k
];
130 fatal_error(0,"Premature end of file, hessian matrix");
136 /* check if matrix is approximately symmetric */
137 for (i
=0; (i
<ndim
); i
++) {
138 for (j
=0; (j
<i
); j
++) {
139 if (hess
[i
*ndim
+j
] != 0.0 && hess
[j
*ndim
+i
] != 0.0)
140 rdum
=(hess
[i
*ndim
+j
]-hess
[j
*ndim
+i
])/(hess
[i
*ndim
+j
]+hess
[j
*ndim
+i
]);
142 if (fabs(hess
[i
*ndim
+j
] - hess
[j
*ndim
+i
]) > 1.0e-5)
147 if (abs(rdum
)>1.0e-5) {
148 fprintf(stderr
,"possible non-symmetric matrix:\n");
149 fprintf(stderr
,"x[%d][%d]=%e,x[%d][%d]=%e\n",i
,j
,\
150 hess
[i
*ndim
+j
],j
,i
,hess
[j
*ndim
+i
]);
152 /* make sure that it is symmetric
153 * this is not very nice, but we did warn, did't we? */
154 hess
[j
*ndim
+i
]=hess
[i
*ndim
+j
];
158 /* divide elements hess[i][j]
159 by sqrt(mas[i])*sqrt(mas[j]) when required */
162 for (i
=0; (i
<natoms
); i
++) {
163 for (j
=0; (j
<DIM
); j
++) {
164 for (k
=0; (k
<natoms
); k
++) {
165 mass_fac
=invsqrt(top
.atoms
.atom
[i
].m
*top
.atoms
.atom
[k
].m
);
166 for (l
=0; (l
<DIM
); l
++)
167 hess
[(i
*DIM
+j
)*ndim
+k
*DIM
+l
]*=mass_fac
;
173 /* call diagonalization routine. Tested only fortran double precision */
175 fprintf(stderr
,"\nDiagonalizing...\n");
178 ql77 (ndim
,hess
,eigv
);
180 /* check the output, first 6 eigenvalues should be quite small */
183 for (i
=0; (i
<6); i
++) {
184 if (abs(eigv
[i
]) > 1.0e-3)
188 fprintf(stderr
,"\nOne of the first eigenvalues has a non-zero value.\n");
189 fprintf(stderr
,"This could mean that the reference structure was not\n");
190 fprintf(stderr
,"properly energy minimised\n");
193 /* now write the output */
194 fprintf (stderr
,"Writing eigenvalues...\n");
195 out
=xvgropen(ftp2fn(efXVG
,NFILE
,fnm
),
196 "Eigenvalues","Eigenvector index","Eigenvalue");
198 fprintf(out
,"@ subtitle \"of mass weighted Hessian matrix\"\n");
200 fprintf(out
,"@ subtitle \"of Hessian matrix\"\n");
201 for (i
=0; i
<ndim
; i
++)
202 fprintf (out
,"%6d %15g\n",i
+1,eigv
[i
]);
210 write_eigenvectors(opt2fn("-v",NFILE
,fnm
),natoms
,hess
,FALSE
,begin
,end
,
211 eWXR_NO
,NULL
,FALSE
,top_x
,bM
);