MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
partmanager.c
Go to the documentation of this file.
1 #include <string.h>
2 
3 #include "partmanager.h"
4 #include "utils/mymalloc.h"
5 #include "utils/endrun.h"
6 #include "utils/system.h"
7 
11 struct part_manager_type PartManager[1] = {{0}};
12 
13 void
15 {
16  size_t bytes;
17  PartManager->Base = (struct particle_data *) mymalloc("P", bytes = MaxPart * sizeof(struct particle_data));
18  PartManager->MaxPart = MaxPart;
19  PartManager->NumPart = 0;
20  if(MaxPart >= 1L<<31 || MaxPart < 0)
21  endrun(5, "Trying to store %ld particles on a single node, more than fit in an int32, not supported\n", MaxPart);
22  memset(PartManager->CurrentParticleOffset, 0, 3*sizeof(double));
23 
24  PartManager->BoxSize = BoxSize;
25  /* clear the memory to avoid valgrind errors;
26  *
27  * note that I tried to set each component in P to zero but
28  * valgrind still complains in PFFT
29  * seems to be to do with how the struct is padded and
30  * the missing holes being accessed by __kmp_atomic functions.
31  * (memory lock etc?)
32  * */
33  memset(PartManager->Base, 0, sizeof(struct particle_data) * MaxPart);
34  message(0, "Allocated %g MByte for storing %ld particles.\n", bytes / (1024.0 * 1024.0), MaxPart);
35 }
36 
37 /* We operate in a situation where the particles are in a coordinate frame
38  * offset slightly from the ICs (to avoid correlated tree errors).
39  * This function updates the global variable containing that offset, and
40  * stores the relative shift from the last offset in the rel_random_shift output
41  * array. */
42 void
43 update_random_offset(struct part_manager_type * PartManager, double * rel_random_shift, double RandomParticleOffset)
44 {
45  int i;
46  for (i = 0; i < 3; i++) {
47  /* Note random number table is duplicated across processors*/
48  double rr = get_random_number(i);
49  /* Upstream Gadget uses a random fraction of the box, but since all we need
50  * is to adjust the tree openings, and the tree force is zero anyway on the
51  * scale of a few PM grid cells, this seems enough.*/
52  rr *= RandomParticleOffset * PartManager->BoxSize;
53  /* Subtract the old random shift first.*/
54  rel_random_shift[i] = rr - PartManager->CurrentParticleOffset[i];
56  }
57  message(0, "Internal particle offset is now %g %g %g\n", PartManager->CurrentParticleOffset[0], PartManager->CurrentParticleOffset[1], PartManager->CurrentParticleOffset[2]);
58 #ifdef DEBUG
59  /* Check explicitly that the vector is the same on all processors*/
60  double test_random_shift[3] = {0};
61  for (i = 0; i < 3; i++)
62  test_random_shift[i] = PartManager->CurrentParticleOffset[i];
63  MPI_Bcast(test_random_shift, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
64  for (i = 0; i < 3; i++)
65  if(test_random_shift[i] != PartManager->CurrentParticleOffset[i])
66  endrun(44, "Random shift %d is %g != %g on task 0!\n", i, test_random_shift[i], PartManager->CurrentParticleOffset[i]);
67 #endif
68 }
void message(int where, const char *fmt,...)
Definition: endrun.c:175
void endrun(int where, const char *fmt,...)
Definition: endrun.c:147
#define mymalloc(name, size)
Definition: mymalloc.h:15
struct part_manager_type PartManager[1]
Definition: partmanager.c:11
void update_random_offset(struct part_manager_type *PartManager, double *rel_random_shift, double RandomParticleOffset)
Definition: partmanager.c:43
void particle_alloc_memory(struct part_manager_type *PartManager, double BoxSize, int64_t MaxPart)
Definition: partmanager.c:14
struct particle_data * Base
Definition: partmanager.h:74
double CurrentParticleOffset[3]
Definition: partmanager.h:82
double get_random_number(uint64_t id)
Definition: system.c:60