3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * GROningen Mixture of Alchemy and Childrens' Stories
35 /* This file is completely threadsafe - keep it that way! */
43 #include "gmx_fatal.h"
48 static real
dist2(t_pbc
*pbc
,rvec x
,rvec y
)
57 real
distance_to_z(rvec x
)
59 return (sqr(x
[XX
])+sqr(x
[YY
]));
62 static void low_rotate_conf(int natom
,rvec
*x
,real alfa
, real beta
,real gamma
)
67 for (i
=0; i
<natom
; i
++) {
68 copy_rvec(x
[i
],x_old
);
69 /*calculate new x[i] by rotation alfa around the x-axis*/
71 x
[i
][YY
]= cos(alfa
)*x_old
[YY
] - sin(alfa
)*x_old
[ZZ
];
72 x
[i
][ZZ
]= sin(alfa
)*x_old
[YY
] + cos(alfa
)*x_old
[ZZ
];
73 copy_rvec(x
[i
],x_old
);
74 /*calculate new x[i] by rotation beta around the y-axis*/
75 x
[i
][XX
]= cos(beta
)*x_old
[XX
] + sin(beta
)*x_old
[ZZ
];
77 x
[i
][ZZ
]= - sin(beta
)*x_old
[XX
] + cos(beta
)*x_old
[ZZ
];
78 copy_rvec(x
[i
],x_old
);
79 /*calculate new x[i] by rotation gamma around the z-axis*/
80 x
[i
][XX
]= x_old
[XX
]*cos(gamma
) - x_old
[YY
]*sin(gamma
);
81 x
[i
][YY
]= x_old
[XX
]*sin(gamma
) + x_old
[YY
]*cos(gamma
);
86 static void low_rotate_conf_indexed(int nindex
,atom_id
*index
,rvec
*x
,real alfa
, real beta
,real gamma
)
91 for (i
=0; i
<nindex
; i
++) {
92 copy_rvec(x
[index
[i
]],x_old
);
93 /*calculate new x[index[i]] by rotation alfa around the x-axis*/
94 x
[index
[i
]][XX
]= x_old
[XX
];
95 x
[index
[i
]][YY
]= cos(alfa
)*x_old
[YY
] - sin(alfa
)*x_old
[ZZ
];
96 x
[index
[i
]][ZZ
]= sin(alfa
)*x_old
[YY
] + cos(alfa
)*x_old
[ZZ
];
97 copy_rvec(x
[index
[i
]],x_old
);
98 /*calculate new x[index[i]] by rotation beta around the y-axis*/
99 x
[index
[i
]][XX
]= cos(beta
)*x_old
[XX
] + sin(beta
)*x_old
[ZZ
];
100 x
[index
[i
]][YY
]= x_old
[YY
];
101 x
[index
[i
]][ZZ
]= - sin(beta
)*x_old
[XX
] + cos(beta
)*x_old
[ZZ
];
102 copy_rvec(x
[index
[i
]],x_old
);
103 /*calculate new x[index[i]] by rotation gamma around the z-axis*/
104 x
[index
[i
]][XX
]= x_old
[XX
]*cos(gamma
) - x_old
[YY
]*sin(gamma
);
105 x
[index
[i
]][YY
]= x_old
[XX
]*sin(gamma
) + x_old
[YY
]*cos(gamma
);
106 x
[index
[i
]][ZZ
]= x_old
[ZZ
];
110 void rotate_conf(int natom
,rvec
*x
,rvec
*v
,real alfa
, real beta
,real gamma
)
113 low_rotate_conf(natom
,x
,alfa
,beta
,gamma
);
115 low_rotate_conf(natom
,v
,alfa
,beta
,gamma
);
118 void orient(int natom
,rvec
*x
,rvec
*v
, rvec angle
,matrix box
)
120 real longest
,rij
,rzi
;
121 int i
,j
,m
,max_i
=0,max_j
=0;
124 real alfa
=0,beta
=0,gamma
=0;
127 set_pbc(&pbc
,-1,box
);
129 /*first i am going to look for the longest atom-atom distance*/
130 longest
=dist2(&pbc
,x
[0],x
[1]);
133 for (i
=0;(i
<natom
);i
++) {
134 for (j
=0;(j
<natom
);j
++) {
135 rij
=dist2(&pbc
,x
[i
],x
[j
]);
143 /* first check if x[max_i]<x[max_j] else swap*/
144 if (x
[max_i
][2]>x
[max_j
][2]) {
150 /*set the origin to x[i]*/
152 origin
[m
]=x
[max_i
][m
];
153 for(i
=0;(i
<natom
);i
++)
157 /* calculate the rotation angles alfa(x_axis) and beta(y_axis)
158 * the rotation angles must be calculated clockwise looking
159 * along the rotation axis to the origin*
162 alfa
=atan(x
[max_j
][ZZ
]/x
[max_j
][YY
])-M_PI_2
;
163 beta
=M_PI_2
-atan(x
[max_j
][ZZ
]/x
[max_j
][XX
]);
164 rotate_conf(natom
,x
,v
,alfa
,beta
,gamma
);
166 /* now search the longest distance for rotation along the z_axis */
167 longest
=distance_to_z(x
[0]);
169 for (i
=1;(i
<natom
);i
++) {
170 rzi
=distance_to_z(x
[i
]);
176 gamma
=atan(x
[max_i
][YY
]/x
[max_i
][XX
])-M_PI_2
;
177 rotate_conf(natom
,x
,v
,0,0,gamma
);
184 void genconf(t_atoms
*atoms
,rvec
*x
,rvec
*v
,real
*r
,matrix box
,ivec n_box
)
186 int i
,ix
,iy
,iz
,m
,j
,imol
,offset
;
190 nmol
=n_box
[XX
]*n_box
[YY
]*n_box
[ZZ
];
193 fprintf(stderr
,"Generating configuration\n");
195 for(ix
=0; (ix
< n_box
[XX
]); ix
++) {
196 delta
[XX
]=ix
*box
[XX
][XX
];
197 for(iy
=0; (iy
< n_box
[YY
]); iy
++) {
198 delta
[YY
]=iy
*box
[YY
][YY
];
199 for(iz
=0; (iz
< n_box
[ZZ
]); iz
++) {
200 delta
[ZZ
]=iz
*box
[ZZ
][ZZ
];
201 offset
=imol
*atoms
->nr
;
202 for (i
=0;(i
< atoms
->nr
);i
++) {
203 for (m
=0;(m
< DIM
);m
++)
204 x
[offset
+i
][m
]=delta
[m
]+x
[i
][m
];
206 for (m
=0;(m
< DIM
);m
++)
207 v
[offset
+i
][m
]=v
[i
][m
];
214 for (i
=1;(i
<nmol
);i
++) {
215 int offs
= i
*atoms
->nr
;
216 int offsres
= i
*atoms
->nres
;
217 for (j
=0;(j
<atoms
->nr
);j
++) {
218 atoms
->atomname
[offs
+j
] = atoms
->atomname
[j
];
219 atoms
->atom
[offs
+j
].resind
= atoms
->atom
[j
].resind
+ offsres
;
220 atoms
->resinfo
[atoms
->atom
[offs
+j
].resind
] =
221 atoms
->resinfo
[atoms
->atom
[j
].resind
];
222 atoms
->resinfo
[atoms
->atom
[offs
+j
].resind
].nr
+= offsres
;
232 /*gen_box() generates a box around a configuration*/
233 void gen_box(int NTB
,int natoms
,rvec
*x
, matrix box
,rvec box_space
,
240 /*calculate minimum and maximum x[0..DIM-1]*/
241 for (m
=0;(m
<DIM
);m
++)
242 xmin
[m
]=xmax
[m
]=x
[0][m
];
243 for (i
=1;(i
< natoms
); i
++)
244 for (m
=0;m
<DIM
;m
++) {
245 xmin
[m
]=min(xmin
[m
],x
[i
][m
]);
246 xmax
[m
]=max(xmax
[m
],x
[i
][m
]);
249 /*calculate the new box sizes for cubic and octahedral ...*/
250 for (m
=0; (m
<DIM
);m
++)
251 box
[m
][m
]=xmax
[m
]-xmin
[m
]+2*box_space
[m
];
253 /*calculate the box size if NTB=1 (truncated octahedron)*/
257 max_box
=max(max_box
,box
[m
][m
]);
258 for (m
=0;(m
<DIM
);m
++)
262 /*move the molecule to the center of the box*/
264 for(i
=0;(i
<natoms
);i
++)
265 for (m
=0;(m
<DIM
);m
++) {
266 x
[i
][m
]+=0.5*(box
[m
][m
]-xmin
[m
]-xmax
[m
]);
271 /* print data to check this */
272 print_stat(x
,natoms
,box
);