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
31double 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
38double 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
45void 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
137
138 /* put in an extra domain decomposition because particle positions have been shifted */
139
141 Domain.domain_free();
142 Domain.domain_decomposition(STANDARD);
144 NgbTree.treebuild(Sp.NumGas, NULL);
145}
146
147#endif
global_data_all_processes All
Definition: main.cc:40
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:1232
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)