MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
Macros | Functions
main.c File Reference
#include <math.h>
#include <stdlib.h>
#include <strings.h>
#include <stdio.h>
#include <mpi.h>
#include <omp.h>
#include <bigfile-mpi.h>
#include <libgenic/allvars.h>
#include <libgenic/proto.h>
#include <libgenic/thermal.h>
#include <libgadget/walltime.h>
#include <libgadget/physconst.h>
#include <libgadget/petapm.h>
#include <libgadget/utils.h>
#include <libgadget/partmanager.h>
#include <libgadget/utils/unitsystem.h>
Include dependency graph for main.c:

Go to the source code of this file.

Macros

#define GLASS_SEED_HASH(seed)   ((seed) * 9999721L)
 

Functions

static void print_spec (int ThisTask, const int Ngrid, struct genic_config All2, Cosmology *CP)
 
int main (int argc, char **argv)
 

Macro Definition Documentation

◆ GLASS_SEED_HASH

#define GLASS_SEED_HASH (   seed)    ((seed) * 9999721L)

Definition at line 19 of file main.c.

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 23 of file main.c.

24 {
25  int thread_provided, ThisTask;
26  MPI_Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &thread_provided);
27  if(thread_provided != MPI_THREAD_FUNNELED)
28  message(1, "MPI_Init_thread returned %d != MPI_THREAD_FUNNELED\n", thread_provided);
29 
30  if(argc < 2)
31  endrun(0,"Please pass a parameter file.\n");
32 
33  tamalloc_init();
34 
35 
36  /* Genic Specific configuration structure*/
37  struct genic_config All2 = {0};
38 
39  Cosmology CP ={0};
40  int ShowBacktrace;
41  double MaxMemSizePerNode;
42  read_parameterfile(argv[1], &All2, &ShowBacktrace, &MaxMemSizePerNode, &CP);
44 
45  mymalloc_init(MaxMemSizePerNode);
46 
48 
49  struct ClockTable Clocks;
51 
52  int64_t TotNumPart = (int64_t) All2.Ngrid*All2.Ngrid*All2.Ngrid;
53  int64_t TotNumPartGas = (int64_t) All2.ProduceGas*All2.NgridGas*All2.NgridGas*All2.NgridGas;
54 
55  init_cosmology(&CP, All2.TimeIC, All2.units);
56 
57  MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask);
59 
60  petapm_module_init(omp_get_max_threads());
61 
62  /*Initialise particle spacings*/
63  const double meanspacing = All2.BoxSize / DMAX(All2.Ngrid, All2.NgridGas);
64  double shift_gas = -All2.ProduceGas * 0.5 * (CP.Omega0 - CP.OmegaBaryon) / CP.Omega0 * meanspacing;
65  double shift_dm = All2.ProduceGas * 0.5 * CP.OmegaBaryon / CP.Omega0 * meanspacing;
66 
67  double shift_nu = 0;
68  if(!All2.ProduceGas && All2.NGridNu > 0) {
69  double OmegaNu = get_omega_nu(&CP.ONu, 1);
70  shift_nu = -0.5 * (CP.Omega0 - OmegaNu) / CP.Omega0 * meanspacing;
71  shift_dm = 0.5 * OmegaNu / CP.Omega0 * meanspacing;
72  }
73 
74  if(All2.PrePosGridCenter){
75  shift_dm += 0.5 * meanspacing;
76  shift_gas += 0.5 * meanspacing;
77  shift_nu += 0.5 * meanspacing;
78  }
79 
80  /*Write the header*/
81  char buf[4096];
82  snprintf(buf, 4096, "%s/%s", All2.OutputDir, All2.InitCondFile);
83  BigFile bf;
84  if(0 != big_file_mpi_create(&bf, buf, MPI_COMM_WORLD)) {
85  endrun(0, "%s\n", big_file_get_error_message());
86  }
87  /*Massive neutrinos*/
88 
89  const int64_t TotNu = (int64_t) All2.NGridNu*All2.NGridNu*All2.NGridNu;
90  double total_nufrac = 0;
91  struct thermalvel nu_therm;
92  if(TotNu > 0) {
93  const double kBMNu = 3*CP.ONu.kBtnu / (CP.MNu[0]+CP.MNu[1]+CP.MNu[2]);
94  double v_th = NU_V0(All2.TimeIC, kBMNu, All2.units.UnitVelocity_in_cm_per_s);
95  if(!All2.UsePeculiarVelocity)
96  v_th /= sqrt(All2.TimeIC);
97  total_nufrac = init_thermalvel(&nu_therm, v_th, All2.Max_nuvel/v_th, 0);
98  message(0,"F-D velocity scale: %g. Max particle vel: %g. Fraction of mass in particles: %g\n",v_th*sqrt(All2.TimeIC), All2.Max_nuvel*sqrt(All2.TimeIC), total_nufrac);
99  }
100  saveheader(&bf, TotNumPart, TotNumPartGas, TotNu, total_nufrac, All2.BoxSize, &CP, All2);
101 
102  /*Save the transfer functions*/
104 
105  /*Use 'total' (CDM + baryon) transfer function
106  * unless DifferentTransferFunctions are on.
107  */
108  enum TransferType DMType = DELTA_CB, GasType = DELTA_CB, NuType = DELTA_NU;
109  if(All2.ProduceGas && All2.PowerP.DifferentTransferFunctions) {
110  DMType = DELTA_CDM;
111  GasType = DELTA_BAR;
112  }
113  PetaPM pm[1];
114 
115  double UnitTime_in_s = All2.units.UnitLength_in_cm / All2.units.UnitVelocity_in_cm_per_s;
116  double Grav = GRAVITY / pow(All2.units.UnitLength_in_cm, 3) * All2.units.UnitMass_in_g * pow(UnitTime_in_s, 2);
117 
118  petapm_init(pm, All2.BoxSize, 0, All2.Nmesh, Grav, MPI_COMM_WORLD);
119 
120  /*First compute and write CDM*/
121  double mass[6] = {0};
122  /*Can neglect neutrinos since this only matters for the glass force.*/
123  compute_mass(mass, TotNumPart, TotNumPartGas, 0, 0, All2.BoxSize, &CP, All2);
124  /*Not used*/
125  IDGenerator idgen_cdm[1];
126  IDGenerator idgen_gas[1];
127 
128  idgen_init(idgen_cdm, pm, All2.Ngrid, All2.BoxSize);
129  idgen_init(idgen_gas, pm, All2.NgridGas, All2.BoxSize);
130 
131  int NumPartCDM = idgen_cdm->NumPart;
132  int NumPartGas = idgen_gas->NumPart;
133 
134  /*Space for both CDM and baryons*/
135  struct ic_part_data * ICP = (struct ic_part_data *) mymalloc("PartTable", (NumPartCDM + All2.ProduceGas * NumPartGas)*sizeof(struct ic_part_data));
136 
137  /* If we have incoherent glass files, we need to store both the particle tables
138  * to ensure that there are no close particle pairs*/
139  /*Make the table for the CDM*/
140  if(!All2.MakeGlassCDM) {
141  setup_grid(idgen_cdm, shift_dm, mass[1], ICP);
142  } else {
143  setup_glass(idgen_cdm, pm, 0, GLASS_SEED_HASH(All2.Seed), mass[1], ICP, All2.units.UnitLength_in_cm, All2.OutputDir);
144  }
145 
146  /*Make the table for the baryons if we need, using the second half of the memory.*/
147  if(All2.ProduceGas) {
148  if(!All2.MakeGlassGas) {
149  setup_grid(idgen_gas, shift_gas, mass[0], ICP+NumPartCDM);
150  } else {
151  setup_glass(idgen_gas, pm, 0, GLASS_SEED_HASH(All2.Seed + 1), mass[0], ICP+NumPartCDM, All2.units.UnitLength_in_cm, All2.OutputDir);
152  }
153  /*Do coherent glass evolution to avoid close pairs*/
154  if(All2.MakeGlassGas || All2.MakeGlassCDM)
155  glass_evolve(pm, 14, "powerspectrum-glass-tot", ICP, NumPartCDM+NumPartGas, All2.units.UnitLength_in_cm, All2.OutputDir);
156  }
157 
158  /*Write initial positions into ICP struct (for CDM and gas)*/
159  int j,k;
160  for(j=0; j<NumPartCDM+NumPartGas; j++)
161  for(k=0; k<3; k++)
162  ICP[j].PrePos[k] = ICP[j].Pos[k];
163 
164  if(NumPartCDM > 0) {
165  displacement_fields(pm, DMType, ICP, NumPartCDM, &CP, All2);
166 
167  /*Add a thermal velocity to WDM particles*/
168  if(All2.WDM_therm_mass > 0){
169  int i;
171  if(!All2.UsePeculiarVelocity)
172  v_th /= sqrt(All2.TimeIC);
173  struct thermalvel WDM;
174  init_thermalvel(&WDM, v_th, 10000/v_th, 0);
175  unsigned int * seedtable = init_rng(All2.Seed+1,All2.Ngrid);
176  gsl_rng * g_rng = gsl_rng_alloc(gsl_rng_ranlxd1);
177  /*Seed the random number table with the Id.*/
178  gsl_rng_set(g_rng, seedtable[0]);
179 
180  for(i = 0; i < NumPartCDM; i++) {
181  /*Find the slab, and reseed if it has zero z rank*/
182  if(i % All2.Ngrid == 0) {
183  uint64_t id = idgen_create_id_from_index(idgen_cdm, i);
184  /*Seed the random number table with x,y index.*/
185  gsl_rng_set(g_rng, seedtable[id / All2.Ngrid]);
186  }
187  add_thermal_speeds(&WDM, g_rng, ICP[i].Vel);
188  }
189  gsl_rng_free(g_rng);
190  myfree(seedtable);
191  }
192 
193  write_particle_data(idgen_cdm, 1, &bf, 0, All2.SavePrePos, All2.NumFiles, All2.NumWriters, ICP);
194  }
195 
196  /*Now make the gas if required*/
197  if(All2.ProduceGas) {
198  displacement_fields(pm, GasType, ICP+NumPartCDM, NumPartGas, &CP, All2);
199  write_particle_data(idgen_gas, 0, &bf, TotNumPart, All2.SavePrePos, All2.NumFiles, All2.NumWriters, ICP+NumPartCDM);
200  }
201  myfree(ICP);
202 
203  /*Now add random velocity neutrino particles*/
204  if(All2.NGridNu > 0) {
205  int i;
206  IDGenerator idgen_nu[1];
207  idgen_init(idgen_nu, pm, All2.NGridNu, All2.BoxSize);
208 
209  int NumPartNu = idgen_nu->NumPart;
210  ICP = (struct ic_part_data *) mymalloc("PartTable", NumPartNu*sizeof(struct ic_part_data));
211 
212  NumPartNu = setup_grid(idgen_nu, shift_nu, mass[2], ICP);
213 
214  /*Write initial positions into ICP struct (for neutrinos)*/
215  for(j=0; j<NumPartNu; j++)
216  for(k=0; k<3; k++)
217  ICP[j].PrePos[k] = ICP[j].Pos[k];
218 
219  displacement_fields(pm, NuType, ICP, NumPartNu, &CP, All2);
220  unsigned int * seedtable = init_rng(All2.Seed+2,All2.NGridNu);
221  gsl_rng * g_rng = gsl_rng_alloc(gsl_rng_ranlxd1);
222  /*Just in case*/
223  gsl_rng_set(g_rng, seedtable[0]);
224  for(i = 0; i < NumPartNu; i++) {
225  /*Find the slab, and reseed if it has zero z rank*/
226  if(i % All2.NGridNu == 0) {
227  uint64_t id = idgen_create_id_from_index(idgen_nu, i);
228  /*Seed the random number table with x,y index.*/
229  gsl_rng_set(g_rng, seedtable[id / All2.NGridNu]);
230  }
231  add_thermal_speeds(&nu_therm, g_rng, ICP[i].Vel);
232  }
233  gsl_rng_free(g_rng);
234  myfree(seedtable);
235 
236  write_particle_data(idgen_nu, 2, &bf, TotNumPart+TotNumPartGas, All2.SavePrePos, All2.NumFiles, All2.NumWriters, ICP);
237  myfree(ICP);
238  }
239 
240  petapm_destroy(pm);
241  big_file_mpi_close(&bf, MPI_COMM_WORLD);
242 
243  walltime_summary(0, MPI_COMM_WORLD);
244  walltime_report(stdout, 0, MPI_COMM_WORLD);
245 
246  message(0, "IC's generated.\n");
247  message(0, "Initial scale factor = %g\n", All2.TimeIC);
248 
249  print_spec(ThisTask, All2.Ngrid, All2, &CP);
250 
251  MPI_Finalize(); /* clean up & finalize MPI */
252  return 0;
253 }
void init_cosmology(Cosmology *CP, const double TimeBegin, const struct UnitSystem units)
Definition: cosmology.c:15
void message(int where, const char *fmt,...)
Definition: endrun.c:175
void init_endrun(int backtrace)
Definition: endrun.c:132
static int ShowBacktrace
Definition: endrun.c:100
void endrun(int where, const char *fmt,...)
Definition: endrun.c:147
static void print_spec(int ThisTask, const int Ngrid, struct genic_config All2, Cosmology *CP)
Definition: main.c:255
#define GLASS_SEED_HASH(seed)
Definition: main.c:19
int setup_glass(IDGenerator *idgen, PetaPM *pm, double shift, int seed, double mass, struct ic_part_data *ICP, const double UnitLength_in_cm, const char *OutputDir)
Definition: glass.c:41
void glass_evolve(PetaPM *pm, int nsteps, const char *pkoutname, struct ic_part_data *ICP, const int NumPart, const double UnitLength_in_cm, const char *OutputDir)
Definition: glass.c:73
void tamalloc_init(void)
Definition: mymalloc.c:29
void mymalloc_init(double MaxMemSizePerNode)
Definition: mymalloc.c:48
#define mymalloc(name, size)
Definition: mymalloc.h:15
#define myfree(x)
Definition: mymalloc.h:19
double get_omega_nu(const _omega_nu *const omnu, const double a)
void petapm_module_init(int Nthreads)
Definition: petapm.c:82
void petapm_init(PetaPM *pm, double BoxSize, double Asmth, int Nmesh, double G, MPI_Comm comm)
Definition: petapm.c:94
void petapm_destroy(PetaPM *pm)
Definition: petapm.c:215
#define GRAVITY
Definition: physconst.h:5
int init_powerspectrum(int ThisTask, double InitTime, double UnitLength_in_cm_in, Cosmology *CPin, struct power_params *ppar)
Definition: power.c:394
void save_all_transfer_tables(BigFile *bf, int ThisTask)
Definition: power.c:150
static Cosmology * CP
Definition: power.c:27
TransferType
Definition: power.h:41
@ DELTA_CB
Definition: power.h:45
@ DELTA_BAR
Definition: power.h:42
@ DELTA_CDM
Definition: power.h:43
@ DELTA_NU
Definition: power.h:44
void compute_mass(double *mass, int64_t TotNumPartCDM, int64_t TotNumPartGas, int64_t TotNuPart, double nufrac, const double BoxSize, Cosmology *CP, const struct genic_config GenicConfig)
Definition: save.c:90
void saveheader(BigFile *bf, int64_t TotNumPartCDM, int64_t TotNumPartGas, int64_t TotNuPart, double nufrac, const double BoxSize, Cosmology *CP, const struct genic_config GenicConfig)
Definition: save.c:112
void write_particle_data(IDGenerator *idgen, const int Type, BigFile *bf, const uint64_t FirstID, const int SavePrePos, int NumFiles, int NumWriters, struct ic_part_data *curICP)
Definition: save.c:61
int setup_grid(IDGenerator *idgen, double shift, double mass, struct ic_part_data *ICP)
Definition: zeldovich.c:91
void idgen_init(IDGenerator *idgen, PetaPM *pm, int Ngrid, double BoxSize)
Definition: zeldovich.c:48
void displacement_fields(PetaPM *pm, enum TransferType Type, struct ic_part_data *dispICP, const int NumPart, Cosmology *CP, const struct genic_config GenicConfig)
Definition: zeldovich.c:150
void read_parameterfile(char *fname, struct genic_config *GenicConfig, int *ShowBacktrace, double *MaxMemSizePerNode, Cosmology *CP)
Definition: params.c:75
uint64_t idgen_create_id_from_index(IDGenerator *idgen, int index)
Definition: zeldovich.c:69
static struct ClockTable Clocks
Definition: run.c:38
double Omega0
Definition: cosmology.h:10
double HubbleParam
Definition: cosmology.h:20
double OmegaBaryon
Definition: cosmology.h:19
double MNu[3]
Definition: cosmology.h:25
_omega_nu ONu
Definition: cosmology.h:24
int NumPart
Definition: proto.h:14
Definition: petapm.h:62
double UnitMass_in_g
Definition: unitsystem.h:8
double UnitLength_in_cm
Definition: unitsystem.h:10
double UnitVelocity_in_cm_per_s
Definition: unitsystem.h:9
int MakeGlassGas
Definition: allvars.h:28
double Max_nuvel
Definition: allvars.h:26
double BoxSize
Definition: allvars.h:20
int NGridNu
Definition: allvars.h:18
char OutputDir[100]
Definition: allvars.h:36
int Ngrid
Definition: allvars.h:18
struct UnitSystem units
Definition: allvars.h:35
int PrePosGridCenter
Definition: allvars.h:25
int ProduceGas
Definition: allvars.h:21
int MakeGlassCDM
Definition: allvars.h:29
int Nmesh
Definition: allvars.h:19
int SavePrePos
Definition: allvars.h:33
struct power_params PowerP
Definition: allvars.h:34
char InitCondFile[100]
Definition: allvars.h:37
int NgridGas
Definition: allvars.h:18
int Seed
Definition: allvars.h:22
double WDM_therm_mass
Definition: allvars.h:27
int UsePeculiarVelocity
Definition: allvars.h:39
int NumFiles
Definition: allvars.h:30
double TimeIC
Definition: allvars.h:38
int NumWriters
Definition: allvars.h:31
double PrePos[3]
Definition: allvars.h:9
float Vel[3]
Definition: allvars.h:11
double Pos[3]
Definition: allvars.h:10
int DifferentTransferFunctions
Definition: power.h:10
int ThisTask
Definition: test_exchange.c:23
int TotNumPart
Definition: test_exchange.c:24
#define DMAX(x, y)
Definition: test_interp.c:11
double NU_V0(const double Time, const double kBTNubyMNu, const double UnitVelocity_in_cm_per_s)
Definition: thermal.c:24
double WDM_V0(const double Time, const double WDM_therm_mass, const double Omega_CDM, const double HubbleParam, const double UnitVelocity_in_cm_per_s)
Definition: thermal.c:30
unsigned int * init_rng(int Seed, int Nmesh)
Definition: thermal.c:90
double init_thermalvel(struct thermalvel *thermals, const double v_amp, double max_fd, const double min_fd)
Definition: thermal.c:47
void add_thermal_speeds(struct thermalvel *thermals, gsl_rng *g_rng, float Vel[])
Definition: thermal.c:109
struct UnitSystem get_unitsystem(double UnitLength_in_cm, double UnitMass_in_g, double UnitVelocity_in_cm_per_s)
Definition: unitsystem.c:6
void walltime_init(struct ClockTable *ct)
Definition: walltime.c:19
void walltime_summary(int root, MPI_Comm comm)
Definition: walltime.c:55
void walltime_report(FILE *fp, int root, MPI_Comm comm)
Definition: walltime.c:220

References add_thermal_speeds(), genic_config::BoxSize, Clocks, compute_mass(), CP, DELTA_BAR, DELTA_CB, DELTA_CDM, DELTA_NU, power_params::DifferentTransferFunctions, displacement_fields(), DMAX, endrun(), get_omega_nu(), get_unitsystem(), glass_evolve(), GLASS_SEED_HASH, GRAVITY, Cosmology::HubbleParam, idgen_create_id_from_index(), idgen_init(), init_cosmology(), init_endrun(), init_powerspectrum(), init_rng(), init_thermalvel(), genic_config::InitCondFile, _omega_nu::kBtnu, genic_config::MakeGlassCDM, genic_config::MakeGlassGas, genic_config::Max_nuvel, message(), Cosmology::MNu, myfree, mymalloc, mymalloc_init(), genic_config::Ngrid, genic_config::NgridGas, genic_config::NGridNu, genic_config::Nmesh, NU_V0(), genic_config::NumFiles, IDGenerator::NumPart, genic_config::NumWriters, Cosmology::Omega0, Cosmology::OmegaBaryon, Cosmology::ONu, genic_config::OutputDir, petapm_destroy(), petapm_init(), petapm_module_init(), ic_part_data::Pos, genic_config::PowerP, ic_part_data::PrePos, genic_config::PrePosGridCenter, print_spec(), genic_config::ProduceGas, read_parameterfile(), save_all_transfer_tables(), saveheader(), genic_config::SavePrePos, genic_config::Seed, setup_glass(), setup_grid(), ShowBacktrace, tamalloc_init(), ThisTask, genic_config::TimeIC, TotNumPart, UnitSystem::UnitLength_in_cm, UnitSystem::UnitMass_in_g, genic_config::units, UnitSystem::UnitVelocity_in_cm_per_s, genic_config::UsePeculiarVelocity, ic_part_data::Vel, walltime_init(), walltime_report(), walltime_summary(), genic_config::WDM_therm_mass, WDM_V0(), and write_particle_data().

Here is the call graph for this function:

◆ print_spec()

void print_spec ( int  ThisTask,
const int  Ngrid,
struct genic_config  All2,
Cosmology CP 
)
static

Definition at line 255 of file main.c.

256 {
257  if(ThisTask == 0)
258  {
259  double k, kstart, kend, DDD;
260  char buf[1000];
261  FILE *fd;
262 
263  sprintf(buf, "%s/inputspec_%s.txt", All2.OutputDir, All2.InitCondFile);
264 
265  fd = fopen(buf, "w");
266  if (fd == NULL) {
267  message(1, "Failed to create powerspec file at:%s\n", buf);
268  return;
269  }
270  DDD = GrowthFactor(CP, All2.TimeIC, 1.0);
271 
272  fprintf(fd, "# %12g %12g\n", 1/All2.TimeIC-1, DDD);
273  /* print actual starting redshift and linear growth factor for this cosmology */
274  kstart = 2 * M_PI / (2*All2.BoxSize * (CM_PER_MPC / All2.units.UnitLength_in_cm)); /* 2x box size Mpc/h */
275  kend = 2 * M_PI / (All2.BoxSize/(8*Ngrid) * (CM_PER_MPC / All2.units.UnitLength_in_cm)); /* 1/8 mean spacing Mpc/h */
276 
277  message(1,"kstart=%lg kend=%lg\n",kstart,kend);
278 
279  for(k = kstart; k < kend; k *= 1.025)
280  {
281  double po = pow(DeltaSpec(k, DELTA_TOT),2);
282  fprintf(fd, "%12g %12g\n", k, po);
283  }
284  fclose(fd);
285  }
286 }
double GrowthFactor(Cosmology *CP, double astart, double aend)
Definition: cosmology.c:82
#define CM_PER_MPC
Definition: physconst.h:20
double DeltaSpec(double k, enum TransferType Type)
Definition: power.c:52
@ DELTA_TOT
Definition: power.h:52

References genic_config::BoxSize, CM_PER_MPC, CP, DELTA_TOT, DeltaSpec(), GrowthFactor(), genic_config::InitCondFile, message(), genic_config::OutputDir, ThisTask, genic_config::TimeIC, UnitSystem::UnitLength_in_cm, and genic_config::units.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function: