Fast Methods for Cosmological Simulations
FastSim serves as a tool for quick N-body simulations in modified gravity.
mod_frozen_potential.cpp
Go to the documentation of this file.
1 
9 #include "core_app.h"
10 #include "core_mesh.h"
11 #include "integration.hpp"
12 #include "params.hpp"
13 
14 namespace {
15 
22 {
23 public:
24  // CONSTRUCTORS & DESTRUCTOR
25  LinkedList(size_t par_num, size_t m, FTYPE_t hc):
26  par_num(par_num), Hc(hc), LL(par_num), HOC(m, m, m) {}
27 
28  // VARIABLES
29  size_t par_num;
30  FTYPE_t Hc;
31  std::vector<size_t> LL;
33 
34  // METHODS
35  void get_linked_list(const std::vector<Particle_v<FTYPE_t>>& particles)
36  {
37  HOC.assign(-1);
38  for (size_t i = 0; i < par_num; i++)
39  {
40  LL[i] = HOC(particles[i].position/Hc);
41  HOC(particles[i].position/Hc) = i;
42  }
43  }
44 };
45 
46 FTYPE_t force_ref(const FTYPE_t r, const FTYPE_t a){
47  // Reference force for an S_2-shaped particle
48  FTYPE_t z = 2 * r / a;
49  if (z > 2) return 1 / (r*r);
50  else if (z > 1) return (12 / (z*z) - 224 + 896 * z - 840 * z*z + 224 * pow(z, 3) +
51  70 * pow(z, 4) - 48 * pow(z, 5) + 7 * pow(z, 6)) / (35 * a*a);
52  else return (224 * z - 224 * pow(z, 3) + 70 * pow(z, 4) + 48 * pow(z, 5) - 21 * pow(z, 7)) / (35 * a*a);
53 }
54 
55 FTYPE_t force_tot(const FTYPE_t r, const FTYPE_t e2){
56  return 1 / (r*r+e2);
57 }
58 
59 void force_short(const Sim_Param &sim, const FTYPE_t D, const LinkedList& linked_list, const std::vector<Particle_v<FTYPE_t>>& particles,
60  const Vec_3D<FTYPE_t>& position, Vec_3D<FTYPE_t>& force, Interp_obj& fs_interp)
61 { // Calculate short range force in position, force is added
62  #define FORCE_SHORT_NO_INTER
63  size_t p;
64  Vec_3D<FTYPE_t> dr_vec;
65  FTYPE_t dr2;
66  FTYPE_t dr; // <-- #ifdef FORCE_SHORT_NO_INTER
67  const FTYPE_t m = pow((FTYPE_t)sim.box_opt.Ng, 3) / D;
68  const size_t Nm = sim.box_opt.mesh_num;
69  const FTYPE_t rs2 = pow2(sim.app_opt.rs);
70  const FTYPE_t e2 = pow2(sim.box_opt.Ng*0.1); // <-- #ifdef FORCE_SHORT_NO_INTER
71 
72  IT<3> it(position, sim.app_opt.Hc);
73  do{
74  p = linked_list.HOC(it.vec);
75  while (p != -1){
76  dr_vec = get_sgn_distance(particles[p].position, position, Nm);
77  dr2 = dr_vec.norm2();
78  if ((dr2 < rs2) && (dr2 != 0)) // Short range force is set 0 for separation larger than cutoff radius
79  {
80  #ifdef FORCE_SHORT_NO_INTER
81  dr = sqrt(dr2);
82  force += dr_vec*(force_tot(dr, e2) - force_ref(dr, sim.app_opt.a))*m/(dr*4*PI);
83  #else
84  force += dr_vec*(m/sqrt(dr2)*fs_interp.eval(dr2));
85  #endif
86  }
87  p = linked_list.LL[p];
88  }
89  } while( it.iter() );
90 }
91 
92 void kick_step_w_pp(const Sim_Param &sim, const FTYPE_t a, const FTYPE_t da, std::vector<Particle_v<FTYPE_t>>& particles, const std::vector< Mesh> &force_field,
93  LinkedList& linked_list, Interp_obj& fs_interp)
94 { // 2nd order ODE with long & short range potential
95  const size_t Np = particles.size();
96  Vec_3D<FTYPE_t> force;
97  const FTYPE_t D = growth_factor(a, sim.cosmo);
98  const FTYPE_t OL = sim.cosmo.Omega_L()*pow(a,3);
99  const FTYPE_t Om = sim.cosmo.Omega_m;
100  // -3/2a represents usual EOM, the rest are LCDM corrections
101  const FTYPE_t f1 = 3/(2*a)*(Om+2*OL)/(Om+OL);
102  const FTYPE_t f2 = 3/(2*a)*Om/(Om+OL)*D/a;
103 
104  BOOST_LOG_TRIVIAL(debug) << "Creating linked list...";
105  linked_list.get_linked_list(particles);
106 
107  BOOST_LOG_TRIVIAL(debug) << "Computing short and long range parts of the potential...";
108  #pragma omp parallel for private(force)
109  for (size_t i = 0; i < Np; i++)
110  {
111  force.fill(0.);
112  assign_from(force_field, particles[i].position, force); // long-range force
113  force_short(sim, D, linked_list, particles, particles[i].position, force, fs_interp); // short range force
114 
115  force = force*f2 - particles[i].velocity*f1;
116  particles[i].velocity += force*da;
117  }
118 }
119 
120 }// end of anonymous namespace
121 
128 {
129 public:
130  FP_ppImpl(const Sim_Param &sim): linked_list(sim.box_opt.par_num, sim.app_opt.M, sim.app_opt.Hc)
131  {
132  memory_alloc = sizeof(size_t)*(linked_list.HOC.length+linked_list.par_num);
133 
134  // precompute short range force
135  size_t res = size_t(sim.app_opt.rs/0.05)+1; // force resolution 5% of mesh cell
136  const FTYPE_t r0 = sim.app_opt.rs / (res-1);
137  Data_Vec<FTYPE_t, 2> data(res);
138  FTYPE_t r;
139  const FTYPE_t e2 = pow2(sim.box_opt.Ng*0.1); // softening of 10% of average interparticle length
140 
141  #pragma omp parallel for private(r)
142  for(size_t i = 0; i < res; i++)
143  {
144  r = i*r0;
145  data[0][i] = pow2(r); // store square of r
146  data[1][i] = (force_tot(r, e2) - force_ref(r, sim.app_opt.a))/(4*PI);
147  }
148  fs_interp.init(data);
149  }
150 
151  // VARIABLES
152  LinkedList linked_list;
154  uint64_t memory_alloc;
155 };
156 
157 
159  App_Var<Particle_v<FTYPE_t>>(sim, "FP_pp", "Modified Frozen-potential approximation"), m_impl(new FP_ppImpl(sim))
160 {
161  memory_alloc += m_impl->memory_alloc;
162 }
163 
165 
166 void App_Var_FP_mod::pot_corr(std::vector<Mesh>& vel_field, Mesh& pot_k)
167 {
168  /* Computing displacement in k-space with S2 shaped particles */
169  gen_displ_k_S2(vel_field, pot_k, sim.app_opt.a);
170 
171  /* Computing force in q-space */
172  BOOST_LOG_TRIVIAL(debug) << "Computing force in q-space...";
173  fftw_execute_dft_c2r_triple(p_B, vel_field);
174 }
175 
177 {// Leapfrog method for modified frozen-potential
178  auto kick_step = [&](){ kick_step_w_pp(sim, a_half(), da(), particles, app_field, m_impl->linked_list, m_impl->fs_interp); };
180 }
const std::unique_ptr< FP_ppImpl > m_impl
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
: 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
Vec_3D< double > get_sgn_distance(const Vec_3D< double > &x_from, const Vec_3D< double > &x_to, size_t per)
Definition: core_mesh.cpp:122
: class storing simulation parameters
Definition: params.hpp:193
bool iter()
Definition: core_mesh.cpp:187
: creates a mesh of N*N*(N+2) cells
Definition: class_mesh.hpp:95
: class for effective iteration of cube of mesh cells
Definition: core_mesh.h:66
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
double Hc
Definition: params.hpp:118
double a
Definition: params.hpp:118
modified frozen-potential approximation interface
T pow2(T base)
Definition: precision.hpp:52
functions for integration of particle trajectories
size_t Ng
Definition: params.hpp:61
void kick_step_w_pp(const Sim_Param &sim, const double a, const double da, std::vector< Particle_v< double >> &particles, const std::vector< Mesh > &force_field, LinkedList &linked_list, Interp_obj &fs_interp)
double force_tot(const double r, const double e2)
std::vector< Mesh > app_field
Definition: app_var.hpp:63
declaration in params.hpp
Definition: core_power.h:19
double Omega_L() const
Definition: params.hpp:38
Cosmo_Param cosmo
Definition: params.hpp:206
void pot_corr(std::vector< Mesh > &vel_field, Mesh &pot_k) override
Grid< NDIM, T > sqrt(Grid< NDIM, T > lhs)
Definition: grid.h:231
interface for common functions for all types of approximations
various simulation parameters
std::vector< Particle_v< double > > particles
Definition: app_var.hpp:65
void force_short(const Sim_Param &sim, const double D, const LinkedList &linked_list, const std::vector< Particle_v< double >> &particles, const Vec_3D< double > &position, Vec_3D< double > &force, Interp_obj &fs_interp)
constexpr double PI
Definition: precision.hpp:37
void get_linked_list(const std::vector< Particle_v< double >> &particles)
static double z[8]
static int p
Definition: ccl_emu17.c:25
basic functions to work with mesh
FP_ppImpl(const Sim_Param &sim)
double Omega_m
Definition: params.hpp:36
float pow(float base, unsigned long int exp)
Definition: precision.hpp:39
App_Var_FP_mod(const Sim_Param &sim)
static int m[2]
Definition: ccl_emu17.c:25
void assign(T val)
Definition: class_mesh.hpp:38
double force_ref(const double r, const double a)
void upd_pos() override
size_t mesh_num
Definition: params.hpp:58
App_Opt app_opt
Definition: params.hpp:207
void assign_from(const Mesh &field, const Vec_3D< double > &position, double &value, double mod)
Definition: core_mesh.cpp:224
Vec_3D< size_t > vec
Definition: core_mesh.h:73
void gen_displ_k_S2(std::vector< Mesh > &vel_field, const Mesh &pot_k, const double a)
Definition: core_app.cpp:586
double rs
Definition: params.hpp:116