GADGET-4
second_order_ics.cc
Go to the documentation of this file.
1 /*******************************************************************************
2  * \copyright This file is part of the GADGET4 N-body/SPH code developed
3  * \copyright by Volker Springel. Copyright (C) 2014-2020 by Volker Springel
4  * \copyright (vspringel@mpa-garching.mpg.de) and all contributing authors.
5  *******************************************************************************/
6 
12 #include "gadgetconfig.h"
13 
14 #include <math.h>
15 #include <mpi.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #include "../data/allvars.h"
20 #include "../data/dtypes.h"
21 #include "../data/intposconvert.h"
22 #include "../data/mymalloc.h"
23 #include "../gravtree/gravtree.h"
24 #include "../io/io.h"
25 #include "../main/simulation.h"
26 #include "../system/system.h"
27 #include "../time_integration/driftfac.h"
28 
29 #ifdef SECOND_ORDER_LPT_ICS
30 
31 double sim::F1_Omega(double a)
32 {
33  double omega_a = All.Omega0 / (All.Omega0 + a * (1 - All.Omega0 - All.OmegaLambda) + a * a * a * All.OmegaLambda);
34 
35  return pow(omega_a, 5.0 / 9);
36 }
37 
38 double sim::F2_Omega(double a)
39 {
40  double omega_a = All.Omega0 / (All.Omega0 + a * (1 - All.Omega0 - All.OmegaLambda) + a * a * a * All.OmegaLambda);
41 
42  return 2.0 * pow(omega_a, 6.0 / 11);
43 }
44 
45 void sim::second_order_ic_correction(void)
46 {
47  if(executed)
48  return;
49 
50  mpi_printf("SECOND_ORDER_LPT_ICS: Now producing ICs based on 2nd-order LPT\n");
51 
52  particle_data *P = Sp.P;
53 
54  /* first, back up masses and set special 2nd LPT masses (which have been read in in the field OldAcc) */
55 
56  double *mass_bak = (double *)Mem.mymalloc("mass_bak", Sp.NumPart * sizeof(double));
57 
58  for(int i = 0; i < Sp.NumPart; i++)
59  {
60  mass_bak[i] = P[i].getMass();
61  P[i].setMass(P[i].OldAcc);
62  }
63 
64  /* now do the gravity computation */
65 
66 #if defined(PMGRID) && defined(PERIODIC) && !defined(TREEPM_NOTIMESPLIT)
68 #endif
69  gravity(0);
70 
72  gravity(0);
73 
74  /* correct the ICs accordingly */
75 
76  double a = All.TimeBegin;
77 
78  double hubble = Driftfac.hubble_function(a);
79 
80  double fac1 = 1.0 / (a * a * hubble * F1_Omega(a)); /* this factor converts the Zeldovich peculiar velocity
81  (expressed as a^2*dX/dt to comoving displacement */
82  double fac2 = All.LptScalingfactor;
83 
84  double fac3 = fac2 * a * a * hubble * F2_Omega(a);
85 
86  mpi_printf("SECOND_ORDER_LPT_ICS: fac1=%g fac2=%g fac3=%g\n", fac1, fac2, fac3);
87 
88  for(int i = 0; i < Sp.NumPart; i++)
89  {
90  double posdiff[3];
91  for(int j = 0; j < 3; j++)
92  posdiff[j] = fac1 * P[i].Vel[j]; /* Zeldovich displacement */
93 
94  MyIntPosType delta[3];
95  Sp.pos_to_signedintpos(posdiff, (MySignedIntPosType *)delta);
96 
97  for(int j = 0; j < 3; j++)
98  P[i].IntPos[j] += delta[j];
99 
100  double acc[3];
101 #if defined(PMGRID) && defined(PERIODIC) && !defined(TREEPM_NOTIMESPLIT)
102  for(int j = 0; j < 3; j++)
103  acc[j] = P[i].GravPM[j] + P[i].GravAccel[j];
104 #else
105  for(int j = 0; j < 3; j++)
106  acc[j] = P[i].GravAccel[j];
107 #endif
108 
109  for(int j = 0; j < 3; j++)
110  posdiff[j] = fac2 * acc[j]; /* second order lpt displacement */
111 
112  Sp.pos_to_signedintpos(posdiff, (MySignedIntPosType *)delta);
113 
114  for(int j = 0; j < 3; j++)
115  P[i].IntPos[j] += delta[j];
116 
117  for(int j = 0; j < 3; j++)
118  P[i].Vel[j] += fac3 * acc[j]; /* second order lpt velocity correction */
119  }
120 
121  /* now restore the correct masses */
122 
123  for(int i = 0; i < Sp.NumPart; i++)
124  {
125  P[i].setMass(mass_bak[i]);
126  P[i].OldAcc = 0;
127  }
128 
129  Mem.myfree(mass_bak);
130 
131  mpi_printf("SECOND_ORDER_LPT_ICS: finished,\n");
132 
133  executed = 1;
134 
135  if(All.TypeOfOpeningCriterion == 1)
137 
138  /* put in an extra domain decomposition because particle positions have been shifted */
139 
140  NgbTree.treefree();
144  NgbTree.treebuild(Sp.NumGas, NULL);
145 }
146 
147 #endif
global_data_all_processes All
Definition: main.cc:40
void domain_free(void)
Definition: domain.cc:179
void domain_decomposition(domain_options mode)
Definition: domain.cc:51
static double hubble_function(double a)
Definition: driftfac.h:39
MySignedIntPosType pos_to_signedintpos(T posdiff)
void mpi_printf(const char *fmt,...)
Definition: setcomm.h:55
domain< simparticles > Domain
Definition: simulation.h:58
void gravity(int timebin)
main driver routine of gravity tree/fmm force calculation
Definition: gravity.cc:171
void gravity_long_range_force(void)
sph NgbTree
Definition: simulation.h:68
simparticles Sp
Definition: simulation.h:56
particle_data * P
Definition: simparticles.h:54
void treeallocate(int max_partindex, partset *Pptr, domain< partset > *Dptr)
Definition: tree.cc:776
void treefree(void)
Definition: tree.cc:1228
int treebuild(int ninsert, int *indexlist)
Definition: tree.cc:52
@ STANDARD
Definition: domain.h:23
uint32_t MyIntPosType
Definition: dtypes.h:35
int32_t MySignedIntPosType
Definition: dtypes.h:36
driftfac Driftfac
Definition: main.cc:41
memory Mem
Definition: main.cc:44
expr pow(half base, half exp)
Definition: half.hpp:2803
MyDouble getMass(void)
void setMass(MyDouble mass)