12#include "gadgetconfig.h"
20#include "../data/allvars.h"
21#include "../data/dtypes.h"
22#include "../data/mymalloc.h"
23#include "../gravity/ewald.h"
24#include "../gravity/ewaldtensors.h"
25#include "../gravtree/gravtree.h"
27#include "../main/simulation.h"
28#include "../mpi_utils/shared_mem_handler.h"
29#include "../sort/cxxsort.h"
30#include "../system/system.h"
71 mpi_printf(
"EWALD: initialize Ewald correction...\n");
83 int recomputeflag = 0;
88 if((fd = fopen(buf,
"r")))
90 mpi_printf(
"\nEWALD: reading Ewald tables from file `%s'\n", buf);
95#ifndef GRAVITY_TALLBOX
98 int ewaldtype = GRAVITY_TALLBOX + 1;
103 mpi_printf(
"\nEWALD: something's wrong with this table file. Discarding it.\n");
122 mpi_printf(
"\nEWALD: No usable Ewald tables in file `%s' found. Recomputing them...\n", buf);
126 int size = (
ENX + 1) * (
ENY + 1) * (
ENZ + 1);
131 for(
int n = first; n < first + count; n++)
133 int i = n / ((
ENY + 1) * (
ENZ + 1));
134 int j = (n - i * (
ENY + 1) * (
ENZ + 1)) / (
ENZ + 1);
135 int k = (n - i * (
ENY + 1) * (
ENZ + 1) - j * (
ENZ + 1));
140 if(((n - first) % (count / 20)) == 0)
142 printf(
"%4.1f percent done\n", (n - first) / (count / 100.0));
147 double xx = 0.5 *
DBX * (1.0 /
LONG_X) * ((
double)i) /
ENX;
148 double yy = 0.5 *
DBY * (1.0 /
LONG_Y) * ((
double)j) /
ENY;
149 double zz = 0.5 *
DBZ * (1.0 /
LONG_Z) * ((
double)k) /
ENZ;
153#ifndef GRAVITY_TALLBOX
158#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 4
161#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 5
164#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 6
167#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 7
172 switch(GRAVITY_TALLBOX)
181 ewdp->D1phi[
vX] = D1phi[
vZ];
182 ewdp->D1phi[
vY] = D1phi[
vX];
183 ewdp->D1phi[
vZ] = D1phi[
vY];
185 ewdp->D2phi[
qXX] = D2phi[
qZZ];
186 ewdp->D2phi[
qXY] = D2phi[
qZX];
187 ewdp->D2phi[
qXZ] = D2phi[
qZY];
188 ewdp->D2phi[
qYY] = D2phi[
qXX];
189 ewdp->D2phi[
qYZ] = D2phi[
qXY];
190 ewdp->D2phi[
qZZ] = D2phi[
qYY];
212 ewdp->D1phi[
vX] = D1phi[
vX];
213 ewdp->D1phi[
vY] = D1phi[
vZ];
214 ewdp->D1phi[
vZ] = D1phi[
vY];
216 ewdp->D2phi[
qXX] = D2phi[
qXX];
217 ewdp->D2phi[
qXY] = D2phi[
qXZ];
218 ewdp->D2phi[
qXZ] = D2phi[
qXY];
219 ewdp->D2phi[
qYY] = D2phi[
qZZ];
220 ewdp->D2phi[
qYZ] = D2phi[
qZY];
221 ewdp->D2phi[
qZZ] = D2phi[
qYY];
248 int *recvcnts = (
int *)
Mem.mymalloc(
"recvcnts",
NTask *
sizeof(
int));
249 int *recvoffs = (
int *)
Mem.mymalloc(
"recvoffs",
NTask *
sizeof(
int));
251 for(
int i = 0; i <
NTask; i++)
261 Mem.myfree(recvoffs);
262 Mem.myfree(recvcnts);
264 mpi_printf(
"\nEWALD: writing Ewald tables to file `%s'\n", buf);
268 if((fd = fopen(buf,
"w")))
275#ifndef GRAVITY_TALLBOX
286 Terminate(
"can't write to file '%s'\n", buf);
301 for(
int i = 0; i <=
ENX; i++)
302 for(
int j = 0; j <=
ENY; j++)
303 for(
int k = 0; k <=
ENZ; k++)
311#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 4
314#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 5
317#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 6
320#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 7
325 mpi_printf(
"EWALD: Initialization of periodic boundaries finished.\n");
327 ewald_is_initialized = 1;
351 test_interpolation_accuracy();
372 MyIntPosType temppos[3] = {p_intpos[0] - target_intpos[0], p_intpos[1] - target_intpos[1], p_intpos[2] - target_intpos[2]};
377 gridpos[0] = (temppos[0] + halflenX) & ewaldmaskX;
378 gridpos[1] = (temppos[1] + halflenY) & ewaldmaskY;
379 gridpos[2] = (temppos[2] + halflenZ) & ewaldmaskZ;
388 int signx = 1, signy = 1, signz = 1;
390#if defined(GRAVITY_TALLBOX) && (GRAVITY_TALLBOX == 0)
391 if(p_intpos[0] < target_intpos[0])
402 else if(i ==
ENX && gridpos[0] < temppos[0])
406#if defined(GRAVITY_TALLBOX) && (GRAVITY_TALLBOX == 1)
407 if(p_intpos[1] < target_intpos[1])
418 else if(j ==
ENY && gridpos[1] < temppos[1])
422#if defined(GRAVITY_TALLBOX) && (GRAVITY_TALLBOX == 2)
423 if(p_intpos[2] < target_intpos[2])
434 else if(k ==
ENZ && gridpos[2] < temppos[2])
438 fper = Ewd[ewd_offset(i, j, k)];
442 fper.
D1phi[0] *= signx;
443 fper.
D1phi[1] *= signy;
444 fper.
D1phi[2] *= signz;
454 fper.
D3phi[
dXYZ] *= signx * signy * signz;
461#if EWALD_TAYLOR_ORDER == 3
463 fper.D4phi[
sXXXY] *= signx * signy;
464 fper.D4phi[
sXYYY] *= signx * signy;
465 fper.D4phi[
sXXXZ] *= signx * signz;
466 fper.D4phi[
sXZZZ] *= signx * signz;
467 fper.D4phi[
sYYYZ] *= signy * signz;
468 fper.D4phi[
sYZZZ] *= signy * signz;
469 fper.D4phi[
sXXYZ] *= signy * signz;
470 fper.D4phi[
sXYYZ] *= signx * signz;
471 fper.D4phi[
sXYZZ] *= signx * signy;
475 fper.
D0phi += fper.
D1phi * off + 0.5 * ((fper.
D2phi * off) * off) + (1.0 / 6) * (((fper.
D3phi * off) * off) * off);
476 fper.
D1phi += fper.
D2phi * off + 0.5 * ((fper.
D3phi * off) * off) + (1.0 / 6) * (((fper.D4phi * off) * off) * off);
481#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 5
482 fper.D5phi[
rXXXXX] *= signx;
483 fper.D5phi[
rYYYYY] *= signy;
484 fper.D5phi[
rZZZZZ] *= signz;
486 fper.D5phi[
rXXXXY] *= signy;
487 fper.D5phi[
rXXXXZ] *= signz;
488 fper.D5phi[
rXYYYY] *= signx;
489 fper.D5phi[
rXZZZZ] *= signx;
490 fper.D5phi[
rYYYYZ] *= signz;
491 fper.D5phi[
rYZZZZ] *= signy;
493 fper.D5phi[
rXXXYY] *= signx;
494 fper.D5phi[
rXXXZZ] *= signx;
495 fper.D5phi[
rXXYYY] *= signy;
496 fper.D5phi[
rXXZZZ] *= signz;
497 fper.D5phi[
rYYYZZ] *= signy;
498 fper.D5phi[
rYYZZZ] *= signz;
500 fper.D5phi[
rXXYZZ] *= signy;
501 fper.D5phi[
rXXYYZ] *= signz;
502 fper.D5phi[
rXYYZZ] *= signx;
504 fper.D5phi[
rXXXYZ] *= signx * signy * signz;
505 fper.D5phi[
rXYYYZ] *= signx * signy * signz;
506 fper.D5phi[
rXYZZZ] *= signx * signy * signz;
508 fper.
D2phi += fper.
D3phi * off + 0.5 * ((fper.D4phi * off) * off) + (1.0 / 6) * (((fper.D5phi * off) * off) * off);
511#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 6
512 fper.D6phi[
pXXXXXY] *= signx * signy;
513 fper.D6phi[
pXXXXXZ] *= signx * signz;
514 fper.D6phi[
pXXXXYZ] *= signy * signz;
515 fper.D6phi[
pXXXYYY] *= signx * signy;
516 fper.D6phi[
pXXXYYZ] *= signx * signz;
517 fper.D6phi[
pXXXYZZ] *= signx * signy;
518 fper.D6phi[
pXXXZZZ] *= signx * signz;
519 fper.D6phi[
pXXYYYZ] *= signy * signz;
520 fper.D6phi[
pXXYZZZ] *= signy * signz;
521 fper.D6phi[
pXYYYYY] *= signx * signy;
522 fper.D6phi[
pXYYYYZ] *= signx * signz;
523 fper.D6phi[
pXYYYZZ] *= signx * signy;
524 fper.D6phi[
pXYYZZZ] *= signx * signz;
525 fper.D6phi[
pXYZZZZ] *= signx * signy;
526 fper.D6phi[
pXZZZZZ] *= signx * signz;
527 fper.D6phi[
pYYYYYZ] *= signy * signz;
528 fper.D6phi[
pYYYZZZ] *= signy * signz;
529 fper.D6phi[
pYZZZZZ] *= signy * signz;
531 fper.
D3phi += fper.D4phi * off + 0.5 * ((fper.D5phi * off) * off) + (1.0 / 6) * (((fper.D6phi * off) * off) * off);
534#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 7
539 fper.D7phi[
tXXXXXYZ] *= signx * signy * signz;
546 fper.D7phi[
tXXXYYYZ] *= signx * signy * signz;
548 fper.D7phi[
tXXXYZZZ] *= signx * signy * signz;
557 fper.D7phi[
tXYYYYYZ] *= signx * signy * signz;
559 fper.D7phi[
tXYYYZZZ] *= signx * signy * signz;
561 fper.D7phi[
tXYZZZZZ] *= signx * signy * signz;
572 fper.D4phi += fper.D5phi * off + 0.5 * ((fper.D6phi * off) * off) + (1.0 / 6) * (((fper.D7phi * off) * off) * off);
573 fper.D5phi += fper.D6phi * off + 0.5 * ((fper.D7phi * off) * off);
587#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 4
588 fper.D4phi[
sXXXY] *= signx * signy;
589 fper.D4phi[
sXYYY] *= signx * signy;
590 fper.D4phi[
sXXXZ] *= signx * signz;
591 fper.D4phi[
sXZZZ] *= signx * signz;
592 fper.D4phi[
sYYYZ] *= signy * signz;
593 fper.D4phi[
sYZZZ] *= signy * signz;
594 fper.D4phi[
sXXYZ] *= signy * signz;
595 fper.D4phi[
sXYYZ] *= signx * signz;
596 fper.D4phi[
sXYZZ] *= signx * signy;
598 fper.
D2phi += fper.
D3phi * off + 0.5 * ((fper.D4phi * off) * off);
601#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 5
602 fper.D5phi[
rXXXXX] *= signx;
603 fper.D5phi[
rYYYYY] *= signy;
604 fper.D5phi[
rZZZZZ] *= signz;
606 fper.D5phi[
rXXXXY] *= signy;
607 fper.D5phi[
rXXXXZ] *= signz;
608 fper.D5phi[
rXYYYY] *= signx;
609 fper.D5phi[
rXZZZZ] *= signx;
610 fper.D5phi[
rYYYYZ] *= signz;
611 fper.D5phi[
rYZZZZ] *= signy;
613 fper.D5phi[
rXXXYY] *= signx;
614 fper.D5phi[
rXXXZZ] *= signx;
615 fper.D5phi[
rXXYYY] *= signy;
616 fper.D5phi[
rXXZZZ] *= signz;
617 fper.D5phi[
rYYYZZ] *= signy;
618 fper.D5phi[
rYYZZZ] *= signz;
620 fper.D5phi[
rXXYZZ] *= signy;
621 fper.D5phi[
rXXYYZ] *= signz;
622 fper.D5phi[
rXYYZZ] *= signx;
624 fper.D5phi[
rXXXYZ] *= signx * signy * signz;
625 fper.D5phi[
rXYYYZ] *= signx * signy * signz;
626 fper.D5phi[
rXYZZZ] *= signx * signy * signz;
628 fper.
D3phi += fper.D4phi * off + 0.5 * ((fper.D5phi * off) * off);
631#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 6
632 fper.D6phi[
pXXXXXY] *= signx * signy;
633 fper.D6phi[
pXXXXXZ] *= signx * signz;
634 fper.D6phi[
pXXXXYZ] *= signy * signz;
635 fper.D6phi[
pXXXYYY] *= signx * signy;
636 fper.D6phi[
pXXXYYZ] *= signx * signz;
637 fper.D6phi[
pXXXYZZ] *= signx * signy;
638 fper.D6phi[
pXXXZZZ] *= signx * signz;
639 fper.D6phi[
pXXYYYZ] *= signy * signz;
640 fper.D6phi[
pXXYZZZ] *= signy * signz;
641 fper.D6phi[
pXYYYYY] *= signx * signy;
642 fper.D6phi[
pXYYYYZ] *= signx * signz;
643 fper.D6phi[
pXYYYZZ] *= signx * signy;
644 fper.D6phi[
pXYYZZZ] *= signx * signz;
645 fper.D6phi[
pXYZZZZ] *= signx * signy;
646 fper.D6phi[
pXZZZZZ] *= signx * signz;
647 fper.D6phi[
pYYYYYZ] *= signy * signz;
648 fper.D6phi[
pYYYZZZ] *= signy * signz;
649 fper.D6phi[
pYZZZZZ] *= signy * signz;
651 fper.D4phi += fper.D5phi * off + 0.5 * ((fper.D6phi * off) * off);
654#if(HIGHEST_NEEDEDORDER_EWALD_DPHI + EWALD_TAYLOR_ORDER) >= 7
659 fper.D7phi[
tXXXXXYZ] *= signx * signy * signz;
666 fper.D7phi[
tXXXYYYZ] *= signx * signy * signz;
668 fper.D7phi[
tXXXYZZZ] *= signx * signy * signz;
677 fper.D7phi[
tXYYYYYZ] *= signx * signy * signz;
679 fper.D7phi[
tXYYYZZZ] *= signx * signy * signz;
681 fper.D7phi[
tXYZZZZZ] *= signx * signy * signz;
692 fper.D5phi += fper.D6phi * off + 0.5 * ((fper.D7phi * off) * off);
707 static int printed = 0;
711#ifndef GRAVITY_TALLBOX
714 double alpha = 2.0 / leff;
715 double alpha2 = alpha * alpha;
717 int qxmax = (int)(8.0 *
LONG_X / alpha + 0.5);
718 int qymax = (int)(8.0 *
LONG_Y / alpha + 0.5);
719 int qzmax = (int)(8.0 *
LONG_Z / alpha + 0.5);
721 int nxmax = (int)(2.0 * alpha /
LONG_X + 0.5);
722 int nymax = (int)(2.0 * alpha /
LONG_Y + 0.5);
723 int nzmax = (int)(2.0 * alpha /
LONG_Z + 0.5);
727 mpi_printf(
"EWALD: D0 table: qxmax=%d qymax=%d qzmax=%d nxmax=%d nymax=%d nzmax=%d\n", qxmax, qymax, qzmax, nxmax, nymax,
732 for(
int nx = -qxmax; nx <= qxmax; nx++)
733 for(
int ny = -qymax; ny <= qymax; ny++)
734 for(
int nz = -qzmax; nz <= qzmax; nz++)
736 double dx = x - nx * (1.0 /
LONG_X);
737 double dy = y - ny * (1.0 /
LONG_Y);
738 double dz = z - nz * (1.0 /
LONG_Z);
740 double r2 = dx * dx + dy * dy + dz * dz;
743 double rinv = (r > 0) ? 1.0 / r : 0.0;
747 if(nx != 0 || ny != 0 || nz != 0)
749 g0 = -
erfc(alpha * r) * rinv;
762 if((alpha * r) < 0.5)
765 (1.0 -
pow(alpha * r, 2) / 3.0 +
pow(alpha * r, 4) / 10.0 -
pow(alpha * r, 6) / 42.0 +
766 pow(alpha * r, 8) / 216.0 -
pow(alpha * r, 10) / 1320.0);
770 g0 =
erf(alpha * r) * rinv;
777 for(
int nx = -nxmax; nx <= nxmax; nx++)
778 for(
int ny = -nymax; ny <= nymax; ny++)
779 for(
int nz = -nzmax; nz <= nzmax; nz++)
781 if(nx != 0 || ny != 0 || nz != 0)
786 double k2 = kx * kx + ky * ky + kz * kz;
787 double kdotx = (x * kx + y * ky + z * kz);
798 double leff =
sqrt(BOXX * BOXY);
799 double alpha = 2.0 / leff;
801 int qxmax = (int)(8.0 / (BOXX * alpha) + 0.5);
802 int qymax = (int)(8.0 / (BOXY * alpha) + 0.5);
804 int nxmax = (int)(2.0 * alpha * BOXX + 0.5);
805 int nymax = (int)(2.0 * alpha * BOXY + 0.5);
809 mpi_printf(
"EWALD: D0 table: qxmax=%d qymax=%d nxmax=%d nymax=%d\n", qxmax, qymax, nxmax, nymax);
813 for(
int nx = -qxmax; nx <= qxmax; nx++)
814 for(
int ny = -qymax; ny <= qymax; ny++)
816 double dx = x - nx * BOXX;
817 double dy = y - ny * BOXY;
818 double r =
sqrt(dx * dx + dy * dy + z * z);
820 double rinv = (r > 0) ? 1.0 / r : 0.0;
824 if(nx != 0 || ny != 0)
826 g0 = -
erfc(alpha * r) * rinv;
832 if((alpha * r) < 0.5)
835 (1.0 -
pow(alpha * r, 2) / 3.0 +
pow(alpha * r, 4) / 10.0 -
pow(alpha * r, 6) / 42.0 +
pow(alpha * r, 8) / 216.0 -
836 pow(alpha * r, 10) / 1320.0);
840 g0 =
erf(alpha * r) * rinv;
847 double alpha2 = alpha * alpha;
849 for(
int nx = -nxmax; nx <= nxmax; nx++)
850 for(
int ny = -nymax; ny <= nymax; ny++)
852 if(nx != 0 || ny != 0)
854 double kx = (2.0 *
M_PI / BOXX) * nx;
855 double ky = (2.0 *
M_PI / BOXY) * ny;
856 double k2 = kx * kx + ky * ky;
859 double ex =
exp(-k * z);
862 D0 += -
M_PI / (BOXX * BOXY) *
cos(kx * x + ky * y) / k * (specerf(z, k, alpha) + specerf(-z, k, alpha));
873double ewald::specerf(
double z,
double k,
double alpha) {
return exp(k * z) *
erfc(k / (2 * alpha) + alpha * z); }
875double ewald::d_specerf(
double z,
double k,
double alpha)
877 return -2 * alpha / (
sqrt(
M_PI) *
exp(
pow(k / (2 * alpha), 2) +
pow(alpha * z, 2))) + k * specerf(z, k, alpha);
880double ewald::dd_specerf(
double z,
double k,
double alpha)
882 return +4 *
pow(alpha, 3) * z / (
sqrt(
M_PI) *
exp(
pow(k / (2 * alpha), 2) +
pow(alpha * z, 2))) + k * d_specerf(z, k, alpha);
885double ewald::ddd_specerf(
double z,
double k,
double alpha)
888 8 *
pow(alpha, 5) * z * z / (
sqrt(
M_PI) *
exp(
pow(k / (2 * alpha), 2) +
pow(alpha * z, 2))) + k * dd_specerf(z, k, alpha);
900 static int printed = 0;
904#ifndef GRAVITY_TALLBOX
907 double alpha = 2.0 / leff;
908 double alpha2 = alpha * alpha;
910 int qxmax = (int)(8.0 *
LONG_X / alpha + 0.5);
911 int qymax = (int)(8.0 *
LONG_Y / alpha + 0.5);
912 int qzmax = (int)(8.0 *
LONG_Z / alpha + 0.5);
914 int nxmax = (int)(2.0 * alpha /
LONG_X + 0.5);
915 int nymax = (int)(2.0 * alpha /
LONG_Y + 0.5);
916 int nzmax = (int)(2.0 * alpha /
LONG_Z + 0.5);
920 mpi_printf(
"EWALD: D1 table: qxmax=%d qymax=%d qzmax=%d nxmax=%d nymax=%d nzmax=%d\n", qxmax, qymax, qzmax, nxmax, nymax,
925 for(
int nx = -qxmax; nx <= qxmax; nx++)
926 for(
int ny = -qymax; ny <= qymax; ny++)
927 for(
int nz = -qzmax; nz <= qzmax; nz++)
929 double dx = x - nx * (1.0 /
LONG_X);
930 double dy = y - ny * (1.0 /
LONG_Y);
931 double dz = z - nz * (1.0 /
LONG_Z);
935 double r2 = dx * dx + dy * dy + dz * dz;
938 double rinv = (r > 0) ? 1.0 / r : 0.0;
939 double r2inv = rinv * rinv;
940 double r3inv = r2inv * rinv;
944 if(nx != 0 || ny != 0 || nz != 0)
946 g1 = (
erfc(alpha * r) + 2.0 * alpha * r /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r3inv;
968 if((alpha * r) < 0.5)
971 (-1.0 / 3.0 +
pow(alpha * r, 2) / 5.0 -
pow(alpha * r, 4) / 14.0 +
pow(alpha * r, 6) / 54.0 -
972 pow(alpha * r, 8) / 264.0 +
pow(alpha * r, 10) / 1560.0);
976 g1 = (-
erf(alpha * r) + 2.0 * alpha * r /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r3inv;
983 for(
int nx = -nxmax; nx <= nxmax; nx++)
984 for(
int ny = -nymax; ny <= nymax; ny++)
985 for(
int nz = -nzmax; nz <= nzmax; nz++)
990 double k2 = kx * kx + ky * ky + kz * kz;
994 double kdotx = (x * kx + y * ky + z * kz);
1004 double leff =
sqrt(BOXX * BOXY);
1005 double alpha = 2.0 / leff;
1006 double alpha2 = alpha * alpha;
1008 int qxmax = (int)(8.0 / (BOXX * alpha) + 0.5);
1009 int qymax = (int)(8.0 / (BOXY * alpha) + 0.5);
1011 int nxmax = (int)(2.0 * alpha * BOXX + 0.5);
1012 int nymax = (int)(2.0 * alpha * BOXY + 0.5);
1016 mpi_printf(
"EWALD: D1 table: qxmax=%d qymax=%d nxmax=%d nymax=%d\n", qxmax, qymax, nxmax, nymax);
1020 for(
int nx = -qxmax; nx <= qxmax; nx++)
1021 for(
int ny = -qymax; ny <= qymax; ny++)
1023 double dx = x - nx * BOXX;
1024 double dy = y - ny * BOXY;
1029 double r2 = dx * dx + dy * dy + dz * dz;
1030 double r =
sqrt(r2);
1032 double rinv = (r > 0) ? 1.0 / r : 0.0;
1033 double r2inv = rinv * rinv;
1034 double r3inv = r2inv * rinv;
1038 if(nx != 0 || ny != 0)
1040 g1 = (
erfc(alpha * r) + 2.0 * alpha * r /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r3inv;
1046 if((alpha * r) < 0.5)
1049 (-1.0 / 3.0 +
pow(alpha * r, 2) / 5.0 -
pow(alpha * r, 4) / 14.0 +
pow(alpha * r, 6) / 54.0 -
1050 pow(alpha * r, 8) / 264.0 +
pow(alpha * r, 10) / 1560.0);
1054 g1 = (-
erf(alpha * r) + 2.0 * alpha * r /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r3inv;
1061 for(
int nx = -nxmax; nx <= nxmax; nx++)
1062 for(
int ny = -nymax; ny <= nymax; ny++)
1064 if(nx != 0 || ny != 0)
1066 double kx = (2.0 *
M_PI / BOXX) * nx;
1067 double ky = (2.0 *
M_PI / BOXY) * ny;
1068 double k2 = kx * kx + ky * ky;
1069 double k =
sqrt(k2);
1071 double ex =
exp(-k * z);
1075 double val =
M_PI / (BOXX * BOXY) / k * (specerf(z, k, alpha) + specerf(-z, k, alpha));
1077 D1[0] += kx * val *
sin(kx * x + ky * y);
1078 D1[1] += ky * val *
sin(kx * x + ky * y);
1079 D1[2] += -
M_PI / (BOXX * BOXY) *
cos(kx * x + ky * y) / k * (d_specerf(z, k, alpha) - d_specerf(-z, k, alpha));
1084 D1[2] += 2.0 *
M_PI / (BOXX * BOXY) *
erf(alpha * z);
1092 static int printed = 0;
1096#ifndef GRAVITY_TALLBOX
1099 double alpha = 2.0 / leff;
1100 double alpha2 = alpha * alpha;
1102 int qxmax = (int)(8.0 *
LONG_X / alpha + 0.5);
1103 int qymax = (int)(8.0 *
LONG_Y / alpha + 0.5);
1104 int qzmax = (int)(8.0 *
LONG_Z / alpha + 0.5);
1106 int nxmax = (int)(2.0 * alpha /
LONG_X + 0.5);
1107 int nymax = (int)(2.0 * alpha /
LONG_Y + 0.5);
1108 int nzmax = (int)(2.0 * alpha /
LONG_Z + 0.5);
1112 mpi_printf(
"EWALD: D2 table: qxmax=%d qymax=%d qzmax=%d nxmax=%d nymax=%d nzmax=%d\n", qxmax, qymax, qzmax, nxmax, nymax,
1117 for(
int nx = -qxmax; nx <= qxmax; nx++)
1118 for(
int ny = -qymax; ny <= qymax; ny++)
1119 for(
int nz = -qzmax; nz <= qzmax; nz++)
1121 double dx = x - nx * (1.0 /
LONG_X);
1122 double dy = y - ny * (1.0 /
LONG_Y);
1123 double dz = z - nz * (1.0 /
LONG_Z);
1127 double r2 = dx * dx + dy * dy + dz * dz;
1128 double r =
sqrt(r2);
1130 double rinv = (r > 0) ? 1.0 / r : 0.0;
1131 double r2inv = rinv * rinv;
1132 double r3inv = r2inv * rinv;
1133 double r5inv = r3inv * r2inv;
1137 if(nx != 0 || ny != 0 || nz != 0)
1139 g1 = (
erfc(alpha * r) + 2.0 * alpha * r /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r3inv;
1141 g2 = -(3.0 *
erfc(alpha * r) + (6.0 * alpha * r + 4.0 *
pow(alpha * r, 3)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r5inv;
1163 if((alpha * r) < 0.5)
1166 (-1.0 / 3.0 +
pow(alpha * r, 2) / 5.0 -
pow(alpha * r, 4) / 14.0 +
pow(alpha * r, 6) / 54.0 -
1167 pow(alpha * r, 8) / 264.0 +
pow(alpha * r, 10) / 1560.0);
1170 (1.0 / 5.0 -
pow(alpha * r, 2) / 7.0 +
pow(alpha * r, 4) / 18.0 -
pow(alpha * r, 6) / 66.0 +
1171 pow(alpha * r, 8) / 312.0 -
pow(alpha * r, 10) / 1800.0);
1175 g1 = (-
erf(alpha * r) + 2.0 * alpha * r /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r3inv;
1177 g2 = (3.0 *
erf(alpha * r) - (6.0 * alpha * r + 4.0 *
pow(alpha * r, 3)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r5inv;
1181 D2 += g2 * (dxyz % dxyz);
1187 for(
int nx = -nxmax; nx <= nxmax; nx++)
1188 for(
int ny = -nymax; ny <= nymax; ny++)
1189 for(
int nz = -nzmax; nz <= nzmax; nz++)
1191 if(nx != 0 || ny != 0 || nz != 0)
1196 double k2 = kx * kx + ky * ky + kz * kz;
1198 double kdotx = (x * kx + y * ky + z * kz);
1203 D2 += (val * kxyz) % kxyz;
1210 double leff =
sqrt(BOXX * BOXY);
1211 double alpha = 2.0 / leff;
1212 double alpha2 = alpha * alpha;
1214 int qxmax = (int)(8.0 / (BOXX * alpha) + 0.5);
1215 int qymax = (int)(8.0 / (BOXY * alpha) + 0.5);
1217 int nxmax = (int)(2.0 * alpha * BOXX + 0.5);
1218 int nymax = (int)(2.0 * alpha * BOXY + 0.5);
1222 mpi_printf(
"EWALD: D2 table: qxmax=%d qymax=%d nxmax=%d nymax=%d\n", qxmax, qymax, nxmax, nymax);
1226 for(
int nx = -qxmax; nx <= qxmax; nx++)
1227 for(
int ny = -qymax; ny <= qymax; ny++)
1229 double dx = x - nx * BOXX;
1230 double dy = y - ny * BOXY;
1235 double r2 = dx * dx + dy * dy + dz * dz;
1236 double r =
sqrt(r2);
1238 double rinv = (r > 0) ? 1.0 / r : 0.0;
1239 double r2inv = rinv * rinv;
1240 double r3inv = r2inv * rinv;
1241 double r5inv = r3inv * r2inv;
1245 if(nx != 0 || ny != 0)
1247 g1 = (
erfc(alpha * r) + 2.0 * alpha * r /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r3inv;
1249 g2 = -(3.0 *
erfc(alpha * r) + (6.0 * alpha * r + 4.0 *
pow(alpha * r, 3)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r5inv;
1255 if((alpha * r) < 0.5)
1258 (-1.0 / 3.0 +
pow(alpha * r, 2) / 5.0 -
pow(alpha * r, 4) / 14.0 +
pow(alpha * r, 6) / 54.0 -
1259 pow(alpha * r, 8) / 264.0 +
pow(alpha * r, 10) / 1560.0);
1262 (1.0 / 5.0 -
pow(alpha * r, 2) / 7.0 +
pow(alpha * r, 4) / 18.0 -
pow(alpha * r, 6) / 66.0 +
1263 pow(alpha * r, 8) / 312.0 -
pow(alpha * r, 10) / 1800.0);
1267 g1 = (-
erf(alpha * r) + 2.0 * alpha * r /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r3inv;
1269 g2 = (3.0 *
erf(alpha * r) - (6.0 * alpha * r + 4.0 *
pow(alpha * r, 3)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r5inv;
1273 D2 += g2 * (dxyz % dxyz);
1279 for(
int nx = -nxmax; nx <= nxmax; nx++)
1280 for(
int ny = -nymax; ny <= nymax; ny++)
1282 if(nx != 0 || ny != 0)
1284 double kx = (2.0 *
M_PI / BOXX) * nx;
1285 double ky = (2.0 *
M_PI / BOXY) * ny;
1286 double k2 = kx * kx + ky * ky;
1287 double k =
sqrt(k2);
1289 double ex =
exp(-k * z);
1293 double val =
M_PI / (BOXX * BOXY) / k * (specerf(z, k, alpha) + specerf(-z, k, alpha));
1294 double dzval =
M_PI / (BOXX * BOXY) / k * (d_specerf(z, k, alpha) - d_specerf(-z, k, alpha));
1296 D2[
qXX] += kx * kx * val *
cos(kx * x + ky * y);
1297 D2[
qXY] += kx * ky * val *
cos(kx * x + ky * y);
1298 D2[
qXZ] += kx * dzval *
sin(kx * x + ky * y);
1299 D2[
qYY] += ky * ky * val *
cos(kx * x + ky * y);
1300 D2[
qYZ] += ky * dzval *
sin(kx * x + ky * y);
1301 D2[
qZZ] += -
M_PI / (BOXX * BOXY) *
cos(kx * x + ky * y) / k * (dd_specerf(z, k, alpha) + dd_specerf(-z, k, alpha));
1314 static int printed = 0;
1318#ifndef GRAVITY_TALLBOX
1321 double alpha = 2.0 / leff;
1322 double alpha2 = alpha * alpha;
1324 int qxmax = (int)(8.0 *
LONG_X / alpha + 0.5);
1325 int qymax = (int)(8.0 *
LONG_Y / alpha + 0.5);
1326 int qzmax = (int)(8.0 *
LONG_Z / alpha + 0.5);
1328 int nxmax = (int)(2.0 * alpha /
LONG_X + 0.5);
1329 int nymax = (int)(2.0 * alpha /
LONG_Y + 0.5);
1330 int nzmax = (int)(2.0 * alpha /
LONG_Z + 0.5);
1334 mpi_printf(
"EWALD: D3 table: qxmax=%d qymax=%d qzmax=%d nxmax=%d nymax=%d nzmax=%d\n", qxmax, qymax, qzmax, nxmax, nymax,
1339 for(
int nx = -qxmax; nx <= qxmax; nx++)
1340 for(
int ny = -qymax; ny <= qymax; ny++)
1341 for(
int nz = -qzmax; nz <= qzmax; nz++)
1343 double dx = x - nx * (1.0 /
LONG_X);
1344 double dy = y - ny * (1.0 /
LONG_Y);
1345 double dz = z - nz * (1.0 /
LONG_Z);
1349 double r2 = dx * dx + dy * dy + dz * dz;
1350 double r =
sqrt(r2);
1352 double rinv = (r > 0) ? 1.0 / r : 0.0;
1353 double r2inv = rinv * rinv;
1354 double r3inv = r2inv * rinv;
1355 double r4inv = r2inv * r2inv;
1356 double r5inv = r2inv * r3inv;
1357 double r7inv = r3inv * r4inv;
1361 if(nx != 0 || ny != 0 || nz != 0)
1363 g2 = -(3.0 *
erfc(alpha * r) + (6.0 * alpha * r + 4.0 *
pow(alpha * r, 3)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r5inv;
1365 g3 = (15.0 *
erfc(alpha * r) +
1366 (30.0 * alpha * r + 20.0 *
pow(alpha * r, 3) + 8.0 *
pow(alpha * r, 5)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) *
1388 if((alpha * r) < 0.5)
1391 (1.0 / 5.0 -
pow(alpha * r, 2) / 7.0 +
pow(alpha * r, 4) / 18.0 -
pow(alpha * r, 6) / 66.0 +
1392 pow(alpha * r, 8) / 312.0 -
pow(alpha * r, 10) / 1800.0);
1395 (-1.0 / 7.0 +
pow(alpha * r, 2) / 9.0 -
pow(alpha * r, 4) / 22.0 +
pow(alpha * r, 6) / 78.0 -
1396 pow(alpha * r, 8) / 360.0 +
pow(alpha * r, 10) / 2040.0);
1400 g2 = (3.0 *
erf(alpha * r) - (6.0 * alpha * r + 4.0 *
pow(alpha * r, 3)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r5inv;
1402 g3 = (-15.0 *
erf(alpha * r) +
1403 (30.0 * alpha * r + 20.0 *
pow(alpha * r, 3) + 8.0 *
pow(alpha * r, 5)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) *
1414 for(
int nx = -nxmax; nx <= nxmax; nx++)
1415 for(
int ny = -nymax; ny <= nymax; ny++)
1416 for(
int nz = -nzmax; nz <= nzmax; nz++)
1418 if(nx != 0 || ny != 0 || nz != 0)
1423 double k2 = kx * kx + ky * ky + kz * kz;
1425 double kdotx = (x * kx + y * ky + z * kz);
1430 D3 += (val * kxyz) % (kxyz % kxyz);
1438 double leff =
sqrt(BOXX * BOXY);
1439 double alpha = 2.0 / leff;
1440 double alpha2 = alpha * alpha;
1442 int qxmax = (int)(8.0 / (BOXX * alpha) + 0.5);
1443 int qymax = (int)(8.0 / (BOXY * alpha) + 0.5);
1445 int nxmax = (int)(2.0 * alpha * BOXX + 0.5);
1446 int nymax = (int)(2.0 * alpha * BOXY + 0.5);
1450 mpi_printf(
"EWALD: D2 table: qxmax=%d qymax=%d nxmax=%d nymax=%d\n", qxmax, qymax, nxmax, nymax);
1454 for(
int nx = -qxmax; nx <= qxmax; nx++)
1455 for(
int ny = -qymax; ny <= qymax; ny++)
1457 double dx = x - nx * BOXX;
1458 double dy = y - ny * BOXY;
1463 double r2 = dx * dx + dy * dy + dz * dz;
1464 double r =
sqrt(r2);
1466 double rinv = (r > 0) ? 1.0 / r : 0.0;
1467 double r2inv = rinv * rinv;
1468 double r3inv = r2inv * rinv;
1469 double r4inv = r2inv * r2inv;
1470 double r5inv = r2inv * r3inv;
1471 double r7inv = r3inv * r4inv;
1475 if(nx != 0 || ny != 0)
1477 g2 = -(3.0 *
erfc(alpha * r) + (6.0 * alpha * r + 4.0 *
pow(alpha * r, 3)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r5inv;
1479 g3 = (15.0 *
erfc(alpha * r) +
1480 (30.0 * alpha * r + 20.0 *
pow(alpha * r, 3) + 8.0 *
pow(alpha * r, 5)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) *
1485 if((alpha * r) < 0.5)
1488 (1.0 / 5.0 -
pow(alpha * r, 2) / 7.0 +
pow(alpha * r, 4) / 18.0 -
pow(alpha * r, 6) / 66.0 +
1489 pow(alpha * r, 8) / 312.0 -
pow(alpha * r, 10) / 1800.0);
1492 (-1.0 / 7.0 +
pow(alpha * r, 2) / 9.0 -
pow(alpha * r, 4) / 22.0 +
pow(alpha * r, 6) / 78.0 -
1493 pow(alpha * r, 8) / 360.0 +
pow(alpha * r, 10) / 2040.0);
1497 g2 = (3.0 *
erf(alpha * r) - (6.0 * alpha * r + 4.0 *
pow(alpha * r, 3)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r5inv;
1499 g3 = (-15.0 *
erf(alpha * r) +
1500 (30.0 * alpha * r + 20.0 *
pow(alpha * r, 3) + 8.0 *
pow(alpha * r, 5)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) *
1511 for(
int nx = -nxmax; nx <= nxmax; nx++)
1512 for(
int ny = -nymax; ny <= nymax; ny++)
1514 if(nx != 0 || ny != 0)
1516 double kx = (2.0 *
M_PI / BOXX) * nx;
1517 double ky = (2.0 *
M_PI / BOXY) * ny;
1518 double k2 = kx * kx + ky * ky;
1519 double k =
sqrt(k2);
1521 double ex =
exp(-k * z);
1525 double val =
M_PI / (BOXX * BOXY) / k * (specerf(z, k, alpha) + specerf(-z, k, alpha));
1526 double dzval =
M_PI / (BOXX * BOXY) / k * (d_specerf(z, k, alpha) - d_specerf(-z, k, alpha));
1527 double dzdzval =
M_PI / (BOXX * BOXY) / k * (dd_specerf(z, k, alpha) + dd_specerf(-z, k, alpha));
1529 D3[
dXXX] += -kx * kx * kx * val *
sin(kx * x + ky * y);
1530 D3[
dXXY] += -kx * kx * ky * val *
sin(kx * x + ky * y);
1531 D3[
dXXZ] += kx * kx * dzval *
cos(kx * x + ky * y);
1532 D3[
dXYY] += -kx * ky * ky * val *
sin(kx * x + ky * y);
1533 D3[
dXYZ] += kx * ky * dzval *
cos(kx * x + ky * y);
1534 D3[
dXZZ] += kx * dzdzval *
sin(kx * x + ky * y);
1535 D3[
dYYY] += -ky * ky * ky * val *
sin(kx * x + ky * y);
1536 D3[
dYYZ] += ky * ky * dzval *
cos(kx * x + ky * y);
1537 D3[
dYZZ] += ky * dzdzval *
sin(kx * x + ky * y);
1538 D3[
dZZZ] += -
M_PI / (BOXX * BOXY) *
cos(kx * x + ky * y) / k * (ddd_specerf(z, k, alpha) - ddd_specerf(-z, k, alpha));
1552 static int printed = 0;
1554#ifdef GRAVITY_TALLBOX
1555 Terminate(
"GRAVITY_TALLBOX is not implemented for MULTIPOLE_ORDER >= 4");
1561 double alpha = 2.0 / leff;
1562 double alpha2 = alpha * alpha;
1564 int qxmax = (int)(8.0 *
LONG_X / alpha + 0.5);
1565 int qymax = (int)(8.0 *
LONG_Y / alpha + 0.5);
1566 int qzmax = (int)(8.0 *
LONG_Z / alpha + 0.5);
1568 int nxmax = (int)(2.0 * alpha /
LONG_X + 0.5);
1569 int nymax = (int)(2.0 * alpha /
LONG_Y + 0.5);
1570 int nzmax = (int)(2.0 * alpha /
LONG_Z + 0.5);
1574 mpi_printf(
"EWALD: D4 table: qxmax=%d qymax=%d qzmax=%d nxmax=%d nymax=%d nzmax=%d\n", qxmax, qymax, qzmax, nxmax, nymax,
1579 for(
int nx = -qxmax; nx <= qxmax; nx++)
1580 for(
int ny = -qymax; ny <= qymax; ny++)
1581 for(
int nz = -qzmax; nz <= qzmax; nz++)
1583 double dx = x - nx * (1.0 /
LONG_X);
1584 double dy = y - ny * (1.0 /
LONG_Y);
1585 double dz = z - nz * (1.0 /
LONG_Z);
1589 double r2 = dx * dx + dy * dy + dz * dz;
1590 double r =
sqrt(r2);
1592 double rinv = (r > 0) ? 1.0 / r : 0.0;
1593 double r2inv = rinv * rinv;
1594 double r3inv = r2inv * rinv;
1595 double r4inv = r2inv * r2inv;
1596 double r5inv = r2inv * r3inv;
1597 double r7inv = r3inv * r4inv;
1598 double r9inv = r4inv * r5inv;
1602 if(nx != 0 || ny != 0 || nz != 0)
1604 g2 = -(3.0 *
erfc(alpha * r) + (6.0 * alpha * r + 4.0 *
pow(alpha * r, 3)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r5inv;
1606 g3 = (15.0 *
erfc(alpha * r) +
1607 (30.0 * alpha * r + 20.0 *
pow(alpha * r, 3) + 8.0 *
pow(alpha * r, 5)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) *
1610 g4 = -(105.0 *
erfc(alpha * r) +
1611 (210.0 * alpha * r + 140.0 *
pow(alpha * r, 3) + 56.0 *
pow(alpha * r, 5) + 16.0 *
pow(alpha * r, 7)) /
1635 if((alpha * r) < 0.5)
1638 (1.0 / 5.0 -
pow(alpha * r, 2) / 7.0 +
pow(alpha * r, 4) / 18.0 -
pow(alpha * r, 6) / 66.0 +
1639 pow(alpha * r, 8) / 312.0 -
pow(alpha * r, 10) / 1800.0);
1642 (-1.0 / 7.0 +
pow(alpha * r, 2) / 9.0 -
pow(alpha * r, 4) / 22.0 +
pow(alpha * r, 6) / 78.0 -
1643 pow(alpha * r, 8) / 360.0 +
pow(alpha * r, 10) / 2040.0);
1646 (1.0 / 9.0 -
pow(alpha * r, 2) / 11.0 +
pow(alpha * r, 4) / 26.0 -
pow(alpha * r, 6) / 90.0 +
1647 pow(alpha * r, 8) / 408.0 -
pow(alpha * r, 10) / 2280.0);
1651 g2 = (3.0 *
erf(alpha * r) - (6.0 * alpha * r + 4.0 *
pow(alpha * r, 3)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) * r5inv;
1653 g3 = (-15.0 *
erf(alpha * r) +
1654 (30.0 * alpha * r + 20.0 *
pow(alpha * r, 3) + 8.0 *
pow(alpha * r, 5)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) *
1657 g4 = (105.0 *
erf(alpha * r) -
1658 (210.0 * alpha * r + 140.0 *
pow(alpha * r, 3) + 56.0 *
pow(alpha * r, 5) + 16.0 *
pow(alpha * r, 7)) /
1668 setup_D4(
ADD, D4, dxyz, aux2, aux3, aux4, g2, g3, g4);
1671 for(
int nx = -nxmax; nx <= nxmax; nx++)
1672 for(
int ny = -nymax; ny <= nymax; ny++)
1673 for(
int nz = -nzmax; nz <= nzmax; nz++)
1675 if(nx != 0 || ny != 0 || nz != 0)
1680 double k2 = kx * kx + ky * ky + kz * kz;
1682 double kdotx = (x * kx + y * ky + z * kz);
1687 D4 += (val * kxyz) % ((kxyz % (kxyz % kxyz)));
1696 static int printed = 0;
1698#ifdef GRAVITY_TALLBOX
1699 Terminate(
"GRAVITY_TALLBOX is not implemented for MULTIPOLE_ORDER >= 4");
1705 double alpha = 2.0 / leff;
1706 double alpha2 = alpha * alpha;
1708 int qxmax = (int)(8.0 *
LONG_X / alpha + 0.5);
1709 int qymax = (int)(8.0 *
LONG_Y / alpha + 0.5);
1710 int qzmax = (int)(8.0 *
LONG_Z / alpha + 0.5);
1712 int nxmax = (int)(2.0 * alpha /
LONG_X + 0.5);
1713 int nymax = (int)(2.0 * alpha /
LONG_Y + 0.5);
1714 int nzmax = (int)(2.0 * alpha /
LONG_Z + 0.5);
1718 mpi_printf(
"EWALD: D5 table: qxmax=%d qymax=%d qzmax=%d nxmax=%d nymax=%d nzmax=%d\n", qxmax, qymax, qzmax, nxmax, nymax,
1723 for(
int nx = -qxmax; nx <= qxmax; nx++)
1724 for(
int ny = -qymax; ny <= qymax; ny++)
1725 for(
int nz = -qzmax; nz <= qzmax; nz++)
1727 double dx = x - nx * (1.0 /
LONG_X);
1728 double dy = y - ny * (1.0 /
LONG_Y);
1729 double dz = z - nz * (1.0 /
LONG_Z);
1733 double r2 = dx * dx + dy * dy + dz * dz;
1734 double r =
sqrt(r2);
1736 double rinv = (r > 0) ? 1.0 / r : 0.0;
1737 double r2inv = rinv * rinv;
1738 double r3inv = r2inv * rinv;
1739 double r4inv = r2inv * r2inv;
1740 double r5inv = r2inv * r3inv;
1741 double r7inv = r3inv * r4inv;
1742 double r9inv = r4inv * r5inv;
1743 double r11inv = r4inv * r7inv;
1747 if(nx != 0 || ny != 0 || nz != 0)
1749 g3 = (15.0 *
erfc(alpha * r) +
1750 (30.0 * alpha * r + 20.0 *
pow(alpha * r, 3) + 8.0 *
pow(alpha * r, 5)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) *
1753 g4 = -(105.0 *
erfc(alpha * r) +
1754 (210.0 * alpha * r + 140.0 *
pow(alpha * r, 3) + 56.0 *
pow(alpha * r, 5) + 16.0 *
pow(alpha * r, 7)) /
1758 g5 = (945.0 *
erfc(alpha * r) + (1890.0 * alpha * r + 1260.0 *
pow(alpha * r, 3) + 504.0 *
pow(alpha * r, 5) +
1759 144.0 *
pow(alpha * r, 7) + 32.0 *
pow(alpha * r, 9)) /
1783 if((alpha * r) < 0.5)
1786 (-1.0 / 7.0 +
pow(alpha * r, 2) / 9.0 -
pow(alpha * r, 4) / 22.0 +
pow(alpha * r, 6) / 78.0 -
1787 pow(alpha * r, 8) / 360.0 +
pow(alpha * r, 10) / 2040.0);
1790 (1.0 / 9.0 -
pow(alpha * r, 2) / 11.0 +
pow(alpha * r, 4) / 26.0 -
pow(alpha * r, 6) / 90.0 +
1791 pow(alpha * r, 8) / 408.0 -
pow(alpha * r, 10) / 2280.0);
1794 (-1.0 / 11.0 +
pow(alpha * r, 2) / 13.0 -
pow(alpha * r, 4) / 30.0 +
pow(alpha * r, 6) / 102.0 -
1795 pow(alpha * r, 8) / 456.0 +
pow(alpha * r, 10) / 2520.0);
1799 g3 = (-15.0 *
erf(alpha * r) +
1800 (30.0 * alpha * r + 20.0 *
pow(alpha * r, 3) + 8.0 *
pow(alpha * r, 5)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) *
1803 g4 = (105.0 *
erf(alpha * r) -
1804 (210.0 * alpha * r + 140.0 *
pow(alpha * r, 3) + 56.0 *
pow(alpha * r, 5) + 16.0 *
pow(alpha * r, 7)) /
1808 g5 = (-945.0 *
erf(alpha * r) + (1890.0 * alpha * r + 1260.0 *
pow(alpha * r, 3) + 504.0 *
pow(alpha * r, 5) +
1809 144.0 *
pow(alpha * r, 7) + 32.0 *
pow(alpha * r, 9)) /
1819 setup_D5(
ADD, D5, dxyz, aux3, aux4, aux5, g3, g4, g5);
1822 for(
int nx = -nxmax; nx <= nxmax; nx++)
1823 for(
int ny = -nymax; ny <= nymax; ny++)
1824 for(
int nz = -nzmax; nz <= nzmax; nz++)
1829 double k2 = kx * kx + ky * ky + kz * kz;
1833 double kdotx = (x * kx + y * ky + z * kz);
1838 D5 += (val * kxyz) % (kxyz % ((kxyz % (kxyz % kxyz))));
1847 static int printed = 0;
1849#ifdef GRAVITY_TALLBOX
1850 Terminate(
"GRAVITY_TALLBOX is not implemented for MULTIPOLE_ORDER >= 4");
1856 double alpha = 2.0 / leff;
1857 double alpha2 = alpha * alpha;
1859 int qxmax = (int)(8.0 *
LONG_X / alpha + 0.5);
1860 int qymax = (int)(8.0 *
LONG_Y / alpha + 0.5);
1861 int qzmax = (int)(8.0 *
LONG_Z / alpha + 0.5);
1863 int nxmax = (int)(2.0 * alpha /
LONG_X + 0.5);
1864 int nymax = (int)(2.0 * alpha /
LONG_Y + 0.5);
1865 int nzmax = (int)(2.0 * alpha /
LONG_Z + 0.5);
1869 mpi_printf(
"EWALD: D6 table: qxmax=%d qymax=%d qzmax=%d nxmax=%d nymax=%d nzmax=%d\n", qxmax, qymax, qzmax, nxmax, nymax,
1874 for(
int nx = -qxmax; nx <= qxmax; nx++)
1875 for(
int ny = -qymax; ny <= qymax; ny++)
1876 for(
int nz = -qzmax; nz <= qzmax; nz++)
1878 double dx = x - nx * (1.0 /
LONG_X);
1879 double dy = y - ny * (1.0 /
LONG_Y);
1880 double dz = z - nz * (1.0 /
LONG_Z);
1884 double r2 = dx * dx + dy * dy + dz * dz;
1885 double r =
sqrt(r2);
1887 double rinv = (r > 0) ? 1.0 / r : 0.0;
1888 double r2inv = rinv * rinv;
1889 double r3inv = r2inv * rinv;
1890 double r4inv = r2inv * r2inv;
1891 double r5inv = r2inv * r3inv;
1892 double r7inv = r3inv * r4inv;
1893 double r9inv = r4inv * r5inv;
1894 double r11inv = r4inv * r7inv;
1895 double r13inv = r4inv * r9inv;
1897 double g3, g4, g5, g6;
1899 if(nx != 0 || ny != 0 || nz != 0)
1901 g3 = (15.0 *
erfc(alpha * r) +
1902 (30.0 * alpha * r + 20.0 *
pow(alpha * r, 3) + 8.0 *
pow(alpha * r, 5)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) *
1905 g4 = -(105.0 *
erfc(alpha * r) +
1906 (210.0 * alpha * r + 140.0 *
pow(alpha * r, 3) + 56.0 *
pow(alpha * r, 5) + 16.0 *
pow(alpha * r, 7)) /
1910 g5 = (945.0 *
erfc(alpha * r) + (1890.0 * alpha * r + 1260.0 *
pow(alpha * r, 3) + 504.0 *
pow(alpha * r, 5) +
1911 144.0 *
pow(alpha * r, 7) + 32.0 *
pow(alpha * r, 9)) /
1915 g6 = (-10395.0 *
erfc(alpha * r) -
1917 (10395.0 * alpha * r + 6930.0 *
pow(alpha * r, 3) + 2772.0 *
pow(alpha * r, 5) + 792.0 *
pow(alpha * r, 7) +
1918 176.0 *
pow(alpha * r, 9) + 32.0 *
pow(alpha * r, 11)) /
1942 if((alpha * r) < 0.5)
1945 (-1.0 / 7.0 +
pow(alpha * r, 2) / 9.0 -
pow(alpha * r, 4) / 22.0 +
pow(alpha * r, 6) / 78.0 -
1946 pow(alpha * r, 8) / 360.0 +
pow(alpha * r, 10) / 2040.0);
1949 (1.0 / 9.0 -
pow(alpha * r, 2) / 11.0 +
pow(alpha * r, 4) / 26.0 -
pow(alpha * r, 6) / 90.0 +
1950 pow(alpha * r, 8) / 408.0 -
pow(alpha * r, 10) / 2280.0);
1953 (-1.0 / 11.0 +
pow(alpha * r, 2) / 13.0 -
pow(alpha * r, 4) / 30.0 +
pow(alpha * r, 6) / 102.0 -
1954 pow(alpha * r, 8) / 456.0 +
pow(alpha * r, 10) / 2520.0);
1957 (1.0 / 13.0 -
pow(alpha * r, 2) / 15.0 +
pow(alpha * r, 4) / 34.0 -
pow(alpha * r, 6) / 114.0 +
1958 pow(alpha * r, 8) / 504.0 -
pow(alpha * r, 10) / 2760.0);
1962 g3 = (-15.0 *
erf(alpha * r) +
1963 (30.0 * alpha * r + 20.0 *
pow(alpha * r, 3) + 8.0 *
pow(alpha * r, 5)) /
sqrt(
M_PI) *
exp(-alpha2 * r2)) *
1966 g4 = (105.0 *
erf(alpha * r) -
1967 (210.0 * alpha * r + 140.0 *
pow(alpha * r, 3) + 56.0 *
pow(alpha * r, 5) + 16.0 *
pow(alpha * r, 7)) /
1971 g5 = (-945.0 *
erf(alpha * r) + (1890.0 * alpha * r + 1260.0 *
pow(alpha * r, 3) + 504.0 *
pow(alpha * r, 5) +
1972 144.0 *
pow(alpha * r, 7) + 32.0 *
pow(alpha * r, 9)) /
1976 g6 = (10395.0 *
erf(alpha * r) -
1978 (10395.0 * alpha * r + 6930.0 *
pow(alpha * r, 3) + 2772.0 *
pow(alpha * r, 5) +
1979 792.0 *
pow(alpha * r, 7) + 176.0 *
pow(alpha * r, 9) + 32.0 *
pow(alpha * r, 11)) /
1988 for(
int nx = -nxmax; nx <= nxmax; nx++)
1989 for(
int ny = -nymax; ny <= nymax; ny++)
1990 for(
int nz = -nzmax; nz <= nzmax; nz++)
1995 double k2 = kx * kx + ky * ky + kz * kz;
1999 double kdotx = (x * kx + y * ky + z * kz);
2004 D6 += (val * kxyz) % (kxyz % (kxyz % ((kxyz % (kxyz % kxyz)))));
2013 static int printed = 0;
2015#ifdef GRAVITY_TALLBOX
2016 Terminate(
"GRAVITY_TALLBOX is not implemented for MULTIPOLE_ORDER >= 4");
2022 double alpha = 2.0 / leff;
2023 double alpha2 = alpha * alpha;
2025 int qxmax = (int)(8.0 *
LONG_X / alpha + 0.5);
2026 int qymax = (int)(8.0 *
LONG_Y / alpha + 0.5);
2027 int qzmax = (int)(8.0 *
LONG_Z / alpha + 0.5);
2029 int nxmax = (int)(2.0 * alpha /
LONG_X + 0.5);
2030 int nymax = (int)(2.0 * alpha /
LONG_Y + 0.5);
2031 int nzmax = (int)(2.0 * alpha /
LONG_Z + 0.5);
2035 mpi_printf(
"EWALD: D7 table: qxmax=%d qymax=%d qzmax=%d nxmax=%d nymax=%d nzmax=%d\n", qxmax, qymax, qzmax, nxmax, nymax,
2040 for(
int nx = -qxmax; nx <= qxmax; nx++)
2041 for(
int ny = -qymax; ny <= qymax; ny++)
2042 for(
int nz = -qzmax; nz <= qzmax; nz++)
2044 double dx = x - nx * (1.0 /
LONG_X);
2045 double dy = y - ny * (1.0 /
LONG_Y);
2046 double dz = z - nz * (1.0 /
LONG_Z);
2050 double r2 = dx * dx + dy * dy + dz * dz;
2051 double r =
sqrt(r2);
2053 double rinv = (r > 0) ? 1.0 / r : 0.0;
2054 double r2inv = rinv * rinv;
2055 double r3inv = r2inv * rinv;
2056 double r4inv = r2inv * r2inv;
2057 double r5inv = r2inv * r3inv;
2058 double r7inv = r3inv * r4inv;
2059 double r9inv = r4inv * r5inv;
2060 double r11inv = r4inv * r7inv;
2061 double r13inv = r4inv * r9inv;
2062 double r15inv = r4inv * r11inv;
2064 double g4, g5, g6, g7;
2066 if(nx != 0 || ny != 0 || nz != 0)
2068 g4 = -(105.0 *
erfc(alpha * r) +
2069 (210.0 * alpha * r + 140.0 *
pow(alpha * r, 3) + 56.0 *
pow(alpha * r, 5) + 16.0 *
pow(alpha * r, 7)) /
2073 g5 = (945.0 *
erfc(alpha * r) + (1890.0 * alpha * r + 1260.0 *
pow(alpha * r, 3) + 504.0 *
pow(alpha * r, 5) +
2074 144.0 *
pow(alpha * r, 7) + 32.0 *
pow(alpha * r, 9)) /
2078 g6 = (-10395.0 *
erfc(alpha * r) -
2080 (10395.0 * alpha * r + 6930.0 *
pow(alpha * r, 3) + 2772.0 *
pow(alpha * r, 5) + 792.0 *
pow(alpha * r, 7) +
2081 176.0 *
pow(alpha * r, 9) + 32.0 *
pow(alpha * r, 11)) /
2086 (135135.0 *
erfc(alpha * r) + 2.0 *
2087 (135135.0 * alpha * r + 90090.0 *
pow(alpha * r, 3) + 36036.0 *
pow(alpha * r, 5) +
2088 10296.0 *
pow(alpha * r, 7) + 2288.0 *
pow(alpha * r, 9) +
2089 416.0 *
pow(alpha * r, 11) + 64.0 *
pow(alpha * r, 13)) /
2113 if((alpha * r) < 0.5)
2116 (1.0 / 9.0 -
pow(alpha * r, 2) / 11.0 +
pow(alpha * r, 4) / 26.0 -
pow(alpha * r, 6) / 90.0 +
2117 pow(alpha * r, 8) / 408.0 -
pow(alpha * r, 10) / 2280.0);
2120 (-1.0 / 11.0 +
pow(alpha * r, 2) / 13.0 -
pow(alpha * r, 4) / 30.0 +
pow(alpha * r, 6) / 102.0 -
2121 pow(alpha * r, 8) / 456.0 +
pow(alpha * r, 10) / 2520.0);
2124 (1.0 / 13.0 -
pow(alpha * r, 2) / 15.0 +
pow(alpha * r, 4) / 34.0 -
pow(alpha * r, 6) / 114.0 +
2125 pow(alpha * r, 8) / 504.0 -
pow(alpha * r, 10) / 2760.0);
2128 (-1.0 / 15.0 +
pow(alpha * r, 2) / 17.0 -
pow(alpha * r, 4) / 38.0 +
pow(alpha * r, 6) / 126.0 -
2129 pow(alpha * r, 8) / 552.0 +
pow(alpha * r, 10) / 3000.0);
2133 g4 = (105.0 *
erf(alpha * r) -
2134 (210.0 * alpha * r + 140.0 *
pow(alpha * r, 3) + 56.0 *
pow(alpha * r, 5) + 16.0 *
pow(alpha * r, 7)) /
2138 g5 = (-945.0 *
erf(alpha * r) + (1890.0 * alpha * r + 1260.0 *
pow(alpha * r, 3) + 504.0 *
pow(alpha * r, 5) +
2139 144.0 *
pow(alpha * r, 7) + 32.0 *
pow(alpha * r, 9)) /
2143 g6 = (10395.0 *
erf(alpha * r) -
2145 (10395.0 * alpha * r + 6930.0 *
pow(alpha * r, 3) + 2772.0 *
pow(alpha * r, 5) +
2146 792.0 *
pow(alpha * r, 7) + 176.0 *
pow(alpha * r, 9) + 32.0 *
pow(alpha * r, 11)) /
2150 g7 = (-135135.0 *
erf(alpha * r) +
2152 (135135.0 * alpha * r + 90090.0 *
pow(alpha * r, 3) + 36036.0 *
pow(alpha * r, 5) +
2153 10296.0 *
pow(alpha * r, 7) + 2288.0 *
pow(alpha * r, 9) + 416.0 *
pow(alpha * r, 11) +
2154 64.0 *
pow(alpha * r, 13)) /
2163 for(
int nx = -nxmax; nx <= nxmax; nx++)
2164 for(
int ny = -nymax; ny <= nymax; ny++)
2165 for(
int nz = -nzmax; nz <= nzmax; nz++)
2170 double k2 = kx * kx + ky * ky + kz * kz;
2174 double kdotx = (x * kx + y * ky + z * kz);
2179 D7 += (val * kxyz) % (kxyz % (kxyz % (kxyz % (kxyz % (kxyz % kxyz)))));
global_data_all_processes All
symtensor3< double > ewald_D3(double x, double y, double z)
double ewald_D0(double x, double y, double z)
This function computes the potential correction term by means of Ewald summation.
symtensor4< double > ewald_D4(double x, double y, double z)
void ewald_init(void)
This function initializes tables with the correction force and the correction potential due to the pe...
symtensor6< double > ewald_D6(double x, double y, double z)
symtensor7< double > ewald_D7(double x, double y, double z)
symtensor5< double > ewald_D5(double x, double y, double z)
vector< double > ewald_D1(double x, double y, double z)
This function computes the force correction term (difference between full force of infinite lattice a...
symtensor2< double > ewald_D2(double x, double y, double z)
void ewald_gridlookup(const MyIntPosType *p_intpos, const MyIntPosType *target_intpos, enum interpolate_options flag, ewald_data &fper)
void nearest_image_intpos_to_pos(const MyIntPosType *const a, const MyIntPosType *const b, T *posdiff)
void constrain_intpos(MyIntPosType *pos)
size_t my_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
A wrapper for the fread() function.
size_t my_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
A wrapper for the fwrite() function.
void mpi_printf(const char *fmt,...)
void ** SharedMemBaseAddr
#define BITS_FOR_POSITIONS
#define EN
Base dimension of cubical Ewald lookup table, for one octant.
#define HIGHEST_NEEDEDORDER_EWALD_DPHI
#define EWALD_TAYLOR_ORDER
int myMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcount, int *displs, MPI_Datatype recvtype, MPI_Comm comm)
expr pow(half base, half exp)
symtensor3< MyReal > D3phi
symtensor2< MyReal > D2phi
void setup_D6(enum setup_options opt, symtensor6< T > &D6, vector< T > &dxyz, TypeGfac g3, TypeGfac g4, TypeGfac g5, TypeGfac g6)
void setup_D5(enum setup_options opt, symtensor5< T > &D5, vector< T > &dxyz, symtensor3< T > &aux3, symtensor4< T > &aux4, symtensor5< T > &aux5, TypeGfac g3, TypeGfac g4, TypeGfac g5)
void setup_D3(enum setup_options opt, symtensor3< T > &D3, vector< T > &dxyz, symtensor2< T > &aux2, symtensor3< T > &aux3, TypeGfac g2, TypeGfac g3)
void setup_D7(enum setup_options opt, symtensor7< T > &D7, vector< T > &dxyz, TypeGfac g4, TypeGfac g5, TypeGfac g6, TypeGfac g7)
void setup_D4(enum setup_options opt, symtensor4< T > &D4, vector< T > &dxyz, symtensor2< T > &aux2, symtensor3< T > &aux3, symtensor4< T > &aux4, TypeGfac g2, TypeGfac g3, TypeGfac g4)
void subdivide_evenly(long long N, int pieces, int index_bin, long long *first, int *count)
void myflush(FILE *fstream)