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 * Green Red Orange Magenta Azure Cyan Skyblue
29 static char *SRCID_pbc_c
= "$Id$";
42 /*****************************************
43 * PERIODIC BOUNDARY CONDITIONS
44 *****************************************/
46 /* Global variables */
47 static bool bInit
=FALSE
;
49 /* static bool bTriclinic; */
50 static real side
,side_2
,side3_4
;
51 /* static real diag; */
52 static rvec gl_fbox
,gl_hbox
,gl_mhbox
;
54 void init_pbc(matrix box
,bool bTruncOct
)
65 diag = side_2*sqrt(3.0);
67 for(i=0; (i<DIM); i++)
68 for(j=0; (j<DIM); j++)
69 if ((i != j) && (box[i][j] != 0.0))
72 for(i
=0; (i
<DIM
); i
++) {
73 gl_fbox
[i
] = box
[i
][i
];
74 gl_hbox
[i
] = gl_fbox
[i
]*0.5;
75 gl_mhbox
[i
] = -gl_hbox
[i
];
79 static void do_trunc(rvec x
)
83 if (fabs(x
[XX
]-side_2
)+fabs(x
[YY
]-side_2
)+fabs(x
[ZZ
]-side_2
) > side3_4
)
84 for(i
=0; (i
<DIM
); i
++)
85 x
[i
] -= sign(side_2
,x
[i
]);
88 void pbc_dx(rvec x1
, rvec x2
, rvec dx
)
93 fatal_error(0,"pbc_dx called before init_pbc");
95 for(i
=0; (i
<DIM
); i
++) {
96 if (dx
[i
] > gl_hbox
[i
])
98 else if (dx
[i
] <= gl_mhbox
[i
])
105 bool image_rect(ivec xi
,ivec xj
,ivec box_size
,real rlong2
,int *shift
,real
*r2
)
113 for(m
=0; (m
<DIM
); m
++) {
137 bool image_cylindric(ivec xi
,ivec xj
,ivec box_size
,real rlong2
,
146 for(m
=0; (m
<DIM
); m
++) {
173 bool image_tri(ivec xi
,ivec xj
,imatrix box
,real rlong2
,int *shift
,real
*r2
)
175 fatal_error(0,"image_tri not implemented");
177 return FALSE
; /* To make the compiler happy */
180 void calc_shifts(matrix box
,rvec box_size
,rvec shift_vec
[],bool bTruncOct
)
184 init_pbc(box
,bTruncOct
);
185 for (m
=0; (m
<DIM
); m
++)
186 box_size
[m
]=box
[m
][m
];
189 for(k
= -D_BOX
; k
<= D_BOX
; k
++)
190 for(l
= -D_BOX
; l
<= D_BOX
; l
++)
191 for(m
= -D_BOX
; m
<= D_BOX
; m
++,n
++) {
194 fprintf(stdlog
,"n=%d, test=%d\n",n
,test
);
195 if (bTrunc
&& (k
!=0) && (l
!=0) && (m
!=0)) {
196 /* Truncated edges... */
197 shift_vec
[n
][XX
]=k
*side_2
;
198 shift_vec
[n
][YY
]=l
*side_2
;
199 shift_vec
[n
][ZZ
]=m
*side_2
;
201 else if (!bTrunc
|| (((k
+l
+m
) % 2)!=0) || ((k
==0) && (l
==0) && (m
==0)))
202 for(d
= 0; d
< DIM
; d
++)
203 shift_vec
[n
][d
]=k
*box
[XX
][d
] + l
*box
[YY
][d
] + m
*box
[ZZ
][d
];
207 void calc_cgcm(FILE *log
,int cg0
,int cg1
,t_block
*cgs
,
208 rvec pos
[],rvec cg_cm
[])
210 int icg
,ai
,k
,k0
,k1
,d
;
213 atom_id
*cga
,*cgindex
;
216 fprintf(log
,"Calculating centre of geometry for charge groups %d to %d\n",
220 cgindex
= cgs
->index
;
222 /* Compute the center of geometry for all charge groups */
223 for(icg
=cg0
; (icg
<cg1
); icg
++) {
229 copy_rvec(pos
[ai
],cg_cm
[icg
]);
235 for(k
=k0
; (k
<k1
); k
++) {
237 for(d
=0; (d
<DIM
); d
++)
240 for(d
=0; (d
<DIM
); d
++)
241 cg_cm
[icg
][d
] = inv_ncg
*cg
[d
];
246 void put_charge_groups_in_box(FILE *log
,int cg0
,int cg1
,bool bTruncOct
,
247 matrix box
,rvec box_size
,t_block
*cgs
,
248 rvec pos
[],rvec shift_vec
[],rvec cg_cm
[])
251 int icg
,ai
,k
,k0
,k1
,d
;
254 atom_id
*cga
,*cgindex
;
257 fprintf(log
,"Putting cgs %d to %d in box\n",cg0
,cg1
);
260 cgindex
= cgs
->index
;
262 for(icg
=cg0
; (icg
<cg1
); icg
++) {
263 /* First compute the center of geometry for this charge group */
270 for(k
=k0
; (k
<k1
); k
++) {
273 cg
[d
] += inv_ncg
*pos
[ai
][d
];
275 /* Now check pbc for this cg */
276 for(d
=0; d
<DIM
; d
++) {
279 for(k
=k0
; (k
<k1
); k
++)
280 pos
[cga
[k
]][d
] += box
[d
][d
];
282 while(cg
[d
] >= box
[d
][d
]) {
284 for(k
=k0
; (k
<k1
); k
++)
285 pos
[cga
[k
]][d
] -= box
[d
][d
];
287 cg_cm
[icg
][d
] = cg
[d
];
290 for(d
=0; (d
<DIM
); d
++) {
291 if ((cg_cm
[icg
][d
] < 0) || (cg_cm
[icg
][d
] >= box
[d
][d
]))
292 fatal_error(0,"cg_cm[%d] = %15f %15f %15f\n"
293 "box = %15f %15f %15f\n",
294 icg
,cg_cm
[icg
][XX
],cg_cm
[icg
][YY
],cg_cm
[icg
][ZZ
],
295 box
[XX
][XX
],box
[YY
][YY
],box
[ZZ
][ZZ
]);
301 void put_atoms_in_box(int natoms
,matrix box
,rvec x
[])
305 for(i
=0; (i
<natoms
); i
++)
306 for(m
=0; m
< DIM
; m
++) {
308 x
[i
][m
] += box
[m
][m
];
309 while (x
[i
][m
] >= box
[m
][m
])
310 x
[i
][m
] -= box
[m
][m
];