Fast Methods for Cosmological Simulations
FastSim serves as a tool for quick N-body simulations in modified gravity.
poisson_solver.h
Go to the documentation of this file.
1 #ifndef _POISSONSOLVER_HEADER
2 #define _POISSONSOLVER_HEADER
3 #include "../src/multigrid_solver.h"
4 
5  //=============================================
6  // //
7  // An example of how to use the multigrid //
8  // solver. We implement the Poisson like eq //
9  // //
10  // D^2 phi = m^2 phi + C * drho //
11  // //
12  // T can be any float-type: float, double, //
13  // complex<float>, complex<double>, ... //
14  // //
15  // NB: we need <drho> = 0.0 for consistency //
16  //=============================================
17 
18 template<unsigned int NDIM, typename T>
19 class PoissonSolver : public MultiGridSolver<NDIM,T> {
20  private:
21 
22  T _mass = 0.0; // The mass-term 'm'
23  T _rhofac = 1.0; // The prefactor 'C' to drho
24 
25  public:
26 
27  // Constructors
29  PoissonSolver(unsigned int N, bool verbose = true) : MultiGridSolver<NDIM,T>(N, verbose) {} ;
30  PoissonSolver(unsigned int N, unsigned int Nmin, bool verbose = true) : MultiGridSolver<NDIM,T>(N, Nmin, verbose) {} ;
31  PoissonSolver(MultiGrid<NDIM,T> &source, bool verbose = true) : MultiGridSolver<NDIM,T>(source.get_N(), source.get_Nmin(), verbose) {
33  }
34 
35  // Change the mass-term
36  void set_mass(double mass){
37  _mass = mass;
38  }
39 
40  // Change the rho-factor
41  void set_rhofac(double rhofac){
42  _rhofac = rhofac;
43  }
44 
45  // The discretized equation of motion L_{ijk...}(phi) (= 0 when phi is the correct solution)
46  T l_operator(unsigned int level, std::vector<int>& index_list, bool addsource){
47  unsigned int i = index_list[0];
48 
49  // Gridspacing
50  T h = 1.0/T( MultiGridSolver<NDIM,T>::get_N(level) );
51 
52  // Solution and pde-source grid at current level
53  T *phi = MultiGridSolver<NDIM,T>::get_y(level);
55 
56  // Compute the standard kinetic term [D^2 phi] (in 1D this is phi''_i = phi_{i+1} + phi_{i-1} - 2 phi_{i} )
57  T kinetic = -2.0 * NDIM * phi[ i ];
58  for(unsigned int k = 1; k < 2*NDIM + 1; k++){
59  kinetic += phi[ index_list[k] ];
60  }
61 
62  // The right hand side of the PDE with the source term arising
63  // from restricting the equation down to the lower level
64  T source = _mass * _mass * phi[ i ] + _rhofac * drho[ i ];
65  if( level > 0 && addsource ){
67  }
68 
69  return kinetic/(h*h) - source;
70  }
71 
72  // Differential of the L operator: dL_{ijk...}/dphi_{ijk...}
73  T dl_operator(unsigned int level, std::vector<int>& index_list){
74  T h = 1.0/T( MultiGridSolver<NDIM,T>::get_N(level) );
75 
76  // Derivative of kinetic term
77  T dkinetic = -2.0*NDIM;
78 
79  // Derivative of source
80  T dsource = _mass * _mass;
81 
82  T dl = dkinetic/(h*h) - dsource;
83  return dl;
84  }
85 };
86 
87 #endif
T * get_y(size_t level=0)
T * get_external_field(size_t level, size_t field)
PoissonSolver(unsigned int N, unsigned int Nmin, bool verbose=true)
size_t get_N(size_t level=0) const
void set_mass(double mass)
T l_operator(unsigned int level, std::vector< int > &index_list, bool addsource)
T dl_operator(unsigned int level, std::vector< int > &index_list)
PoissonSolver(unsigned int N, bool verbose=true)
T get_multigrid_source(size_t level, size_t i) const
void add_external_grid(MultiGrid< NDIM, T > *field)
PoissonSolver(MultiGrid< NDIM, T > &source, bool verbose=true)
void set_rhofac(double rhofac)