MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
runtests.c
Go to the documentation of this file.
1 #include <mpi.h>
2 #include <math.h>
3 
4 #include "partmanager.h"
5 #include "forcetree.h"
6 #include "gravity.h"
7 #include "petaio.h"
8 #include "domain.h"
9 #include "run.h"
10 
11 char * GDB_format_particle(int i);
12 
13 SIMPLE_GETTER(GTGravAccel, GravAccel[0], float, 3, struct particle_data)
14 SIMPLE_GETTER(GTGravPM, GravPM[0], float, 3, struct particle_data)
15 
17 {
18  int ptype;
19  for(ptype = 0; ptype < 6; ptype++) {
20  IO_REG_WRONLY(GravAccel, "f4", 3, ptype, IOTable);
21  IO_REG_WRONLY(GravPM, "f4", 3, ptype, IOTable);
22  }
23 }
24 
25 double copy_and_mean_accn(double (* PairAccn)[3])
26 {
27  int i;
28  double meanacc = 0;
29  #pragma omp parallel for reduction(+: meanacc)
30  for(i = 0; i < PartManager->NumPart; i++)
31  {
32  int k;
33  for(k=0; k<3; k++) {
34  PairAccn[i][k] = P[i].GravPM[k] + P[i].GravAccel[k];
35  meanacc += fabs(PairAccn[i][k]);
36  }
37  }
38  int64_t tot_npart;
39  MPI_Allreduce(&PartManager->NumPart, &tot_npart, 1, MPI_INT64, MPI_SUM, MPI_COMM_WORLD);
40  MPI_Allreduce(MPI_IN_PLACE, &meanacc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
41  meanacc/= (tot_npart*3.);
42  return meanacc;
43 }
44 
45 void check_accns(double * meanerr_tot, double * maxerr_tot, double (*PairAccn)[3], double meanacc)
46 {
47  double meanerr=0, maxerr=-1;
48  int i;
49  /* This checks that the short-range force accuracy is being correctly estimated.*/
50  #pragma omp parallel for reduction(+: meanerr) reduction(max:maxerr)
51  for(i = 0; i < PartManager->NumPart; i++)
52  {
53  int k;
54  for(k=0; k<3; k++) {
55  double err = 0;
56  if(PairAccn[i][k] != 0)
57  err = fabs((PairAccn[i][k] - (P[i].GravPM[k] + P[i].GravAccel[k]))/meanacc);
58  meanerr += err;
59  if(maxerr < err)
60  maxerr = err;
61  }
62  }
63  MPI_Allreduce(&meanerr, meanerr_tot, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
64  MPI_Allreduce(&maxerr, maxerr_tot, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
65  int64_t tot_npart;
66  MPI_Allreduce(&PartManager->NumPart, &tot_npart, 1, MPI_INT64, MPI_SUM, MPI_COMM_WORLD);
67  *meanerr_tot/= (tot_npart*3.);
68 }
69 
70 void
71 run_gravity_test(int RestartSnapNum, Cosmology * CP, const double Asmth, const int Nmesh, const int FastParticleType, const inttime_t Ti_Current, const char * OutputDir, const struct header_data * header)
72 {
73  DomainDecomp ddecomp[1] = {0};
74  domain_decompose_full(ddecomp);
75 
76  struct IOTable IOTable = {0};
77  /* NO metals written*/
80 
81  double (* PairAccn)[3] = (double (*) [3]) mymalloc2("PairAccns", 3*sizeof(double) * PartManager->NumPart);
82 
83  PetaPM pm[1] = {0};
85 
86  int NTask;
87  MPI_Comm_size(MPI_COMM_WORLD, &NTask);
88  ActiveParticles Act = {0};
89  DriftKickTimes times = init_driftkicktime(Ti_Current);
90  rebuild_activelist(&Act, &times, 0, header->TimeSnapshot);
91 
92  ForceTree Tree = {0};
93  force_tree_rebuild(&Tree, ddecomp, 1, 1, OutputDir);
94  gravpm_force(pm, &Tree, CP, header->TimeSnapshot, header->UnitLength_in_cm, OutputDir, header->TimeIC, FastParticleType);
95  force_tree_rebuild(&Tree, ddecomp, 1, 1, OutputDir);
96 
97  struct gravshort_tree_params origtreeacc = get_gravshort_treepar();
98  struct gravshort_tree_params treeacc = origtreeacc;
99  const double rho0 = CP->Omega0 * 3 * CP->Hubble * CP->Hubble / (8 * M_PI * CP->GravInternal);
100  grav_short_pair(&Act, pm, &Tree, treeacc.Rcut, rho0, 0, FastParticleType);
101 
102  double meanacc = copy_and_mean_accn(PairAccn);
103  message(0, "GravShort Pairs %s\n", GDB_format_particle(0));
104  char * fname = fastpm_strdup_printf("%s/PART-pairs-%03d", OutputDir, RestartSnapNum);
105 
106  petaio_save_snapshot(fname, &IOTable, 0, header->TimeSnapshot, CP);
107 
108  treeacc.ErrTolForceAcc = 0;
109  set_gravshort_treepar(treeacc);
110  grav_short_tree(&Act, pm, &Tree, rho0, 0, FastParticleType);
111 
112  /* This checks fully opened tree force against pair force*/
113  double meanerr, maxerr;
114  check_accns(&meanerr,&maxerr,PairAccn, meanacc);
115  message(0, "Force error, open tree vs pairwise. max : %g mean: %g forcetol: %g\n", maxerr, meanerr, treeacc.ErrTolForceAcc);
116 
117  if(maxerr > 0.1)
118  endrun(2, "Fully open tree force does not agree with pairwise calculation! maxerr %g > 0.1!\n", maxerr);
119 
120  message(0, "GravShort Tree %s\n", GDB_format_particle(0));
121  fname = fastpm_strdup_printf("%s/PART-tree-open-%03d", OutputDir, RestartSnapNum);
122  petaio_save_snapshot(fname, &IOTable, 0, header->TimeSnapshot, CP);
123 
124  /* This checks tree force against tree force with zero error (which always opens).*/
125  copy_and_mean_accn(PairAccn);
126 
127  treeacc = origtreeacc;
128  set_gravshort_treepar(treeacc);
129  /* Code automatically sets the UseTreeBH parameter.*/
130  grav_short_tree(&Act, pm, &Tree, rho0, 0, FastParticleType);
131  grav_short_tree(&Act, pm, &Tree, rho0, 0, FastParticleType);
132 
133  fname = fastpm_strdup_printf("%s/PART-tree-%03d", OutputDir, RestartSnapNum);
134  petaio_save_snapshot(fname, &IOTable, 0, header->TimeSnapshot, CP);
135 
136  check_accns(&meanerr,&maxerr,PairAccn, meanacc);
137  message(0, "Force error, open tree vs tree.: %g mean: %g forcetol: %g\n", maxerr, meanerr, treeacc.ErrTolForceAcc);
138 
139  if(meanerr > treeacc.ErrTolForceAcc* 1.2)
140  endrun(2, "Average force error is underestimated: %g > 1.2 * %g!\n", meanerr, treeacc.ErrTolForceAcc);
141 
142  copy_and_mean_accn(PairAccn);
143  /* This checks the tree against a larger Rcut.*/
144  treeacc.Rcut = 9.5;
145  set_gravshort_treepar(treeacc);
146  grav_short_tree(&Act, pm, &Tree, rho0, 0, FastParticleType);
147  grav_short_tree(&Act, pm, &Tree, rho0, 0, FastParticleType);
148  fname = fastpm_strdup_printf("%s/PART-tree-rcut-%03d", OutputDir, RestartSnapNum);
149  petaio_save_snapshot(fname, &IOTable, 0, header->TimeSnapshot, CP);
150 
151  check_accns(&meanerr,&maxerr,PairAccn, meanacc);
152  message(0, "Force error, tree vs rcut.: %g mean: %g Rcut = %g\n", maxerr, meanerr, treeacc.Rcut);
153 
154  if(maxerr > 0.2)
155  endrun(2, "Rcut decreased below desired value, error too large %g\n", maxerr);
156 
157  /* This checks the tree against a box with a smaller Nmesh.*/
158  treeacc = origtreeacc;
159  force_tree_free(&Tree);
160 
161  petapm_destroy(pm);
162 
163  gravpm_init_periodic(pm, PartManager->BoxSize, Asmth, Nmesh/2., CP->GravInternal);
164  force_tree_rebuild(&Tree, ddecomp, 1, 1, OutputDir);
165  gravpm_force(pm, &Tree, CP, header->TimeSnapshot, header->UnitLength_in_cm, OutputDir, header->TimeIC, FastParticleType);
166  force_tree_rebuild(&Tree, ddecomp, 1, 1, OutputDir);
167  set_gravshort_treepar(treeacc);
168  grav_short_tree(&Act, pm, &Tree, rho0, 0, FastParticleType);
169  grav_short_tree(&Act, pm, &Tree, rho0, 0, FastParticleType);
170  fname = fastpm_strdup_printf("%s/PART-tree-nmesh2-%03d", OutputDir, RestartSnapNum);
171  petaio_save_snapshot(fname, &IOTable, 0, header->TimeSnapshot, CP);
172 
173  check_accns(&meanerr, &maxerr, PairAccn, meanacc);
174  message(0, "Force error, nmesh %d vs %d: %g mean: %g \n", Nmesh, Nmesh/2, maxerr, meanerr);
175 
176  if(maxerr > 0.5 || meanerr > 0.05)
177  endrun(2, "Nmesh sensitivity worse, something may be wrong\n");
178 
179  force_tree_free(&Tree);
180  petapm_destroy(pm);
181 
182  myfree(PairAccn);
183 
185  domain_free(ddecomp);
186 }
void domain_free(DomainDecomp *ddecomp)
Definition: domain.c:320
void domain_decompose_full(DomainDecomp *ddecomp)
Definition: domain.c:155
void message(int where, const char *fmt,...)
Definition: endrun.c:175
void endrun(int where, const char *fmt,...)
Definition: endrun.c:147
void force_tree_rebuild(ForceTree *tree, DomainDecomp *ddecomp, const int HybridNuGrav, const int DoMoments, const char *EmergencyOutputDir)
Definition: forcetree.c:140
void force_tree_free(ForceTree *tree)
Definition: forcetree.c:1409
struct gravshort_tree_params get_gravshort_treepar(void)
void grav_short_pair(const ActiveParticles *act, PetaPM *pm, ForceTree *tree, double Rcut, double rho0, int NeutrinoTracer, int FastParticleType)
void set_gravshort_treepar(struct gravshort_tree_params tree_params)
void gravpm_force(PetaPM *pm, ForceTree *tree, Cosmology *CP, double Time, double UnitLength_in_cm, const char *PowerOutputDir, double TimeIC, int FastParticleType)
Definition: gravpm.c:62
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)
Definition: gravpm.c:53
static struct gravpm_params GravPM
#define mymalloc2(name, size)
Definition: mymalloc.h:16
#define myfree(x)
Definition: mymalloc.h:19
struct part_manager_type PartManager[1]
Definition: partmanager.c:11
#define P
Definition: partmanager.h:88
void destroy_io_blocks(struct IOTable *IOTable)
Definition: petaio.c:1034
void register_io_blocks(struct IOTable *IOTable, int WriteGroupID, int MetalReturnOn)
Definition: petaio.c:909
void petaio_save_snapshot(const char *fname, struct IOTable *IOTable, int verbose, const double atime, const Cosmology *CP)
Definition: petaio.c:151
#define SIMPLE_GETTER(name, field, type, items, stype)
Definition: petaio.h:145
#define IO_REG_WRONLY(name, dtype, items, ptype, IOTable)
Definition: petaio.h:117
void petapm_destroy(PetaPM *pm)
Definition: petapm.c:215
static Cosmology * CP
Definition: power.c:27
void check_accns(double *meanerr_tot, double *maxerr_tot, double(*PairAccn)[3], double meanacc)
Definition: runtests.c:45
void register_extra_blocks(struct IOTable *IOTable)
Definition: runtests.c:16
double copy_and_mean_accn(double(*PairAccn)[3])
Definition: runtests.c:25
char * GDB_format_particle(int i)
Definition: gdbtools.c:58
void run_gravity_test(int RestartSnapNum, Cosmology *CP, const double Asmth, const int Nmesh, const int FastParticleType, const inttime_t Ti_Current, const char *OutputDir, const struct header_data *header)
Definition: runtests.c:71
char * fastpm_strdup_printf(const char *fmt,...)
Definition: string.c:41
double GravInternal
Definition: cosmology.h:32
double Omega0
Definition: cosmology.h:10
double Hubble
Definition: cosmology.h:21
Definition: petaio.h:60
Definition: petapm.h:62
double ErrTolForceAcc
Definition: gravity.h:11
double TimeIC
Definition: petaio.h:24
double TimeSnapshot
Definition: petaio.h:26
double UnitLength_in_cm
Definition: petaio.h:30
#define MPI_INT64
Definition: system.h:12
int NTask
Definition: test_exchange.c:23
DriftKickTimes init_driftkicktime(inttime_t Ti_Current)
Definition: timestep.c:133
int rebuild_activelist(ActiveParticles *act, const DriftKickTimes *const times, int NumCurrentTiStep, const double Time)
Definition: timestep.c:721
int32_t inttime_t
Definition: types.h:8
static enum TransferType ptype
Definition: zeldovich.c:146