Fast Methods for Cosmological Simulations
FastSim serves as a tool for quick N-body simulations in modified gravity.
fofr_solver.h
Go to the documentation of this file.
1 #ifndef _FOFRSOLVER_HEADER
2 #define _FOFRSOLVER_HEADER
3 #include "../src/multigrid_solver.h"
4 
5  //=============================================
6  // //
7  // An example of how to use the multigrid //
8  // solver. We implement the Hu-Sawicky //
9  // f(R) gravity equation: //
10  // //
11  // D[b(u) D f(u)] = g(u,rho) //
12  // //
13  // where b(u) = e^u //
14  //=============================================
15 
16 template<unsigned int NDIM, typename T>
17 class FofrSolver : public MultiGridSolver<NDIM,T> {
18  private:
19 
20  // Parameters
21  double _boxsize = 100.0; // Boxsize in units of Mpc/h
22  double _omegam = 0.3; // Density parameter Omega_matter
23  double _aexp = 1.0; // Scale factor
24  double _nfofr = 1.0; // Hu-Sawicky f(R) model n-index
25  double _fofr0 = 1.0e-5; // Hu-Sawicky f(R) model f(R0) value
26 
27  // Derived parameters
28  double _fac1 = 10.33333333;
29  double _fac2 = 0.032676900;
30  double _prefac = 0.000333778;
31 
32  public:
33 
34  // Constructors
36  FofrSolver(unsigned int N, bool verbose = true) : MultiGridSolver<NDIM,T>(N, verbose) {} ;
37  FofrSolver(unsigned int N, int Nmin, bool verbose = true) : MultiGridSolver<NDIM,T>(N, Nmin, verbose) {} ;
38  FofrSolver(MultiGrid<NDIM,T> &source, bool verbose = true) : MultiGridSolver<NDIM,T>(source.get_N(), source.get_Nmin(), verbose) {
40  }
41 
42  void set_parameters(double boxsize, double omegam, double aexp, double nfofr, double fofr0){
43  std::cout << "==> FofrSolver::set_parameters | Boxsize: " << boxsize << " Omegam: " << omegam;
44  std::cout << " aexp: " << aexp << " nfofr: " << nfofr << " fofr0: " << fofr0 << std::endl;
45 
46  // Set parameters
47  _boxsize = boxsize;
48  _omegam = omegam;
49  _aexp = aexp;
50  _nfofr = nfofr;
51  _fofr0 = fofr0;
52 
53  // Derived parameters
54  _fac1 = 1.0 + 4.0 * _aexp * _aexp * _aexp * (1.0 - _omegam) / _omegam;
55  _fac2 = (1.0 + 4.0 * (1.0 - _omegam) / _omegam ) * _aexp * _aexp * _aexp * std::pow( _fofr0 * _aexp, 1.0 / (_nfofr+1.0) );
56  _prefac = pow( _boxsize / 2998.0 , 2) * _omegam * _aexp;
57  }
58 
59  inline double bfunc(double x){ return std::exp(x); }
60 
61  // The dicretized equation L(phi)
62  T l_operator(unsigned int level, std::vector<unsigned int>& index_list, bool addsource){
63  unsigned int i = index_list[0];
64 
65  // Gridspacing
66  T h = 1.0/T( MultiGridSolver<NDIM,T>::get_N(level) );
67 
68  // Solution and pde-source grid at current level
69  T *phi = MultiGridSolver<NDIM,T>::get_y(level);
71 
72  // The kinetic term is D[ b[f] Df ] with b = exp(x)
73  T kinetic = 0.0;
74  T f = phi[i];
75  T boff = bfunc(f);
76  for(unsigned int j = 0; j < NDIM; j++){
77  unsigned int iminus = index_list[2*j+1];
78  unsigned int iplus = index_list[2*j+2];
79  T fminus = phi[iminus];
80  T fplus = phi[iplus];
81  T bminus = 0.5 * ( bfunc(fminus) + boff );
82  T bplus = 0.5 * ( bfunc(fplus) + boff );
83  kinetic += bplus * (fplus - f) - bminus * (f - fminus);
84  }
85 
86  // The right hand side of the PDE
87  T source = _prefac * ( drho[ i ] + _fac1 - _fac2 * std::exp(-phi[ i ]/(_nfofr+1.0)) );
88  if( level > 0 && addsource ){
90  }
91 
92  // The discretized equation of motion L_{ijk...}(phi) = 0
93  return kinetic/(h*h) - source;
94  }
95 
96  // Differential of the L operator: dL_{ijk...}/dphi_{ijk...}
97  T dl_operator(unsigned int level, std::vector<unsigned int>& index_list){
98  unsigned int i = index_list[0];
99 
100  // Gridspacing
101  T h = 1.0/T( MultiGridSolver<NDIM,T>::get_N(level) );
102 
103  // Solution and pde-source grid at current level
104  T *phi = MultiGridSolver<NDIM,T>::get_y(level);
105 
106  // The derivative of the kinetic term D[ b[f] Df ]
107  T dkinetic = 0.0;
108  T f = phi[i];
109  T boff = bfunc(f);
110  T dboff = boff;
111  for(unsigned int j = 0; j < NDIM; j++){
112  unsigned int iminus = index_list[2*j+1];
113  unsigned int iplus = index_list[2*j+2];
114  T fminus = phi[iminus];
115  T fplus = phi[iplus];
116  T bminus = 0.5 * ( bfunc(fminus) + boff );
117  T bplus = 0.5 * ( bfunc(fplus) + boff );
118 
119  // Add up kinetic term
120  dkinetic += 0.5 * dboff * (fplus + fminus - 2.0 * f) - (bplus + bminus);
121  }
122 
123  // The derivative of the right hand side
124  T dsource = _prefac * ( _fac2 * std::exp(-phi[ i ] / (_nfofr+1.0) ) ) / (1.0+_nfofr);
125 
126  return dkinetic/(h*h) - dsource;
127  }
128 };
129 
130 #endif
T dl_operator(unsigned int level, std::vector< unsigned int > &index_list)
Definition: fofr_solver.h:97
double _fac2
Definition: fofr_solver.h:29
T * get_y(size_t level=0)
T * get_external_field(size_t level, size_t field)
FofrSolver(MultiGrid< NDIM, T > &source, bool verbose=true)
Definition: fofr_solver.h:38
size_t get_N(size_t level=0) const
double _omegam
Definition: fofr_solver.h:22
double _aexp
Definition: fofr_solver.h:23
double _boxsize
Definition: fofr_solver.h:21
FofrSolver(unsigned int N, bool verbose=true)
Definition: fofr_solver.h:36
std::ostream & cout()
T l_operator(unsigned int level, std::vector< unsigned int > &index_list, bool addsource)
Definition: fofr_solver.h:62
double _nfofr
Definition: fofr_solver.h:24
static CCL_BEGIN_DECLS double x[111][8]
double _fofr0
Definition: fofr_solver.h:25
double bfunc(double x)
Definition: fofr_solver.h:59
void set_parameters(double boxsize, double omegam, double aexp, double nfofr, double fofr0)
Definition: fofr_solver.h:42
T get_multigrid_source(size_t level, size_t i) const
double _prefac
Definition: fofr_solver.h:30
float pow(float base, unsigned long int exp)
Definition: precision.hpp:39
double _fac1
Definition: fofr_solver.h:28
FofrSolver(unsigned int N, int Nmin, bool verbose=true)
Definition: fofr_solver.h:37