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 rotate_conf_indexed(int nindex
,atom_id
*index
,rvec
*x
,rvec
*v
,real alfa
, real beta
,real gamma
)
121 low_rotate_conf_indexed(nindex
,index
,x
,alfa
,beta
,gamma
);
123 low_rotate_conf_indexed(nindex
,index
,v
,alfa
,beta
,gamma
);
126 void orient(int natom
,rvec
*x
,rvec
*v
, rvec angle
,matrix box
)
128 real longest
,rij
,rzi
;
129 int i
,j
,m
,max_i
=0,max_j
=0;
132 real alfa
=0,beta
=0,gamma
=0;
135 set_pbc(&pbc
,-1,box
);
137 /*first i am going to look for the longest atom-atom distance*/
138 longest
=dist2(&pbc
,x
[0],x
[1]);
141 for (i
=0;(i
<natom
);i
++) {
142 for (j
=0;(j
<natom
);j
++) {
143 rij
=dist2(&pbc
,x
[i
],x
[j
]);
151 /* first check if x[max_i]<x[max_j] else swap*/
152 if (x
[max_i
][2]>x
[max_j
][2]) {
158 /*set the origin to x[i]*/
160 origin
[m
]=x
[max_i
][m
];
161 for(i
=0;(i
<natom
);i
++)
165 /* calculate the rotation angles alfa(x_axis) and beta(y_axis)
166 * the rotation angles must be calculated clockwise looking
167 * along the rotation axis to the origin*
170 alfa
=atan(x
[max_j
][ZZ
]/x
[max_j
][YY
])-M_PI_2
;
171 beta
=M_PI_2
-atan(x
[max_j
][ZZ
]/x
[max_j
][XX
]);
172 rotate_conf(natom
,x
,v
,alfa
,beta
,gamma
);
174 /* now search the longest distance for rotation along the z_axis */
175 longest
=distance_to_z(x
[0]);
177 for (i
=1;(i
<natom
);i
++) {
178 rzi
=distance_to_z(x
[i
]);
184 gamma
=atan(x
[max_i
][YY
]/x
[max_i
][XX
])-M_PI_2
;
185 rotate_conf(natom
,x
,v
,0,0,gamma
);
192 void genconf(t_atoms
*atoms
,rvec
*x
,rvec
*v
,real
*r
,matrix box
,ivec n_box
)
194 int i
,ix
,iy
,iz
,m
,j
,imol
,offset
;
198 nmol
=n_box
[XX
]*n_box
[YY
]*n_box
[ZZ
];
201 fprintf(stderr
,"Generating configuration\n");
203 for(ix
=0; (ix
< n_box
[XX
]); ix
++) {
204 delta
[XX
]=ix
*box
[XX
][XX
];
205 for(iy
=0; (iy
< n_box
[YY
]); iy
++) {
206 delta
[YY
]=iy
*box
[YY
][YY
];
207 for(iz
=0; (iz
< n_box
[ZZ
]); iz
++) {
208 delta
[ZZ
]=iz
*box
[ZZ
][ZZ
];
209 offset
=imol
*atoms
->nr
;
210 for (i
=0;(i
< atoms
->nr
);i
++) {
211 for (m
=0;(m
< DIM
);m
++)
212 x
[offset
+i
][m
]=delta
[m
]+x
[i
][m
];
214 for (m
=0;(m
< DIM
);m
++)
215 v
[offset
+i
][m
]=v
[i
][m
];
222 for (i
=1;(i
<nmol
);i
++) {
223 int offs
= i
*atoms
->nr
;
224 int offsres
= i
*atoms
->nres
;
225 for (j
=0;(j
<atoms
->nr
);j
++) {
226 atoms
->atomname
[offs
+j
] = atoms
->atomname
[j
];
227 atoms
->atom
[offs
+j
].resind
= atoms
->atom
[j
].resind
+ offsres
;
228 atoms
->resinfo
[atoms
->atom
[offs
+j
].resind
] =
229 atoms
->resinfo
[atoms
->atom
[j
].resind
];
230 atoms
->resinfo
[atoms
->atom
[offs
+j
].resind
].nr
+= offsres
;
240 /*gen_box() generates a box around a configuration*/
241 void gen_box(int NTB
,int natoms
,rvec
*x
, matrix box
,rvec box_space
,
248 /*calculate minimum and maximum x[0..DIM-1]*/
249 for (m
=0;(m
<DIM
);m
++)
250 xmin
[m
]=xmax
[m
]=x
[0][m
];
251 for (i
=1;(i
< natoms
); i
++)
252 for (m
=0;m
<DIM
;m
++) {
253 xmin
[m
]=min(xmin
[m
],x
[i
][m
]);
254 xmax
[m
]=max(xmax
[m
],x
[i
][m
]);
257 /*calculate the new box sizes for cubic and octahedral ...*/
258 for (m
=0; (m
<DIM
);m
++)
259 box
[m
][m
]=xmax
[m
]-xmin
[m
]+2*box_space
[m
];
261 /*calculate the box size if NTB=1 (truncated octahedron)*/
265 max_box
=max(max_box
,box
[m
][m
]);
266 for (m
=0;(m
<DIM
);m
++)
270 /*move the molecule to the center of the box*/
272 for(i
=0;(i
<natoms
);i
++)
273 for (m
=0;(m
<DIM
);m
++) {
274 x
[i
][m
]+=0.5*(box
[m
][m
]-xmin
[m
]-xmax
[m
]);
279 /* print data to check this */
280 print_stat(x
,natoms
,box
);