4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Copyright (c) 1991-2001, University of Groningen, The Netherlands
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * If you want to redistribute modifications, please consider that
18 * scientific software is very special. Version control is crucial -
19 * bugs must be traceable. We will be happy to consider code for
20 * inclusion in the official distribution, but derived work must not
21 * be called official GROMACS. Details are found in the README & COPYING
22 * files - if they are missing, get the official version at www.gromacs.org.
24 * To help us fund GROMACS development, we humbly ask that you cite
25 * the papers on the package - you can find them in the top README file.
27 * For more info, check our website at http://www.gromacs.org
30 * Getting the Right Output Means no Artefacts in Calculating Stuff
37 #include "gmxcomplex.h"
40 #include "ewald_util.h"
41 #include "shift_util.h"
52 /* the other routines are in complex.h */
53 static t_complex
conjmul(t_complex a
,t_complex b
)
57 c
.re
= a
.re
*b
.re
+ a
.im
*b
.im
;
58 c
.im
= a
.im
*b
.re
- a
.re
*b
.im
;
66 static void tabulate_eir(int natom
,rvec x
[],int kmax
,cvec
**eir
,rvec lll
)
71 printf("Go away! kmax = %d\n",kmax
);
75 for(i
=0; (i
<natom
); i
++) {
76 for(m
=0; (m
<3); m
++) {
81 for(m
=0; (m
<3); m
++) {
82 eir
[1][i
][m
].re
= cos(x
[i
][m
]*lll
[m
]);
83 eir
[1][i
][m
].im
= sin(x
[i
][m
]*lll
[m
]);
85 for(j
=2; (j
<kmax
); j
++)
87 eir
[j
][i
][m
] = cmul(eir
[j
-1][i
][m
],eir
[1][i
][m
]);
94 real
do_ewald(FILE *log
, bool bVerbose
,
97 real charge
[], rvec box
,
98 t_commrec
*cr
, t_nsborder
*nsb
,
99 matrix lrvir
, real ewaldcoeff
)
101 static bool bFirst
= TRUE
;
102 static int nx
,ny
,nz
,kmax
;
104 static t_complex
*tab_xy
,*tab_qxyz
;
105 real factor
=-1.0/(4*ewaldcoeff
*ewaldcoeff
);
108 int lowiy
,lowiz
,ix
,iy
,iz
,n
;
109 real tmp
,cs
,ss
,ak
,akv
,mx
,my
,mz
,m2
;
113 fprintf(log
,"Will do ordinary reciprocal space Ewald sum.\n");
116 if (cr
->nnodes
> 1 || cr
->nthreads
>1)
117 fatal_error(0,"No parallel Ewald. Use PME instead.\n");
123 kmax
= max(nx
,max(ny
,nz
));
126 snew(eir
[n
],HOMENR(nsb
));
127 snew(tab_xy
,HOMENR(nsb
));
128 snew(tab_qxyz
,HOMENR(nsb
));
134 /* make tables for the structure factor parts */
135 tabulate_eir(HOMENR(nsb
),x
,kmax
,eir
,lll
);
140 for(ix
=0;ix
<nx
;ix
++) {
142 for(iy
=lowiy
;iy
<ny
;iy
++) {
145 for(n
=0;n
<HOMENR(nsb
);n
++)
146 tab_xy
[n
]=cmul(eir
[ix
][n
][XX
],eir
[iy
][n
][YY
]);
148 for(n
=0;n
<HOMENR(nsb
);n
++)
149 tab_xy
[n
]=conjmul(eir
[ix
][n
][XX
],eir
[-iy
][n
][YY
]);
150 for(iz
=lowiz
;iz
<nz
;iz
++) {
152 m2
=mx
*mx
+my
*my
+mz
*mz
;
153 ak
=exp(m2
*factor
)/m2
;
154 akv
=2.0*ak
*(1.0/m2
-factor
);
156 for(n
=0;n
<HOMENR(nsb
);n
++)
157 tab_qxyz
[n
]=rcmul(charge
[n
],cmul(tab_xy
[n
],eir
[iz
][n
][ZZ
]));
159 for(n
=0;n
<HOMENR(nsb
);n
++)
160 tab_qxyz
[n
]=rcmul(charge
[n
],conjmul(tab_xy
[n
],eir
[-iz
][n
][ZZ
]));
163 for(n
=0;n
<HOMENR(nsb
);n
++) {
167 energy
+=ak
*(cs
*cs
+ss
*ss
);
168 tmp
=akv
*(cs
*cs
+ss
*ss
);
169 lrvir
[XX
][XX
]-=tmp
*mx
*mx
;
170 lrvir
[XX
][YY
]-=tmp
*mx
*my
;
171 lrvir
[XX
][ZZ
]-=tmp
*mx
*mz
;
172 lrvir
[YY
][YY
]-=tmp
*my
*my
;
173 lrvir
[YY
][ZZ
]-=tmp
*my
*mz
;
174 lrvir
[ZZ
][ZZ
]-=tmp
*mz
*mz
;
175 for(n
=0;n
<HOMENR(nsb
);n
++) {
176 tmp
=ak
*(cs
*tab_qxyz
[n
].im
-ss
*tab_qxyz
[n
].re
);
186 tmp
=4.0*M_PI
/(box
[XX
]*box
[YY
]*box
[ZZ
])*ONE_4PI_EPS0
;
187 for(n
=0;n
<HOMENR(nsb
);n
++) {
192 lrvir
[XX
][XX
]=-0.5*tmp
*(lrvir
[XX
][XX
]+energy
);
193 lrvir
[XX
][YY
]=-0.5*tmp
*(lrvir
[XX
][YY
]);
194 lrvir
[XX
][ZZ
]=-0.5*tmp
*(lrvir
[XX
][ZZ
]);
195 lrvir
[YY
][YY
]=-0.5*tmp
*(lrvir
[YY
][YY
]+energy
);
196 lrvir
[YY
][ZZ
]=-0.5*tmp
*(lrvir
[YY
][ZZ
]);
197 lrvir
[ZZ
][ZZ
]=-0.5*tmp
*(lrvir
[ZZ
][ZZ
]+energy
);
199 lrvir
[YY
][XX
]=lrvir
[XX
][YY
];
200 lrvir
[ZZ
][XX
]=lrvir
[XX
][ZZ
];
201 lrvir
[ZZ
][YY
]=lrvir
[YY
][ZZ
];