0bedb9cb24503f8f538b79699636f598dd027597
[alexxy/gromacs.git] / include / pbc.h
1 /*
2  * 
3  *                This source code is part of
4  * 
5  *                 G   R   O   M   A   C   S
6  * 
7  *          GROningen MAchine for Chemical Simulations
8  * 
9  *                        VERSION 3.2.0
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.
14
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.
19  * 
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.
26  * 
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.
29  * 
30  * For more info, check our website at http://www.gromacs.org
31  * 
32  * And Hey:
33  * Gromacs Runs On Most of All Computer Systems
34  */
35
36 #ifndef _pbc_h
37 #define _pbc_h
38
39 #include "sysstuff.h"
40 #include "typedefs.h"
41
42 #ifdef __cplusplus
43 extern "C" { 
44 #endif
45
46 #define TRICLINIC(box) (box[YY][XX]!=0 || box[ZZ][XX]!=0 || box[ZZ][YY]!=0)
47
48 #define NTRICIMG 14
49 #define NCUCVERT 24
50 #define NCUCEDGE 36
51
52   enum {
53     ecenterTRIC, /* 0.5*(a+b+c)                  */
54     ecenterRECT, /* (0.5*a[x],0.5*b[y],0.5*c[z]) */
55     ecenterZERO, /* (0,0,0)                      */
56     ecenterDEF = ecenterTRIC
57   };
58
59   int ePBC2npbcdim(int ePBC);
60   /* Returns the number of dimensions that use pbc, starting at X */
61
62   int inputrec2nboundeddim(t_inputrec *ir);
63   /* Returns the number of dimensions in which
64    * the coordinates of the particles are bounded, starting at X.
65    */
66
67   void dump_pbc(FILE *fp,t_pbc *pbc);
68   /* Dump the contents of the pbc structure to the file */
69   
70   const char *check_box(int ePBC,matrix box);
71   /* Returns NULL if the box is supported by Gromacs.
72    * Otherwise is returns a string with the problem.
73    * When ePBC=-1, the type of pbc is guessed from the box matrix.
74    */
75
76   real max_cutoff2(int ePBC,matrix box);
77   /* Returns the square of the maximum cut-off allowed for the box,
78    * taking into account that the grid neighborsearch code and pbc_dx
79    * only check combinations of single box-vector shifts.
80    */
81
82   int guess_ePBC(matrix box);
83   /* Guesses the type of periodic boundary conditions using the box */
84
85   bool correct_box(FILE *fplog,int step,tensor box,t_graph *graph);
86   /* Checks for un-allowed box angles and corrects the box
87    * and the integer shift vectors in the graph (if graph!=NULL) if necessary.
88    * Returns TRUE when the box was corrected.
89    */
90
91   int ndof_com(t_inputrec *ir);
92   /* Returns the number of degrees of freedom of the center of mass */
93
94   void set_pbc(t_pbc *pbc,int ePBC,matrix box);
95   /* Initiate the periodic boundary conditions.
96    * pbc_dx will not use pbc and return the normal difference vector
97    * when one or more of the diagonal elements of box are zero.
98    * When ePBC=-1, the type of pbc is guessed from the box matrix.
99    */
100
101   t_pbc *set_pbc_dd(t_pbc *pbc,int ePBC,
102                            gmx_domdec_t *dd,bool bSingleDir,matrix box);
103   /* As set_pbc, but additionally sets that correct distances can
104    * be obtained using (combinations of) single box-vector shifts.
105    * Should be used with pbc_dx_aiuc.
106    * If dd!=NULL pbc is not used for directions
107    * with dd->nc[i]==1 with bSingleDir==TRUE or
108    * with dd->nc[i]<=2 with bSingleDir==FALSE.
109    * Returns pbc when pbc operations are required, NULL otherwise.
110    */
111
112   void pbc_dx(const t_pbc *pbc,const rvec x1, const rvec x2, rvec dx);
113   /* Calculate the correct distance vector from x2 to x1 and put it in dx.
114    * set_pbc must be called before ever calling this routine.
115    *
116    * For triclinic boxes pbc_dx does not necessarily return the shortest
117    * distance vector. If pbc->bLimitDistance=TRUE an atom pair with
118    * distance vector dx with norm2(dx) > pbc->limit_distance2 could
119    * have a shorter distance, but not shorter than sqrt(pbc->limit_distance2).
120    * pbc->limit_distance2 is always larger than max_cutoff2(box).
121    * For the standard rhombic dodecahedron and truncated octahedron
122    * pbc->bLimitDistance=FALSE and thus all distances are correct.
123    */
124
125   int pbc_dx_aiuc(const t_pbc *pbc,const rvec x1,const rvec x2,rvec dx);
126   /* Calculate the correct distance vector from x2 to x1 and put it in dx,
127    * This function can only be used when all atoms are in the rectangular
128    * or triclinic unit-cell.
129    * Returns the ishift required to shift x1 at closest distance to x2;
130    * i.e. if 0<=ishift<SHIFTS then x1 - x2 + shift_vec[ishift] = dx
131    * (see calc_shifts below on how to obtain shift_vec)
132    * set_pbc_dd or set_pbc must be called before ever calling this routine.
133    */
134   void pbc_dx_d(const t_pbc *pbc,const dvec x1, const dvec x2, dvec dx);
135   /* As pbc_dx, but for double precision vectors.
136    * set_pbc must be called before ever calling this routine.
137    */
138
139   bool image_rect(ivec xi,ivec xj,ivec box_size,
140                          real rlong2,int *shift,real *r2);
141   /* Calculate the distance between xi and xj for a rectangular box.
142    * When the distance is SMALLER than rlong2 return TRUE, return
143    * the shift code in shift and the distance in r2. When the distance is
144    * >= rlong2 return FALSE;
145    * It is assumed that rlong2 is scaled the same way as the ivecs xi and xj.
146    */
147
148   bool image_tri(ivec xi,ivec xj,imatrix box,
149                         real rlong2,int *shift,real *r2);
150   /* Calculate the distance between xi and xj for a triclinic box.
151    * When the distance is SMALLER than rlong2 return TRUE, return
152    * the shift code in shift and the distance in r2. When the distance is
153    * >= rlong2 return FALSE;
154    * It is assumed that rlong2 is scaled the same way as the ivecs xi and xj.
155    */
156   
157   bool image_cylindric(ivec xi,ivec xj,ivec box_size,real rlong2,
158                               int *shift,real *r2);
159   /* Calculate the distance between xi and xj for a rectangular box
160    * using a cylindric cutoff for long-range only.
161    * When the distance is SMALLER than rlong2 (in X and Y dir.)
162    * return TRUE, return
163    * the shift code in shift and the distance in r2. When the distance is
164    * >= rlong2 return FALSE;
165    * It is assumed that rlong2 is scaled the same way as the ivecs xi and xj.
166    */
167
168   void calc_shifts(matrix box,rvec shift_vec[]);
169   /* This routine calculates ths shift vectors necessary to use the
170    * ns routine.
171    */
172
173   void calc_box_center(int ecenter,matrix box,rvec box_center);
174   /* Calculates the center of the box.
175    * See the description for the enum ecenter above.
176    */
177
178   void calc_triclinic_images(matrix box,rvec img[]);
179   /* Calculates the NTRICIMG box images */
180
181   void calc_compact_unitcell_vertices(int ecenter,matrix box,
182                                              rvec vert[]);
183   /* Calculates the NCUCVERT vertices of a compact unitcell */
184   
185   int *compact_unitcell_edges(void);
186   /* Return an array of unitcell edges of length NCUCEDGE*2,
187    * this is an index in vert[], which is calculated by calc_unitcell_vertices.
188    * The index consists of NCUCEDGE pairs of vertex indices.
189    * The index does not change, so it needs to be retrieved only once.
190    */
191   void put_atom_in_box(matrix box,rvec x);
192
193   void put_atoms_in_box(matrix box,int natoms,rvec x[]);
194   /* These routines puts ONE or ALL atoms in the box, not caring 
195    * about charge groups!
196    * Also works for triclinic cells.
197    */
198   
199   void put_atoms_in_triclinic_unitcell(int ecenter,matrix box,
200                                               int natoms,rvec x[]);
201   /* This puts ALL atoms in the triclinic unit cell, centered around the
202    * box center as calculated by calc_box_center.
203    */
204
205   const char *put_atoms_in_compact_unitcell(int ePBC,int ecenter,
206                                                    matrix box,
207                                                    int natoms,rvec x[]);
208   /* This puts ALL atoms at the closest distance for the center of the box
209    * as calculated by calc_box_center.
210    * Will return NULL is everything went ok and a warning string if not
211    * all atoms could be placed in the unitcell. This can happen for some
212    * triclinic unitcells, see the comment at pbc_dx above.
213    * When ePBC=-1, the type of pbc is guessed from the box matrix.
214    */
215   
216 #ifdef __cplusplus
217 }
218 #endif
219
220 #endif  /* _pbc_h */