Fast Methods for Cosmological Simulations
FastSim serves as a tool for quick N-body simulations in modified gravity.
adhesion.cpp
Go to the documentation of this file.
1 
9 #include "adhesion.hpp"
10 #include "core_app.h"
11 #include "core_mesh.h"
12 #include "integration.hpp"
13 #include "params.hpp"
14 
15 #include <algorithm>
16 
17 namespace {
18 const FTYPE_t ACC = 1e-10;
19 const FTYPE_t log_acc = log(ACC);
20 
21 void gen_init_expot(const Mesh& potential, Mesh& expotential, FTYPE_t nu)
22 {
23  BOOST_LOG_TRIVIAL(debug) << "Storing initial expotenital in q-space...";
24  // store exponent only
25  // *expotential = potential; !!! <- do not use this in case potential and expotential are meshes of different size
26  #pragma omp parallel for
27  for (size_t i = 0; i < expotential.length; i++) expotential[i] = -potential[i] / (2*nu);
28 }
29 
30 FTYPE_t get_summation(const std::vector<FTYPE_t>& exp_aux)
31 {
32  FTYPE_t max_exp = *max_element(exp_aux.begin(), exp_aux.end());
33  FTYPE_t sum = 0;
34  for(auto const& a_exp: exp_aux) {
35  if ((a_exp - max_exp) > log_acc) sum+= exp(a_exp - max_exp);
36  }
37  return max_exp + log(sum);
38 }
39 
40 void convolution_y1(Mesh& potential, const std::vector<FTYPE_t>& gaussian, const Mesh& expotential_0){
41  // multi-thread index is y3
42  // compute f1 (x1, y2, y3)
43 
44  const unsigned int N = potential.N;
45  std::vector<FTYPE_t> exp_aux;
46 
47  #pragma omp parallel for private(exp_aux)
48  for (int x1 = 0; x1 < N; x1++){
49  for (int y2 = 0; y2 < N; y2++){
50  for (int y3 = 0; y3 < N; y3++){
51  exp_aux.reserve(N);
52  // fill in exponents
53  for (int y1 = 0; y1 < N; y1++){
54  exp_aux.push_back(expotential_0(y1, y2, y3)+gaussian[std::abs(x1-y1)]);
55  }
56  potential(x1, y2, y3) = get_summation(exp_aux); // potential is now f1
57  exp_aux.clear();
58  }
59  }
60  }
61 }
62 
63 void convolution_y2(Mesh& potential, const std::vector<FTYPE_t>& gaussian){
64  // compute f2 (x1, x2, y3)
65 
66  const unsigned int N = potential.N;
67  std::vector<FTYPE_t> sum_aux;
68  std::vector<FTYPE_t> exp_aux;
69 
70  #pragma omp parallel for private(sum_aux, exp_aux)
71  for (int x1 = 0; x1 < N; x1++){
72  for (int y3 = 0; y3 < N; y3++){
73  sum_aux.reserve(N);
74  for (int x2 = 0; x2 < N; x2++){
75  exp_aux.reserve(N);
76  // fill in exponents
77  for (int y2 = 0; y2 < N; y2++){
78  exp_aux.push_back(potential(x1, y2, y3) + gaussian[abs(x2-y2)]);
79  }
80  sum_aux.push_back(get_summation(exp_aux));
81  exp_aux.clear();
82  }
83 
84  for (int x2 = 0; x2 < N; x2++){
85  potential(x1, x2, y3) = sum_aux[x2]; // potential is now f2
86  }
87  sum_aux.clear();
88  }
89  }
90 }
91 
92 void convolution_y3(Mesh& potential, const std::vector<FTYPE_t>& gaussian){
93  // compute f3 (x1, x2, x3) == expotential(x, b)
94 
95  const unsigned int N = potential.N;
96  std::vector<FTYPE_t> sum_aux;
97  std::vector<FTYPE_t> exp_aux;
98 
99  #pragma omp parallel for private(sum_aux, exp_aux)
100  for (int x1 = 0; x1 < N; x1++){
101  for (int x2 = 0; x2 < N; x2++){
102  sum_aux.reserve(N);
103  for (int x3 = 0; x3 < N; x3++){
104  exp_aux.reserve(N);
105  // fill in exponents
106  for (int y3 = 0; y3 < N; y3++){
107  exp_aux.push_back(potential(x1, x2, y3) + gaussian[abs(x3-y3)]);
108  }
109  sum_aux.push_back(get_summation(exp_aux));
110  exp_aux.clear();
111  }
112  for (int x3 = 0; x3 < N; x3++){
113  potential(x1, x2, x3) = sum_aux[x3]; // potential is now f3
114  }
115  sum_aux.clear();
116  }
117  }
118 }
119 
120 void gen_expot(Mesh& potential, const Mesh& expotential_0, FTYPE_t nu, FTYPE_t b)
121 {
122  /* Computing convolution using direct sum */
123  BOOST_LOG_TRIVIAL(debug) << "Computing expotential in q-space...";
124  /*
125  f(x1, x2, x3) = \int dy^3 { g(y1, y2, y3) * h(x1 - y1) * h(x2 - y2) * h(x3 - y3)}
126  ..
127  f1 (x1, y2, y3) = \int dy1 { g (y1, y2, y3) * h(x1 - y1)} :: N^3 sums of length N
128  f2 (x1, x2, y3) = \int dy2 { f1 (x1, y2, y3) * h(x2 - y2)} :: N^3 sums of length N
129  f3 (x1, x2, x3) = \int dy3 { f2 (x1, x2, y3) * h(x3 - y3)} :: N^3 sums of length N
130  */
131 
132  // store values of exponential - every convolution uses the same exp(-r^2/4bv)
133  std::vector<FTYPE_t> gaussian(expotential_0.N);
134 
135  #pragma omp parallel for
136  for (size_t i = 0; i < expotential_0.N; i++){
137  gaussian[i]=-i*i/(4*b*nu);
138  }
139 
140  convolution_y1(potential, gaussian, expotential_0);
141  convolution_y2(potential, gaussian);
142  convolution_y3(potential, gaussian);
143 }
144 
145 }// end of anonymous namespace
146 
153 {
154 public:
155  AAImpl(const Sim_Param &sim): expotential(sim.box_opt.mesh_num)
156  {
157  memory_alloc = sizeof(FTYPE_t)*expotential.length;
158  }
159 
161  {
162  BOOST_LOG_TRIVIAL(debug) << "Computing potential...";
163  gen_expot(APP.app_field[0], expotential, APP.sim.app_opt.nu, APP.a_half());
164  APP.app_field[0] *= -2*APP.sim.app_opt.nu;
165 
166  BOOST_LOG_TRIVIAL(debug) << "Computing velocity field via FFT...";
167  fftw_execute_dft_r2c(APP.p_F, APP.app_field[0]);
168  gen_displ_k(APP.app_field, APP.app_field[0]);
170  }
171 
172  // VARIABLES
174  uint64_t memory_alloc;
175 };
176 
178  App_Var<Particle_v<FTYPE_t>>(sim, "AA", "Adhesion approximation"), m_impl(new AAImpl(sim))
179 {
180  memory_alloc += m_impl->memory_alloc;
181 }
182 
183 App_Var_AA::~App_Var_AA() = default;
184 
185 void App_Var_AA::pot_corr(std::vector<Mesh>& vel_field, Mesh& pot_k)
186 {
187  /* Computing initial expotential */
188  fftw_execute_dft_c2r(p_B, pot_k);
189  gen_init_expot(pot_k, m_impl->expotential, sim.app_opt.nu);
190 }
191 
193 {// Leapfrog method for adhesion
194  m_impl->aa_convolution(*this);
195  auto kick_step = [&](){ kick_step_w_momentum(sim.cosmo, a_half(), da(), particles, app_field); };
197 }
class containing core variables and methods for approximations
Definition: app_var.hpp:41
void stream_kick_stream(const double da, std::vector< Particle_v< double >> &particles, std::function< void()> kick_step, size_t per)
Definition: integration.cpp:24
class handling particles (position only)
Box_Opt box_opt
Definition: params.hpp:202
void upd_pos() override
Definition: adhesion.cpp:192
double nu
Definition: params.hpp:116
void kick_step_w_momentum(const Cosmo_Param &cosmo, const double a, const double da, std::vector< Particle_v< double >> &particles, const std::vector< Mesh > &force_field)
Definition: integration.cpp:48
AAImpl(const Sim_Param &sim)
Definition: adhesion.cpp:155
void gen_displ_k(std::vector< Mesh > &vel_field, const Mesh &pot_k)
Definition: core_app.cpp:623
: class storing simulation parameters
Definition: params.hpp:193
void fftw_execute_dft_r2c(const FFTW_PLAN_TYPE &p_F, Mesh &rho)
compute forward (real to complex) FFT on mesh (inplace)
Definition: core_mesh.cpp:247
: creates a mesh of N*N*(N+2) cells
Definition: class_mesh.hpp:95
void fftw_execute_dft_c2r_triple(const FFTW_PLAN_TYPE &p_B, std::vector< Mesh > &rho)
compute three backward (complex to real) FFTs on vector of meshes (inplace)
Definition: core_mesh.cpp:263
ahesion approximation interface
uint64_t memory_alloc
Definition: adhesion.cpp:174
FFTW_PLAN_TYPE p_F
Definition: app_var.hpp:69
void gen_expot(Mesh &potential, const Mesh &expotential_0, double nu, double b)
Definition: adhesion.cpp:120
functions for integration of particle trajectories
void fftw_execute_dft_c2r(const FFTW_PLAN_TYPE &p_B, Mesh &rho)
compute backward (complex to real) FFT on mesh (inplace)
Definition: core_mesh.cpp:253
std::vector< Mesh > app_field
Definition: app_var.hpp:63
Cosmo_Param cosmo
Definition: params.hpp:206
void pot_corr(std::vector< Mesh > &vel_field, Mesh &pot_k) override
Definition: adhesion.cpp:185
interface for common functions for all types of approximations
: class containing variables and methods for adhesion approximation
Definition: adhesion.hpp:35
void aa_convolution(App_Var_AA &APP)
Definition: adhesion.cpp:160
various simulation parameters
std::vector< Particle_v< double > > particles
Definition: app_var.hpp:65
FFTW_PLAN_TYPE p_B
Definition: app_var.hpp:69
size_t N
Definition: class_mesh.hpp:102
void convolution_y2(Mesh &potential, const std::vector< double > &gaussian)
Definition: adhesion.cpp:63
size_t length
Definition: class_mesh.hpp:32
const std::unique_ptr< AAImpl > m_impl
Definition: adhesion.hpp:44
basic functions to work with mesh
App_Var_AA(const Sim_Param &sim)
Definition: adhesion.cpp:177
double a_half()
Definition: app_var.cpp:529
size_t mesh_num
Definition: params.hpp:58
void convolution_y1(Mesh &potential, const std::vector< double > &gaussian, const Mesh &expotential_0)
Definition: adhesion.cpp:40
App_Opt app_opt
Definition: params.hpp:207
void gen_init_expot(const Mesh &potential, Mesh &expotential, double nu)
Definition: adhesion.cpp:21
void convolution_y3(Mesh &potential, const std::vector< double > &gaussian)
Definition: adhesion.cpp:92
double get_summation(const std::vector< double > &exp_aux)
Definition: adhesion.cpp:30