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
43 #include "gmx_fatal.h"
47 int factor
[facNR
] = {2,3,5,7,11,13};
49 int ng
,ng_max
,*list
,n_list
,n_list_alloc
;
51 static void make_list(int start_fac
)
56 if (n_list
>= n_list_alloc
) {
58 srenew(list
,n_list_alloc
);
63 for(i
=start_fac
; i
<facNR
; i
++) {
64 /* allow any power of 2, 3, 5 and 7, but only one of 11 or 13 */
65 if (i
<4 || (decomp
[4]+decomp
[5]==0)) {
76 static int list_comp(const void *a
,const void *b
)
78 return (*((int *)a
) - *((int *)b
));
81 real
calc_grid(FILE *fp
,matrix box
,real gr_sp
,
82 int *nx
,int *ny
,int *nz
,int nnodes
)
86 rvec box_size
,spacing
;
91 gmx_fatal(FARGS
,"invalid fourier grid spacing: %g",gr_sp
);
93 /* New grid calculation setup:
95 * To maintain similar accuracy for triclinic PME grids as for rectangular
96 * ones, the max grid spacing should set along the box vectors rather than
97 * cartesian X/Y/Z directions. This will lead to slightly larger grids, but
98 * it is much better than having to go to pme_order=6.
100 * Thus, instead of just extracting the diagonal elements to box_size[d], we
101 * now calculate the cartesian length of the vectors.
103 * /Erik Lindahl, 20060402.
110 box_size
[d
] += box
[d
][i
]*box
[d
][i
];
112 box_size
[d
] = sqrt(box_size
[d
]);
122 for(d
=0; d
<DIM
; d
++) {
123 nmin
[d
] = (int)(box_size
[d
]/gr_sp
+ 0.999);
124 if (2*nmin
[d
] > ng_max
)
130 for(i
=0; i
<facNR
; i
++)
134 if ((*nx
<=0) || (*ny
<=0) || (*nz
<=0))
135 fprintf(fp
,"Calculating fourier grid dimensions for%s%s%s\n",
136 *nx
> 0 ? "":" X",*ny
> 0 ? "":" Y",*nz
> 0 ? "":" Z");
138 qsort(list
,n_list
,sizeof(list
[0]),list_comp
);
140 for(i
=0; i
<n_list
; i
++)
141 fprintf(debug
,"grid: %d\n",list
[i
]);
143 if (((*nx
>0) && (*nx
!= nnodes
*(*nx
/nnodes
))) ||
144 ((*ny
>0) && (*ny
!= nnodes
*(*ny
/nnodes
))))
145 gmx_fatal(FARGS
,"the x or y grid spacing (nx %d, ny %d) is not divisible by the number of nodes (%d)",*nx
,*ny
,nnodes
);
147 for(d
=0; d
<DIM
; d
++) {
148 for(i
=0; (i
<n_list
) && (n
[d
]<=0); i
++)
149 if ((list
[i
] >= nmin
[d
]) &&
150 ((d
== ZZ
) || (list
[i
] == nnodes
*(list
[i
]/nnodes
))))
153 gmx_fatal(FARGS
,"could not find a grid spacing with nx and ny divisible by the number of nodes (%d)",nnodes
);
157 for(d
=0; d
<DIM
; d
++) {
158 spacing
[d
] = box_size
[d
]/n
[d
];
159 if (spacing
[d
] > max_spacing
)
160 max_spacing
= spacing
[d
];
165 fprintf(fp
,"Using a fourier grid of %dx%dx%d, spacing %.3f %.3f %.3f\n",
166 *nx
,*ny
,*nz
,spacing
[XX
],spacing
[YY
],spacing
[ZZ
]);