Fast Methods for Cosmological Simulations
FastSim serves as a tool for quick N-body simulations in modified gravity.
core_out.cpp
Go to the documentation of this file.
1 
9 #include <iomanip>
10 #include <boost/filesystem.hpp>
11 #include "core_out.h"
12 #include "class_particles.hpp"
13 
14 namespace fs = boost::filesystem;
15 
16 #define BUFF_SIZE 1024 * 1024 * 16 // 16 MB buffer
17 
18 Ofstream::Ofstream(std::string file_name) : std::ofstream(file_name), buf(new char[BUFF_SIZE])
19 {
20  if (!this->is_open()) throw std::runtime_error("Error while opening '" + file_name + "'");
21  this->rdbuf()->pubsetbuf(buf, sizeof(buf));
22 }
23 
25 {
26  delete[] buf;
27  if (this->is_open()) this->close();
28 }
29 
30 Ifstream::Ifstream(std::string file_name) : std::ifstream(file_name)
31 {
32  if (!this->is_open()) throw std::runtime_error("Error while opening '" + file_name + "'");
33 }
34 
36 {
37  if (this->is_open()) this->close();
38 }
39 
40 // Get current date/time, format is YYYY-MM-DD.HH:mm:ss
41 std::string currentDateTime()
42 {
43  const time_t now = time(0);
44  struct tm tstruct;
45  char buf[80];
46  gmtime_r(&now, &tstruct);
47  strftime(buf, sizeof(buf), "%y%m%d_%H%M%S", &tstruct);
48 
49  std::string returnval(buf);
50  return returnval;
51 }
52 
53 std::string std_out_dir(const std::string& pre_subdir, const Sim_Param &sim)
54 {
56  const std::string out_dir = sim.out_opt.out_dir + pre_subdir + currentDateTime() + "_" + std::to_string(sim.box_opt.mesh_num) +"m_" +
57  std::to_string(sim.box_opt.Ng) + "p_" + std::to_string(sim.box_opt.mesh_num_pwr) +"M_" +
58  std::to_string((size_t)sim.box_opt.box_size) + "b";
59 
61  if (!fs::exists(fs::path(out_dir.c_str()))) return out_dir + "/";
62 
64  else
65  {
66  for(size_t i = 2; ; ++i)
67  {
68  const std::string out_dir_new = out_dir + "_" + std::to_string(i);
69  if (!fs::exists(fs::path(out_dir_new.c_str()))) return out_dir_new + "/";
70  }
71  }
72 }
73 
74 void create_dir(const std::string &out_dir)
75 {
76  const fs::path dir(out_dir.c_str());
77  if(fs::create_directories(dir))
78  {
79  BOOST_LOG_TRIVIAL(debug) << "Directory created: "<< out_dir;
80  }
81 }
82 
83 void remove_dir(const std::string &out_dir)
84 {
85  const fs::path dir(out_dir.c_str());
86  if (fs::remove_all(dir))
87  {
88  BOOST_LOG_TRIVIAL(debug) << "Directory removed: "<< out_dir;
89  }
90 }
91 
92 void remove_all_files(const std::string &out_dir)
93 {
94  const fs::path dir(out_dir.c_str());
95  size_t i = 0;
96 
97  for(auto & p : fs::directory_iterator(dir))
98  {
99  if (fs::is_regular_file(p))
100  {
101  fs::remove(p);
102  ++i;
103  }
104  }
105  BOOST_LOG_TRIVIAL(debug) << "Removed " << i << " file(s) in directory: "<< out_dir;
106 }
107 
108 template <class T>
109 void print_par_pos_cut_small(const std::vector<T>& particles, const Sim_Param &sim, std::string out_dir, std::string suffix)
110 {
111  out_dir += "par_cut/";
112  std::string file_name = out_dir + "par_cut" + suffix + ".dat";
113  Ofstream File(file_name);
114 
115  BOOST_LOG_TRIVIAL(debug) << "Writing small cut through the box of particles into file " << file_name;
116  File << "# This file contains positions of particles in units [Mpc/h].\n";
117  FTYPE_t x, y, z, dx;
118  const FTYPE_t x_0 = sim.x_0();
119  const size_t N = sim.box_opt.par_num;
120  for(size_t i=0; i < N; i++)
121  {
122  x = particles[i].position[0];
123  y = particles[i].position[1];
124  z = particles[i].position[2];
125  dx = std::abs(y - sim.box_opt.mesh_num/2);
126  if ((dx < 0.5) && (x < sim.box_opt.mesh_num/4.) && (z < sim.box_opt.mesh_num/4.))
127  {
128  // cut (L/4 x L/4 x 0.5)
129  File << x*x_0 << "\t" << z*x_0 << "\t" << y*x_0 << "\n";
130  }
131  }
132 }
133 
134 void print_pow_spec(const Data_Vec<FTYPE_t, 2> &pwr_spec_binned, std::string out_dir, std::string suffix)
135 {
136  out_dir += "pwr_spec/";
137  std::string file_name = out_dir + "pwr_spec" + suffix + ".dat";
138  Ofstream File(file_name);
139 
140  BOOST_LOG_TRIVIAL(debug) << "Writing power spectrum into file " << file_name;
141  File << "# This file contains power spectrum P(k) in units [(Mpc/h)^3] depending on wavenumber k in units [h/Mpc].\n"
142  "# k [h/Mpc]\tP(k) [(Mpc/h)^3]\n";
143 
144  File << std::scientific;
145  const size_t size = pwr_spec_binned.size();
146  for (size_t j = 0; j < size; j++){
147  for (size_t i = 0; i < 2; i++){
148  File << pwr_spec_binned[i][j] << "\t";
149  }
150  File << "\n";
151  }
152 }
153 
154 void print_vel_pow_spec(const Data_Vec<FTYPE_t, 2> &pwr_spec_binned, std::string out_dir, std::string suffix)
155 {
156  out_dir += "vel_pwr_spec/";
157  std::string file_name = out_dir + "vel_pwr_spec" + suffix + ".dat";
158  Ofstream File(file_name);
159 
160  BOOST_LOG_TRIVIAL(debug) << "Writing velocity divergence power spectrum into file " << file_name;
161  File << "# This file contains velocity divergence power spectrum P(k) in units [(Mpc/h)^3] depending on wavenumber k in units [h/Mpc].\n"
162  "# k [h/Mpc]\tP(k) [(Mpc/h)^3]\n";
163 
164  File << std::scientific;
165  const size_t size = pwr_spec_binned.size();
166  for (size_t j = 0; j < size; j++){
167  for (size_t i = 0; i < 2; i++){
168  File << pwr_spec_binned[i][j] << "\t";
169  }
170  File << "\n";
171  }
172 }
173 
174 void print_corr_func(const Data_Vec<FTYPE_t, 2> &pwr_spec_binned, std::string out_dir, std::string suffix)
175 {
176  out_dir += "corr_func/";
177  std::string file_name = out_dir + "corr_func" + suffix + ".dat";
178  Ofstream File(file_name);
179 
180  BOOST_LOG_TRIVIAL(debug) << "Writing correlation function into file " << file_name;
181  File << "# This file contains correlation function depending on distance r in units [Mpc/h].\n"
182  "# x [Mpc/h]\txsi(r)\n";
183 
184  const size_t N = pwr_spec_binned.size();
185  for (size_t j = 0; j < N; j++){
186  if (pwr_spec_binned[1][j]) File << pwr_spec_binned[0][j] << "\t" << pwr_spec_binned[1][j] << "\n";
187  }
188 }
189 
190 template<typename T>
191 T rel_error(const T& a, const T& b)
192 {
193  return a ? fabs((a-b)/a) : fabs(a-b);
194 }
195 
196 template<typename T>
197 bool is_err(const std::vector<T>& vec1, const std::vector<T>& vec2, size_t bin)
198 {
199  const T err = rel_error( vec1[bin], vec2[bin]);
200  constexpr T prec_err = std::is_same<T, float>::value ? 1e-3f : 1e-7;
201  constexpr T prec_war = std::is_same<T, float>::value ? 1e-5f : 1e-12;
202 
203  if (err > prec_err){
204  BOOST_LOG_TRIVIAL(error) << "ERROR! Different values of k in bin " << bin << "! Relative error = " << err;
205  return true;
206  }
207  else if (err > prec_war) BOOST_LOG_TRIVIAL(warning) << "WARNING! Different values of k in bin " << bin << "! Relative error = " << err;
208  return false;
209 }
210 
211 void print_pow_spec_diff(const Data_Vec<FTYPE_t, 2> &pwr_spec_binned, const Data_Vec<FTYPE_t, 2> &pwr_spec_binned_0,
212  FTYPE_t growth, std::string out_dir, std::string suffix)
213 {
214  out_dir += "pwr_diff/";
215  std::string file_name = out_dir + "pwr_spec_diff" + suffix + ".dat";
216  Ofstream File(file_name);
217 
218  BOOST_LOG_TRIVIAL(debug) << "Writing power spectrum difference into file " << file_name;
219  File << "# This file contains relative difference between power spectrum P(k)\n"
220  "# and lineary extrapolated power spectrum of initial position of particles\n"
221  "# depending on wavenumber k in units [h/Mpc].\n"
222  "# k [h/Mpc]\t(P(k, z)-P_lin(k, z))/P_lin(k, z)\n";
223 
224  FTYPE_t P_k, P_lin;
225  File << std::setprecision(10);
226  const size_t size = pwr_spec_binned.size();
227  for (size_t j = 0; j < size; j++){
228  if (is_err(pwr_spec_binned[0], pwr_spec_binned_0[0], j)) continue;
229  P_k = pwr_spec_binned[1][j];
230  P_lin = pwr_spec_binned_0[1][j] * pow2(growth);
231  File << std::scientific << pwr_spec_binned_0[0][j] << "\t" << std::fixed << (P_k-P_lin)/P_lin << "\n";
232  }
233 }
234 
235 void print_pow_spec_diff(const Data_Vec<FTYPE_t, 2> &pwr_spec_binned, const Interp_obj &pwr_spec_input,
236  FTYPE_t growth, std::string out_dir, std::string suffix)
237 {
238  out_dir += "pwr_diff/";
239  std::string file_name = out_dir + "pwr_spec_diff" + suffix + ".dat";
240  Ofstream File(file_name);
241 
242  BOOST_LOG_TRIVIAL(debug) << "Writing power spectrum difference into file " << file_name;
243  File << "# This file contains relative difference between power spectrum P(k)\n"
244  "# and lineary extrapolated input power spectrum\n"
245  "# depending on wavenumber k in units [h/Mpc].\n"
246  "# k [h/Mpc]\t(P(k, z)-P_lin(k, z))/P_lin(k, z)\n";
247 
248  FTYPE_t k, P_k, P_lin;
249  const size_t size = pwr_spec_binned.size();
250  for (size_t j = 0; j < size; j++){
251  k = pwr_spec_binned[0][j];
252  if (k < pwr_spec_input.x_min) continue;
253  else if(k > pwr_spec_input.x_max) break;
254  else
255  {
256  P_k = pwr_spec_binned[1][j];
257  P_lin = pwr_spec_input(k) * pow2(growth);
258  File << std::scientific << k << "\t" << std::fixed << (P_k-P_lin)/P_lin << "\n";
259  }
260  }
261 }
262 
263 void print_pow_spec_diff(const Data_Vec<FTYPE_t, 2> &pwr_spec_binned, const Data_Vec<FTYPE_t, 2> &pwr_spec_binned_0,
264  const Interp_obj &pwr_spec_input, FTYPE_t growth_now, FTYPE_t growth_init, std::string out_dir, std::string suffix)
265 {
266  out_dir += "pwr_diff/";
267  std::string file_name = out_dir + "pwr_spec_diff" + suffix + ".dat";
268  Ofstream File(file_name);
269 
270  BOOST_LOG_TRIVIAL(debug) << "Writing power spectrum difference into file " << file_name;
271  File << "# This file contains relative difference between power spectrum P(k)\n"
272  "# and lineary extrapolated 'hybrid' power spectrum\n"
273  "# depending on wavenumber k in units [h/Mpc].\n"
274  "# k [h/Mpc]\t(P(k, z)-P_lin(k, z))/P_lin(k, z)\n";
275 
276  FTYPE_t k, P_k, P_input, P_par;
277  File << std::setprecision(10);
278  const size_t size = pwr_spec_binned.size();
279  for (size_t j = 0; j < size; j++){
280  if (is_err(pwr_spec_binned[0], pwr_spec_binned_0[0], j)) continue;
281  k = pwr_spec_binned_0[0][j];
282  if (k < pwr_spec_input.x_min) continue;
283  else if(k > pwr_spec_input.x_max) break;
284  else
285  {
286  P_k = pwr_spec_binned[1][j];
287  P_input = pwr_spec_input(k) * pow2(growth_now);
288  P_par = pwr_spec_binned_0[1][j] * pow2(growth_now / growth_init);
289  File << std::scientific << k << "\t" << std::fixed << P_k/P_input - P_k/P_par << "\n";
290  }
291  }
292 }
293 
294 void print_vel_pow_spec_diff(const Data_Vec<FTYPE_t, 2> &pwr_spec_binned, const Data_Vec<FTYPE_t, 2> &pwr_spec_binned_0,
295  FTYPE_t dDda, std::string out_dir, std::string suffix)
296 {
297  out_dir += "vel_pwr_diff/";
298  std::string file_name = out_dir + "vel_pwr_spec_diff" + suffix + ".dat";
299  Ofstream File(file_name);
300 
301  BOOST_LOG_TRIVIAL(debug) << "Writing power velocity divergence spectrum difference into file " << file_name;
302  File << "# This file contains relative difference between velocity divergence power spectrum P(k)\n"
303  "# and lineary extrapolated velocity divergence power spectrum depending on wavenumber k in units [h/Mpc].\n"
304  "# k [h/Mpc]\t(P(k, z)-P_lin(k, z))/P_lin(k, z)\n";
305 
306  FTYPE_t P_k, P_ZA;
307  File << std::setprecision(10);
308  const size_t size = pwr_spec_binned.size();
309  for (size_t j = 0; j < size; j++){
310  if (is_err(pwr_spec_binned[0], pwr_spec_binned_0[0], j)) continue;
311  P_k = pwr_spec_binned[1][j];
312  P_ZA = pwr_spec_binned_0[1][j] * pow2(dDda);
313  File << std::scientific << pwr_spec_binned_0[0][j] << "\t" << std::fixed << (P_k-P_ZA)/P_ZA << "\n";
314  }
315 }
316 
317 void print_rho_map(const Mesh& delta, const Sim_Param &sim, std::string out_dir, std::string suffix)
318 {
319  out_dir += "rho_map/";
320  const FTYPE_t x_0 = sim.x_0_pwr();
321  std::string file_name = out_dir + "rho_map" + suffix + ".dat";
322  Ofstream File(file_name);
323 
324  BOOST_LOG_TRIVIAL(debug) << "Writing density map into file " << file_name;
325  File << "# This file contains density map delta(x).\n";
326  File << "# x [Mpc/h]\tz [Mpc/h]\tdelta\n";
327 
328  #define HALF_THICKNESS 2
329  #define MAX_SIZE 512
330  // create buffer into which we can write in parallel
331  // smear density field if we have very hight accuracy
332  const size_t N = sim.box_opt.mesh_num_pwr;
333  const size_t N_step = N > MAX_SIZE ? N / MAX_SIZE : 1;
334  std::vector<FTYPE_t> buffer(N/N_step*N/N_step);
335 
336  // go throught one side (in parallel)
337  #pragma omp parallel for
338  for (size_t i = 0; i < N; i += N_step)
339  {
340  for (size_t j = 0; j < N; j += N_step)
341  {
342  // average over one side, add up 3rd dimension
343  FTYPE_t proj_delta = 0;
344  for (size_t i_xx = 0; i_xx < N_step; i_xx++)
345  {
346  for (size_t j_xx = 0; j_xx < N_step; j_xx++)
347  {
348  for (int k = -HALF_THICKNESS; k < HALF_THICKNESS; k++)
349  {
350  // we are at [i+i_xx, N/2 + k, j+j_xx]
351  proj_delta += delta(i+i_xx, sim.box_opt.mesh_num_pwr/2 + k, j+j_xx) + 1;
352  }
353  }
354  }
355  // average and save
356  proj_delta /= N_step*N_step;
357  proj_delta--;
358  size_t id = (i/N_step) * (N/N_step) + j/N_step;
359  buffer[id] = proj_delta;
360  }
361  }
362 
363  // write into file
364  for (size_t i = 0; i < N; i += N_step)
365  {
366  for (size_t j = 0; j < N; j += N_step)
367  {
368  size_t id = (i/N_step) * (N/N_step) + j/N_step;
369  FTYPE_t proj_delta = buffer[id];
370  File << i*x_0 << "\t" << j*x_0 << "\t" << proj_delta << "\n";
371  }
372  File << "\n";
373  }
374 }
375 
376 void print_projected_rho(const Mesh& delta, const Sim_Param &sim, std::string out_dir, std::string suffix)
377 {
378  out_dir += "rho_map/";
379  const FTYPE_t x_0 = sim.x_0_pwr();
380  std::string file_name = out_dir + "rho_map_projected" + suffix + ".dat";
381  Ofstream File(file_name);
382 
383  BOOST_LOG_TRIVIAL(debug) << "Writing density map into file " << file_name << "\n";
384  File << "# This file contains density map delta(x).\n"
385  "# x [Mpc/h]\tz [Mpc/h]\tdelta\n";
386  FTYPE_t rho, rho_tmp;
387  const size_t N = sim.box_opt.mesh_num_pwr;
388  for (size_t i = 0; i < N; i++){
389  for (size_t j = 0; j < N; j++){
390  rho = 0;
391  for (size_t k = 0; k < N; k++){
392  rho_tmp = delta(i, k, j);
393  // if (rho_tmp != -1) printf("Density in (%i, %i, %i) = %f\n", i, j, k, rho_tmp);
394  rho+=rho_tmp + 1;
395  }
396  File << i*x_0 << "\t" << j*x_0 << "\t" << rho -1 << "\n";
397  }
398  File << "\n";
399  }
400 }
401 
402 void print_dens_bin(const std::vector<size_t> &dens_binned, std::string out_dir, std::string suffix){
403  out_dir += "rho_bin/";
404  std::string file_name = out_dir + "rho_bin" + suffix + ".dat";
405  Ofstream File(file_name);
406 
407  BOOST_LOG_TRIVIAL(debug) << "Writing binned density into file " << file_name;
408  File << "# This file contains binned density field.\n"
409  "# dens\tbin_num\n";
410  FTYPE_t dens;
411  const size_t N = dens_binned.size();
412  for (size_t j = 0; j < N; j++)
413  {
414  dens = j*0.1-0.9;
415  File << dens << "\t" << dens_binned[j] << "\n";
416  }
417 }
418 
419 template void print_par_pos_cut_small(const std::vector<Particle_x<FTYPE_t>>&, const Sim_Param&, std::string, std::string);
420 template void print_par_pos_cut_small(const std::vector<Particle_v<FTYPE_t>>&, const Sim_Param&, std::string, std::string);
void print_rho_map(const Mesh &delta, const Sim_Param &sim, std::string out_dir, std::string suffix)
Definition: core_out.cpp:317
double box_size
Definition: params.hpp:59
void print_vel_pow_spec_diff(const Data_Vec< double, 2 > &pwr_spec_binned, const Data_Vec< double, 2 > &pwr_spec_binned_0, double dDda, std::string out_dir, std::string suffix)
Definition: core_out.cpp:294
Ifstream(std::string file_name)
Definition: core_out.cpp:30
std::string std_out_dir(const std::string &pre_subdir, const Sim_Param &sim)
Definition: core_out.cpp:53
size_t par_num
Definition: params.hpp:61
functions handling output of the program
std::string currentDateTime()
Definition: core_out.cpp:41
: linear interpolation (Steffen) of data [x, y]
Definition: core_power.h:96
class handling particles (position only)
Box_Opt box_opt
Definition: params.hpp:202
void remove_all_files(const std::string &out_dir)
Definition: core_out.cpp:92
: class storing simulation parameters
Definition: params.hpp:193
size_t size() const noexcept
size_t mesh_num_pwr
Definition: params.hpp:58
Definition: json.hpp:20160
void print_dens_bin(const std::vector< size_t > &dens_binned, std::string out_dir, std::string suffix)
Definition: core_out.cpp:402
: creates a mesh of N*N*(N+2) cells
Definition: class_mesh.hpp:95
~Ifstream()
Definition: core_out.cpp:35
void print_pow_spec(const Data_Vec< double, 2 > &pwr_spec_binned, std::string out_dir, std::string suffix)
Definition: core_out.cpp:134
#define HALF_THICKNESS
define container Particle (with and without velocity)
void print_vel_pow_spec(const Data_Vec< double, 2 > &pwr_spec_binned, std::string out_dir, std::string suffix)
Definition: core_out.cpp:154
T pow2(T base)
Definition: precision.hpp:52
size_t Ng
Definition: params.hpp:61
void print_projected_rho(const Mesh &delta, const Sim_Param &sim, std::string out_dir, std::string suffix)
Definition: core_out.cpp:376
double x_min
Definition: core_power.h:104
bool is_err(const std::vector< T > &vec1, const std::vector< T > &vec2, size_t bin)
Definition: core_out.cpp:197
class handling particles (position only)
declaration in params.hpp
Definition: core_power.h:19
void create_dir(const std::string &out_dir)
Definition: core_out.cpp:74
double x_0_pwr() const
Definition: params.hpp:217
static CCL_BEGIN_DECLS double x[111][8]
T rel_error(const T &a, const T &b)
Definition: core_out.cpp:191
Out_Opt out_opt
Definition: params.hpp:204
void print_pow_spec_diff(const Data_Vec< double, 2 > &pwr_spec_binned, const Data_Vec< double, 2 > &pwr_spec_binned_0, double growth, std::string out_dir, std::string suffix)
Definition: core_out.cpp:211
#define BUFF_SIZE
Definition: core_out.cpp:16
void print_corr_func(const Data_Vec< double, 2 > &pwr_spec_binned, std::string out_dir, std::string suffix)
Definition: core_out.cpp:174
static double z[8]
static int p
Definition: ccl_emu17.c:25
void print_par_pos_cut_small(const std::vector< T > &particles, const Sim_Param &sim, std::string out_dir, std::string suffix)
Definition: core_out.cpp:109
#define MAX_SIZE
void remove_dir(const std::string &out_dir)
Definition: core_out.cpp:83
~Ofstream()
Definition: core_out.cpp:24
double x_0() const
Definition: params.hpp:216
char * buf
Definition: core_out.h:25
size_t mesh_num
Definition: params.hpp:58
std::string out_dir
Definition: params.hpp:86
auto value(T const &val) -> Generator< T >
Definition: catch.hpp:3177
double x_max
Definition: core_power.h:104
bool exists(std::string filename)
Definition: continuity.cpp:195
Ofstream(std::string file_name)
Definition: core_out.cpp:18