12#include "gadgetconfig.h"
21#include "../cooling_sfr/cooling.h"
22#include "../data/allvars.h"
23#include "../data/dtypes.h"
24#include "../data/mymalloc.h"
25#include "../domain/domain.h"
26#include "../fof/fof.h"
27#include "../gravtree/gravtree.h"
29#include "../io/snap_io.h"
30#include "../logs/timer.h"
31#include "../main/main.h"
32#include "../main/simulation.h"
33#include "../mpi_utils/mpi_utils.h"
34#include "../ngbtree/ngbtree.h"
35#include "../ngenic/ngenic.h"
37#include "../sort/parallel_sort.h"
38#include "../subfind/subfind_readid_io.h"
39#include "../system/system.h"
40#include "../time_integration/timestep.h"
56 Ngenic.ngenic_displace_particles();
62 for(
int k = 0; k < 3; k++)
75 Terminate(
"Compile with option NGENIC to create cosmological initial conditions");
79#ifdef LIGHTCONE_PARTICLES
85#ifdef LIGHTCONE_MASSMAPS
86 LightCone.Mp->Npix = nside2npix(
All.LightConeMassMapsNside);
93 LightCone.MassMap = (
double *)
Mem.mymalloc_movable_clear(&LightCone.MassMap,
"MassMap", LightCone.Mp->NpixLoc *
sizeof(
double));
114#ifdef GENERATE_GAS_IN_ICS
126 for(
int i = 0; i <
NTask; i++)
134#ifdef SPLIT_PARTICLE_TYPE
135 if((1 <<
Sp.
P[i].
getType()) & (SPLIT_PARTICLE_TYPE))
141 int *numpart_list = (
int *)
Mem.mymalloc(
"numpart_list",
NTask *
sizeof(
int));
142 MPI_Allgather(&count, 1, MPI_INT, numpart_list, 1, MPI_INT,
Communicator);
147 maxid += numpart_list[i];
149 Mem.myfree(numpart_list);
169#ifdef SPLIT_PARTICLE_TYPE
170 if((1 <<
Sp.
P[i].
getType()) & (SPLIT_PARTICLE_TYPE))
180 double aa[3] = {a, a, a};
184 double bb[3] = {b, b, b};
192#ifdef SECOND_ORDER_LPT_ICS
214#ifdef SPLIT_PARTICLE_TYPE
215 for(
int i = 1; i <
NTYPES; i++)
216 if((1 << i) & (SPLIT_PARTICLE_TYPE))
222 mpi_printf(
"\nGENERATE_GAS_IN_ICS: Generated gas particles from DM particle distribution. TotNumGas=%lld\n\n",
Sp.
TotNumGas);
239 double molecular_weight;
245 u_init /= molecular_weight;
253 for(
int i = 0; i < Sp.NumGas; i++)
255 if(ThisTask == 0 && i == 0 && Sp.SphP[i].Entropy == 0)
256 mpi_printf(
"READIC: Initializing u from InitGasTemp !\n");
258 if(Sp.SphP[i].Entropy == 0)
266 for(
int i = 0; i < Sp.NumGas; i++)
267 Sp.SphP[i].Entropy = std::max<double>(
All.
MinEgySpec, Sp.SphP[i].Entropy);
270 CoolSfr.IonizeParams();
291 if(RestartSnapNum < 0)
308#if defined(EVALPOTENTIAL) && defined(PMGRID) && defined(PERIODIC)
311 for(
int i = 0; i < Sp.NumPart; i++)
312 mass_sum += Sp.P[i].getMass();
314 MPI_Allreduce(&mass_sum, &
All.TotalMass, 1, MPI_DOUBLE, MPI_SUM, Communicator);
321 for(
int i = 0; i < Sp.NumPart; i++)
323 for(
int j = 0; j < 3; j++)
324 Sp.P[i].Vel[j] *= afac;
331#
if defined(PMGRID) && !defined(TREEPM_NOTIMESPLIT)
332 All.PM_Ti_endstep =
All.PM_Ti_begstep = 0;
335 for(
int i = 0; i < Sp.NumPart; i++)
338 Sp.P[i].access.clear();
346 Sp.TimeBinSynchronized[i] = 1;
348 Sp.reconstruct_timebins();
350 for(
int i = 0; i < Sp.NumGas; i++)
352 Sp.SphP[i].EntropyPred = Sp.SphP[i].Entropy;
354 for(
int j = 0; j < 3; j++)
355 Sp.SphP[i].VelPred[j] = Sp.P[i].Vel[j];
364#ifdef PRESSURE_ENTROPY_SPH
365 Sp.SphP[i].EntropyToInvGammaPred =
pow(Sp.SphP[i].EntropyPred, 1.0 /
GAMMA);
368#ifdef TIMEDEP_ART_VISC
369#ifdef HIGH_ART_VISC_START
372 Sp.SphP[i].Alpha =
All.AlphaMin;
377#ifdef RECREATE_UNIQUE_IDS
378 recreate_unique_ids();
381 test_id_uniqueness();
383 Domain.domain_decomposition(
STANDARD);
385 GravTree.set_softenings();
387#ifdef ADAPTIVE_HYDRO_SOFTENING
388 mpi_printf(
"INIT: Adaptive hydro softening, minimum gravitational softening for SPH particles: %g\n",
389 All.MinimumComovingHydroSoftening);
390 mpi_printf(
"INIT: Adaptive hydro softening, maximum gravitational softening for SPH particles: %g\n",
392 mpi_printf(
"INIT: Adaptive hydro softening, number of softening values: %d\n",
NSOFTCLASSES_HYDRO);
395#ifdef INDIVIDUAL_GRAVITY_SOFTENING
396 Sp.init_individual_softenings();
403#if defined(SUBFIND) && defined(MERGERTREE)
405 MergerTree.get_previous_size_of_subhalo_for_each_particle(RestartSnapNum - 1);
411 for(
int i = 0; i < Sp.NumGas; i++)
413 if(ThisTask == 0 && i == 0)
414 printf(
"INIT: Converting u -> entropy All.cf_a3inv=%g\n",
All.
cf_a3inv);
420 for(
int i = 0; i < Sp.NumPart; i++)
422 Sp.PS[i].OriginTask = ThisTask;
423 Sp.PS[i].OriginIndex = i;
425 fof<simparticles> FoF{Communicator, &Sp, &Domain};
426 FoF.fof_fof(RestartSnapNum,
"fof",
"groups", 0);
434#ifdef SUBFIND_ORPHAN_TREATMENT
442 if(RestartSnapNum > 0)
444 subreadid_io SnapIDread(&Sp.IdStore, Communicator,
All.
SnapFormat);
445 SnapIDread.previously_bound_read_snap_ids(RestartSnapNum - 1);
447 FoF.subfind_match_ids_of_previously_most_bound_ids(&Sp);
460 NgbTree.treeallocate(Sp.NumGas, &Sp, &Domain);
461 NgbTree.treebuild(Sp.NumGas, NULL);
465#if defined(PMGRID) && defined(PERIODIC)
467 PM.calculate_power_spectra(RestartSnapNum);
469 mpi_printf(
"\nThis option (Power Spectrum) only works for PERIODIC and enabled PMGRID.\n\n");
476 setup_smoothinglengths();
482#ifdef PRESSURE_ENTROPY_SPH
483#ifndef INITIAL_CONDITIONS_CONTAIN_ENTROPY
484 NgbTree.setup_entropy_to_invgamma();
489 for(
int i = 0; i < Sp.NumGas; i++)
491#ifndef INITIAL_CONDITIONS_CONTAIN_ENTROPY
493 if(ThisTask == 0 && i == 0)
494 printf(
"INIT: Converting u -> entropy\n");
496#if !defined(PRESSURE_ENTROPY_SPH) && !defined(ISOTHERM_EQS)
499 Sp.SphP[i].EntropyPred = Sp.SphP[i].Entropy;
504 Sp.SphP[i].set_thermodynamic_variables();
506 mass += Sp.P[i].getMass();
520 mpi_printf(
"Skipping Omega check since not all particles are loaded\n");
527 for(
int i = 0; i < Sp.NumGas; i++)
529 Sp.SphP[i].Metallicity = Sp.P[i].Metallicity;
531 Sp.SphP[i].MassMetallicity = Sp.SphP[i].Metallicity * Sp.P[i].getMass();
550void sim::check_omega(
void)
558 MPI_Allreduce(&mass, &masstot, 1, MPI_DOUBLE, MPI_SUM,
Communicator);
565 "\n\nI've found something odd!\nThe mass content accounts only for Omega=%g,\nbut you specified Omega=%g in the "
566 "parameterfile.\n\nI better stop.\n",
581void sim::setup_smoothinglengths(
void)
592 mpi_printf(
"INIT: Setup smoothing lengths.\n");
626#ifdef PRESSURE_ENTROPY_SPH
635void sim::recreate_unique_ids(
void)
637 mpi_printf(
"INIT: Setting new unique IDs.\n");
639 int *numpart_list = (
int *)
Mem.mymalloc(
"numpart_list",
NTask *
sizeof(
int));
646 id += numpart_list[i];
651 Mem.myfree(numpart_list);
659void sim::test_id_uniqueness(
void)
661 mpi_printf(
"INIT: Testing ID uniqueness...\n");
667 int *num_list = (
int *)
Mem.mymalloc(
"num_list",
NTask *
sizeof(
int));
676 if(ids[i] == ids[i - 1])
684 int next_non_empty_task =
ThisTask + 1;
686 while(next_non_empty_task <
NTask)
687 if(num_list[next_non_empty_task] == 0)
688 next_non_empty_task++;
694 if(ids[
Sp.
NumPart - 1] == ids_first[next_non_empty_task])
698 Mem.myfree(num_list);
699 Mem.myfree(ids_first);
global_data_all_processes All
MySignedIntPosType pos_to_signedintpos(T posdiff)
double timediff(double t0, double t1)
void log_debug_md5(const char *msg)
void mpi_printf(const char *fmt,...)
domain< simparticles > Domain
void init(int RestartSnapNum)
Prepares the loaded initial conditions for the run.
void endrun(void)
This function aborts the simulations.
TimeBinData TimeBinsGravity
TimeBinData TimeBinsHydro
static bool compare_IDs(const MyIDType &a, const MyIDType &b)
void write_snapshot(int num, mysnaptype snap_type)
Save snapshot to disk.
void density(int *targetlist, int ntarget)
void treeallocate(int max_partindex, partset *Pptr, domain< partset > *Dptr)
int treebuild(int ninsert, int *indexlist)
#define NSOFTCLASSES_HYDRO
#define HYDROGEN_MASSFRAC
#define LIGHTCONE_MASSMAP_ALLOC_FAC
#define LIGHTCONE_ALLOC_FAC
@ MOST_BOUND_PARTICLE_SNAPHOT
int32_t MySignedIntPosType
#define BITS_FOR_POSITIONS
void sumup_large_ints(int n, int *src, long long *res, MPI_Comm comm)
expr pow(half base, half exp)
double mycxxsort_parallel(T *begin, T *end, Comp comp, MPI_Comm comm)
long long GlobalNActiveParticles
int SofteningClassOfPartType[NTYPES]
enum restart_options RestartFlag
double TopNodeAllocFactor
integertime Ti_begstep[TIMEBINS]
int ComovingIntegrationOn
long long TotNumDirectForces
double NgbTreeAllocFactor
char SnapshotFileBase[MAXLEN_PATH]
double TimeLastStatistics
void set_cosmo_factors_for_current_time(void)
char InitCondFile[MAXLEN_PATH]
void setSofteningClass(unsigned char softclass)
void setMass(MyDouble mass)
unsigned char getType(void)
void setType(unsigned char type)
void subdivide_evenly(long long N, int pieces, int index_bin, long long *first, int *count)