12 #include <gsl/gsl_rng.h>
35 static const double G = 43.0071;
38 grav_force(
const int this,
const int other,
const double * offset,
double * accns)
44 for(d = 0; d < 3; d ++) {
46 dist[d] = offset[d] +
P[
this].Pos[d] -
P[other].Pos[d];
47 r2 += dist[d] * dist[d];
50 const double r = sqrt(r2);
54 double fac = 1 / (r2 * r);
56 double h_inv = 1.0 / h;
57 double h3_inv = h_inv * h_inv * h_inv;
60 fac = 1. * h3_inv * (10.666666666667 + u * u * (32.0 * u - 38.4));
63 1. * h3_inv * (21.333333333333 - 48.0 * u +
64 38.4 * u * u - 10.666666666667 * u * u * u - 0.066666666667 / (u * u * u));
67 for(d = 0; d < 3; d ++) {
68 accns[3*
this + d] += - dist[d] * fac *
G *
P[other].Mass;
69 accns[3*other + d] += dist[d] * fac *
G *
P[
this].Mass;
73 void check_accns(
double * meanerr_tot,
double * maxerr_tot,
double *PairAccn,
double meanacc)
75 double meanerr=0, maxerr=-1;
78 #pragma omp parallel for reduction(+: meanerr) reduction(max: maxerr)
83 double err = fabs((PairAccn[3*i+k] - (
P[i].
GravPM[k] +
P[i].GravAccel[k]))/meanacc);
89 MPI_Allreduce(&meanerr, meanerr_tot, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
90 MPI_Allreduce(&maxerr, maxerr_tot, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
94 *meanerr_tot/= (tot_npart*3.);
97 static void find_means(
double * meangrav,
double * suppmean,
double * suppaccns)
100 double meanacc = 0, meanforce = 0;
101 #pragma omp parallel for reduction(+: meanacc) reduction(+: meanforce)
107 meanacc += fabs(suppaccns[3*i+k]);
108 meanforce += fabs(
P[i].
GravPM[k] +
P[i].GravAccel[k]);
114 MPI_Allreduce(&meanacc, suppmean, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
115 *suppmean/= (tot_npart*3.);
117 MPI_Allreduce(&meanforce, meangrav, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
118 *meangrav/= (tot_npart*3.);
132 for(xx=-repeat; xx <= repeat; xx++)
133 for(yy=-repeat; yy <= repeat; yy++)
134 for(zz=-repeat; zz <= repeat; zz++)
150 double meanerr=0, maxerr=-1, meanacc=0, meanforce=0;
154 message(0,
"Mean rel err is: %g max rel err is %g, meanacc %g mean grav force %g\n", meanerr, maxerr, meanacc, meanforce);
156 assert_true(maxerr < 3*ErrTolForceAcc);
157 assert_true(meanerr < 0.8*ErrTolForceAcc);
162 static void do_force_test(
int Nmesh,
double Asmth,
double ErrTolForceAcc,
int direct)
166 #pragma omp parallel for
229 int ncbrt = cbrt(numpart);
235 #pragma omp parallel for
236 for(i=0; i<numpart; i++) {
245 double meanerr=0, maxerr=-1;
246 #pragma omp parallel for reduction(+: meanerr) reduction(max: maxerr)
251 double err = fabs((
P[i].
GravPM[k] +
P[i].GravAccel[k]));
257 MPI_Allreduce(MPI_IN_PLACE, &meanerr, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
258 MPI_Allreduce(MPI_IN_PLACE, &maxerr, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
261 meanerr/= (tot_npart*3.);
263 message(0,
"Max force %g, mean grav force %g\n", maxerr, meanerr);
265 assert_true(maxerr < 0.015);
266 assert_true(meanerr < 0.005);
273 int ncbrt = cbrt(numpart);
279 #pragma omp parallel for
280 for(i=0; i<numpart; i++) {
281 P[i].Pos[0] = 4. + (i/ncbrt/ncbrt)/close;
282 P[i].Pos[1] = 4. + ((i/ncbrt) % ncbrt) /close;
283 P[i].Pos[2] = 4. + (i % ncbrt)/close;
296 for(i=0; i<numpart/4; i++) {
301 for(i=numpart/4; i<3*numpart/4; i++) {
306 for(i=3*numpart/4; i<numpart; i++) {
320 gsl_rng *
r = data->
r;
347 data->
r = gsl_rng_alloc(gsl_rng_mt19937);
348 gsl_rng_set(data->
r, 0);
349 *state = (
void *) data;
361 const struct CMUnitTest tests[] = {
void init_cosmology(Cosmology *CP, const double TimeBegin, const struct UnitSystem units)
void domain_free(DomainDecomp *ddecomp)
void domain_decompose_full(DomainDecomp *ddecomp)
void set_domain_par(DomainParams dp)
void message(int where, const char *fmt,...)
void force_tree_rebuild(ForceTree *tree, DomainDecomp *ddecomp, const int HybridNuGrav, const int DoMoments, const char *EmergencyOutputDir)
void init_forcetree_params(const int FastParticleType)
void force_tree_free(ForceTree *tree)
void gravshort_fill_ntab(const enum ShortRangeForceWindowType ShortRangeForceWindowType, const double Asmth)
void gravshort_set_softenings(double MeanDMSeparation)
void set_gravshort_treepar(struct gravshort_tree_params tree_params)
double FORCE_SOFTENING(int i, int type)
void gravpm_force(PetaPM *pm, ForceTree *tree, Cosmology *CP, double Time, double UnitLength_in_cm, const char *PowerOutputDir, double TimeIC, int FastParticleType)
void grav_short_tree(const ActiveParticles *act, PetaPM *pm, ForceTree *tree, double rho0, int NeutrinoTracer, int FastParticleType)
void gravpm_init_periodic(PetaPM *pm, double BoxSize, double Asmth, int Nmesh, double G)
@ SHORTRANGE_FORCE_WINDOW_TYPE_EXACT
static struct gravpm_params GravPM
#define mymalloc(name, size)
struct part_manager_type PartManager[1]
static peano_t PEANO(double *Pos, double BoxSize)
void petapm_module_init(int Nthreads)
void petapm_destroy(PetaPM *pm)
int64_t NumActiveParticle
int DomainOverDecompositionFactor
int DomainUseGlobalSorting
double TopNodeAllocFactor
double FractionalGravitySoftening
static int check_against_force_direct(double ErrTolForceAcc)
static void test_force_random(void **state)
void do_random_test(gsl_rng *r, const int numpart)
static struct ClockTable CT
static void test_force_flat(void **state)
static int setup_tree(void **state)
static void do_force_test(int Nmesh, double Asmth, double ErrTolForceAcc, int direct)
static void force_direct(double *accn)
static void grav_force(const int this, const int other, const double *offset, double *accns)
static void find_means(double *meangrav, double *suppmean, double *suppaccns)
static int teardown_tree(void **state)
static void test_force_close(void **state)
void check_accns(double *meanerr_tot, double *maxerr_tot, double *PairAccn, double meanacc)
struct UnitSystem get_unitsystem(double UnitLength_in_cm, double UnitMass_in_g, double UnitVelocity_in_cm_per_s)
void walltime_init(struct ClockTable *ct)