Fast Methods for Cosmological Simulations
FastSim serves as a tool for quick N-body simulations in modified gravity.
anonymous_namespace{chameleon.cpp}::ChiSolver< T > Class Template Reference

: class to solve chameleon equations of motion More...

Inheritance diagram for anonymous_namespace{chameleon.cpp}::ChiSolver< T >:
Collaboration diagram for anonymous_namespace{chameleon.cpp}::ChiSolver< T >:

Public Member Functions

 ChiSolver (size_t N, unsigned int Nmin, const Sim_Param &sim, bool verbose=true)
 
 ChiSolver (size_t N, const Sim_Param &sim, bool verbose=true)
 
chi_a (T a) const
 
chi_force_units (T a) const
 
void get_chi_k (Mesh &rho_k)
 
bool check_surr_dens (T const *const rho_grid, std::vector< size_t > index_list, size_t i, size_t N)
 
void set_time (T a, const Cosmo_Param &cosmo)
 
get_chi_prefactor () const
 
get_phi_prefactor () const
 
l_operator (const T chi_i, const size_t level, const std::vector< size_t > &index_list, const bool addsource, const T h) const
 
l_operator (const size_t level, const std::vector< size_t > &index_list, const bool addsource, const T h) const override
 
dl_operator (const size_t level, const std::vector< size_t > &index_list, const T h) const override
 
bool find_opposite_l_sign (const T f1, const T l1, T df, T &f2, T &l2, const size_t level, const std::vector< size_t > &index_list, const T h) const
 
bool check_bisection_convergence (const T df_new, const T l_new) const
 
bisection_step (T &f1, T &l1, T &f2, T &l2, const size_t level, const std::vector< size_t > &index_list, const T h) const
 
bisection (T f1, T l1, const T df, const size_t level, const std::vector< size_t > &index_list, const T h) const
 
upd_operator (const T f, const size_t level, const std::vector< size_t > &index_list, const T h) const override
 
void correct_sol (Grid< 3, T > &f, const Grid< 3, T > &corr, const size_t level) override
 
ES check_convergence () override
 check if solution already converged More...
 
void check_solution (size_t level, Grid< 3, T > &chi) override
 
void set_convergence (double eps, double err_stop, double err_stop_min, double rms_stop_min, size_t num_fail)
 
void set_bisection_convergence (size_t max_bi_step, T dchi_stop, T l_stop)
 
void set_def_convergence ()
 
void set_bulk_field ()
 
void set_linear_sol_at_level (Mesh &rho, const FFTW_PLAN_TYPE &p_F, const FFTW_PLAN_TYPE &p_B, size_t level)
 
void set_linear_recursively (size_t level)
 
void set_linear (Mesh &rho, const FFTW_PLAN_TYPE &p_F, const FFTW_PLAN_TYPE &p_B)
 
void set_screened (size_t level=0)
 
chi_min (T delta) const
 
- Public Member Functions inherited from MultiGridSolver< 3, T >
 MultiGridSolver ()
 
 MultiGridSolver (size_t N)
 
 MultiGridSolver (size_t N, bool verbose)
 
 MultiGridSolver (size_t N, size_t Nmin, bool verbose)
 
size_t get_istep () const
 
T * get_y (size_t level=0)
 
T const * get_y (size_t level=0) const
 
Grid< NDIM, T > & get_grid (size_t level=0)
 
const Grid< NDIM, T > & get_grid (size_t level=0) const
 
MultiGrid< NDIM, T > & get_mlt_grid (size_t level=0)
 
const MultiGrid< NDIM, T > & get_mlt_grid (size_t level=0) const
 
T * get_external_field (size_t level, size_t field)
 
T const * get_external_field (size_t level, size_t field) const
 
Grid< NDIM, T > & get_external_grid (size_t level, size_t field)
 
const Grid< NDIM, T > & get_external_grid (size_t level, size_t field) const
 
size_t get_external_field_size () const
 
get_multigrid_source (size_t level, size_t i) const
 
void set_epsilon (double eps_converge)
 
void set_maxsteps (size_t maxsteps)
 
void set_ngs_sweeps (size_t ngs_fine, size_t ngs_coarse)
 
void set_convergence_criterion_residual (bool use_residual)
 
void set_Nlevel (size_t N)
 
size_t get_N (size_t level=0) const
 
size_t get_Ntot (size_t level=0) const
 
size_t get_Nlevel () const
 
void add_external_grid (MultiGrid< NDIM, T > *field)
 
void set_initial_guess (T guess)
 
void set_initial_guess (T *guess)
 
void set_initial_guess (Grid< NDIM, T > &guess)
 
Exit_Status solve ()
 
void clear ()
 
virtual void correct_sol (Grid< NDIM, T > &f, const Grid< NDIM, T > &corr, const size_t level)
 
virtual void check_solution (size_t level, Grid< NDIM, T > &sol)
 
void check_solution (size_t level)
 

Public Attributes

const T n
 Hu-Sawicki paramater. More...
 
const T beta
 Chameleon coupling constant. More...
 
const T chi_0
 2*beta*Mpl*phi_scr More...
 
const T phi_prefactor
 prefactor for Poisson equation for gravitational potential More...
 
const T chi_prefactor_0
 dimensionless prefactor to poisson equation at a = 1 More...
 
chi_prefactor
 time-dependent prefactor More...
 
size_t m_conv_stop = 0
 
double m_rms_stop_min
 
double m_err_stop
 
double m_err_stop_min
 
size_t m_num_fail
 
size_t m_max_bisection_steps
 
m_dchi_stop
 
m_l_stop
 
std::vector< std::map< size_t, T > > fix_vals
 <index, value> More...
 
- Public Attributes inherited from MultiGridSolver< 3, T >
bool _store_all_residual
 
std::vector< double_res_domain_array
 

Additional Inherited Members

- Public Types inherited from MultiGridSolver< 3, T >
enum  Exit_Status
 
- Protected Member Functions inherited from MultiGridSolver< 3, T >
void get_neighbor_gridindex (std::vector< size_t > &index_list, size_t i, size_t ngrid)
 
- Protected Attributes inherited from MultiGridSolver< 3, T >
bool _verbose
 
bool _conv_criterion_residual
 
double _eps_converge
 
size_t _maxsteps
 
size_t _istep_vcycle
 
double _rms_res
 
double _rms_res_i
 
double _rms_res_old
 

Detailed Description

template<typename T>
class anonymous_namespace{chameleon.cpp}::ChiSolver< T >

: class to solve chameleon equations of motion

Definition at line 156 of file chameleon.cpp.

Constructor & Destructor Documentation

template<typename T >
anonymous_namespace{chameleon.cpp}::ChiSolver< T >::ChiSolver ( size_t  N,
unsigned int  Nmin,
const Sim_Param sim,
bool  verbose = true 
)
inline

Definition at line 183 of file chameleon.cpp.

183  :
184  MultiGridSolver<3, T>(N, Nmin, verbose), n(sim.chi_opt.n), beta(sim.chi_opt.beta), chi_0(2*beta*MPL*sim.chi_opt.phi),
185  phi_prefactor( // prefactor for Poisson equation for gravitational potential, [] = (h/Mpc)^2
186  // 4*pi*G*rho_m,0 + computing units [Mpc/h]
187  3/2.*sim.cosmo.Omega_m*pow(sim.cosmo.H0 * sim.cosmo.h / c_kms ,2)
188  ),
189  chi_prefactor_0( // dimensionless prefactor to poisson equation
190  // beta*rho_m,0 / (Mpl*chi_0) + computing units [Mpc/h]; additional a^(-3 -3/(1-n)) at each timestep
192  ),
193  fix_vals(this->get_Nlevel())
194  {
195  if ((n <= 0) || (n >= 1) || (chi_0 <= 0)) throw std::out_of_range("invalid values of chameleon power-law potential parameters");
196  }
Chi_Opt chi_opt
Definition: params.hpp:210
double box_size
Definition: params.hpp:59
Box_Opt box_opt
Definition: params.hpp:202
double h
Definition: params.hpp:36
constexpr double MPL
mass & chi in units of Planck mass
Definition: chameleon.cpp:38
size_t get_Nlevel() const
const T chi_prefactor_0
dimensionless prefactor to poisson equation at a = 1
Definition: chameleon.cpp:164
double n
Definition: params.hpp:185
const T beta
Chameleon coupling constant.
Definition: chameleon.cpp:161
Cosmo_Param cosmo
Definition: params.hpp:206
double H0
Definition: params.hpp:36
std::vector< std::map< size_t, T > > fix_vals
<index, value>
Definition: chameleon.cpp:180
constexpr double c_kms
speed of light [km / s]
Definition: chameleon.cpp:45
const T phi_prefactor
prefactor for Poisson equation for gravitational potential
Definition: chameleon.cpp:163
double Omega_m
Definition: params.hpp:36
float pow(float base, unsigned long int exp)
Definition: precision.hpp:39
double phi
Definition: params.hpp:185
double beta
Definition: params.hpp:185
template<typename T >
anonymous_namespace{chameleon.cpp}::ChiSolver< T >::ChiSolver ( size_t  N,
const Sim_Param sim,
bool  verbose = true 
)
inline

Definition at line 198 of file chameleon.cpp.

198 : ChiSolver(N, 2, sim, verbose) {}
ChiSolver(size_t N, unsigned int Nmin, const Sim_Param &sim, bool verbose=true)
Definition: chameleon.cpp:183

Member Function Documentation

template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::bisection ( f1,
l1,
const T  df,
const size_t  level,
const std::vector< size_t > &  index_list,
const T  h 
) const
inline

Definition at line 356 of file chameleon.cpp.

References growth_allz::T.

357  {/* initialize bisection solver -- find two values with opposite value of l_operator -- and start iterating */
358  T f_new, f2, l2;
359 
360  // get initial guess -- return when failed
361  if (!find_opposite_l_sign(f1, l1, df, f2, l2, level, index_list, h)) return f2;
362 
363  // iterate
364  for (size_t i = 0; i < m_max_bisection_steps; ++i){
365  f_new = bisection_step(f1, l1, f2, l2, level, index_list, h);
366  if (f_new != CHI_MIN)
367  {
368  return f_new;
369  }
370  }
371 
372  // failed iteration
373  return f1;
374  }
constexpr CHI_PREC_t CHI_MIN
minimum value of chameleon field, in chi_a units it is &#39;0&#39;, in phi units it is &#39;-1&#39; ...
Definition: chameleon.cpp:66
bool find_opposite_l_sign(const T f1, const T l1, T df, T &f2, T &l2, const size_t level, const std::vector< size_t > &index_list, const T h) const
Definition: chameleon.cpp:307
T bisection_step(T &f1, T &l1, T &f2, T &l2, const size_t level, const std::vector< size_t > &index_list, const T h) const
Definition: chameleon.cpp:333
template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::bisection_step ( T &  f1,
T &  l1,
T &  f2,
T &  l2,
const size_t  level,
const std::vector< size_t > &  index_list,
const T  h 
) const
inline

Definition at line 333 of file chameleon.cpp.

References anonymous_namespace{chameleon.cpp}::CHI_MIN, and growth_allz::T.

334  {/* given 'f1' and 'f2' with different signs of l_operator(f_i) perform one step of bisection:
335  f_new = (f1 + f2) / 2
336  change whichever l_operator(f_i) has the same sign as l_operator(f_new)
337  return value indicates convergence -- 0 (unphysical for chameleon) not, otherwise yes*/
338 
339  const T f_new = (f1 + f2) / 2;
340  const T l_new = l_operator(f_new, level, index_list, true, h);
341 
342  if (check_bisection_convergence(f2 - f_new, l_new)) return f_new;
343 
344  if (l1*l_new > 0) {
345  f1 = f_new;
346  l1 = l_new;
347 
348  } else {
349  f2 = f_new;
350  l2 = l_new;
351  }
352 
353  return CHI_MIN;
354  }
constexpr CHI_PREC_t CHI_MIN
minimum value of chameleon field, in chi_a units it is &#39;0&#39;, in phi units it is &#39;-1&#39; ...
Definition: chameleon.cpp:66
T l_operator(const T chi_i, const size_t level, const std::vector< size_t > &index_list, const bool addsource, const T h) const
Definition: chameleon.cpp:258
bool check_bisection_convergence(const T df_new, const T l_new) const
Definition: chameleon.cpp:328
template<typename T >
bool anonymous_namespace{chameleon.cpp}::ChiSolver< T >::check_bisection_convergence ( const T  df_new,
const T  l_new 
) const
inline

Definition at line 328 of file chameleon.cpp.

329  {
330  return ((std::abs(l_new) < m_l_stop) || (std::abs(df_new) < m_dchi_stop));
331  }
template<typename T >
ES anonymous_namespace{chameleon.cpp}::ChiSolver< T >::check_convergence ( )
inlineoverridevirtual

check if solution already converged

Returns
ES exit status (SUCCESS, FAILURE, SLOW, ITERATE, MAX_STEPS)
  • bring variables from this-> namespace here
  • Compute ratio of residual to previous residual
  • convergence criteria
  • print some information
  • Print out some information
  • check individual conditions

Reimplemented from MultiGridSolver< 3, T >.

Definition at line 422 of file chameleon.cpp.

423  {
425  const double _rms_res_i = this->_rms_res_i;
426  const double _rms_res = this->_rms_res;
427  const double _rms_res_old = this->_rms_res_old;
428  const double _verbose = this->_verbose;
429  const double _istep_vcycle = this->_istep_vcycle;
430  const double _eps_converge = this->_eps_converge;
431  const double _maxsteps = this->_maxsteps;
432 
434  const double err = _rms_res_old != 0.0 ? _rms_res/_rms_res_old : 0.0;
435  ES converged = ES::ITERATE;
436 
438  bool res_below_optimal_tresh = (_rms_res < _eps_converge) || (_eps_converge == 0.0);
439  bool res_below_minimal_tresh = (_rms_res < m_rms_stop_min) || (m_rms_stop_min == 0.0);
440  bool fast_convergence = err < m_err_stop_min;
441  bool slow_convergence = err > m_err_stop;
442  bool worse_solution = err > 1;
443  bool over_max_steps = _istep_vcycle >= _maxsteps;
444 
446  auto print_success = [=](size_t m_conv_stop){
447  BOOST_LOG_TRIVIAL(debug) << "\n\tSUCCESS: res = " << _rms_res << ", err = " << err << ", num_err = " << m_conv_stop << " (istep = " << _istep_vcycle << ")";
448  };
449  auto print_failure = [=](size_t m_conv_stop){
450  BOOST_LOG_TRIVIAL(debug) << "\tFAILURE: res = " << _rms_res << ", err = " << err << ", num_err = " << m_conv_stop << " (istep = " << _istep_vcycle << ")";
451  };
452 
453  auto print_iterate = [=](size_t m_conv_stop){
454  BOOST_LOG_TRIVIAL(debug) << "\tITERATE: res = " << _rms_res << ", err = " << err << ", num_err = " << m_conv_stop << " (istep = " << _istep_vcycle << ")";
455  };
456 
458  if (_verbose){
459  BOOST_LOG_TRIVIAL(debug) << " Checking for convergence at step = " << _istep_vcycle;
460  BOOST_LOG_TRIVIAL(debug) << " Residual = " << _rms_res << " Residual_old = " << _rms_res_old;
461  BOOST_LOG_TRIVIAL(debug) << " Residual_i = " << _rms_res_i << " Err = " << err;
462  }
463 
465  if (res_below_optimal_tresh && !fast_convergence){
466  print_success(m_conv_stop);
467  converged = ES::SUCCESS;
468  }
469  else if (worse_solution)
470  {
471  if(_verbose) print_failure(m_conv_stop);
472  m_conv_stop++;
473  converged = ES::ITERATE;
474  }
475  else if (slow_convergence)
476  {
477  if (res_below_minimal_tresh)
478  {
479  print_success(m_conv_stop);
480  converged = ES::SLOW;
481  }
482  else
483  {
484  m_conv_stop++;
485  if (m_conv_stop >= m_num_fail)
486  {
487  print_failure(m_conv_stop);
488  converged = ES::FAILURE;
489  }
490  else
491  {
492  if(_verbose) print_iterate(m_conv_stop);
493  converged = ES::ITERATE;
494  }
495  }
496  }
497  else
498  {
499  if (m_conv_stop >= m_num_fail)
500  {
501  print_failure(m_conv_stop);
502  converged = ES::FAILURE;
503  }
504  else
505  {
506  if(_verbose) print_iterate(m_conv_stop);
507  converged = ES::ITERATE;
508  }
509  }
510 
511  if(over_max_steps)
512  {
513  print_failure(m_conv_stop);
514  converged = ES::MAX_STEPS;
515  }
516 
517  if (converged != ES::ITERATE)
518  {
519  m_conv_stop = 0;
520  }
521  return converged;
522  }
MultiGridSolver< 3, CHI_PREC_t >::Exit_Status ES
acces Exit_Status namespace
Definition: chameleon.cpp:86
template<typename T >
void anonymous_namespace{chameleon.cpp}::ChiSolver< T >::check_solution ( size_t  level,
Grid< 3, T > &  chi 
)
inlineoverride

Definition at line 524 of file chameleon.cpp.

525  {
526  for (auto fv : fix_vals[level]) chi[fv.first] = fv.second;
527  }
std::vector< std::map< size_t, T > > fix_vals
<index, value>
Definition: chameleon.cpp:180
template<typename T >
bool anonymous_namespace{chameleon.cpp}::ChiSolver< T >::check_surr_dens ( T const *const  rho_grid,
std::vector< size_t >  index_list,
size_t  i,
size_t  N 
)
inline

Definition at line 237 of file chameleon.cpp.

References anonymous_namespace{test_chameleon.cpp}::get_neighbor_gridindex().

238  {/* internal method for finding highest density in nearby points */
239  // never fix bulk field in under-dense region
240  if (rho_grid[i] <= 0) return false;
241 
242  // check surrounding points if theres is higher density
243  this->get_neighbor_gridindex(index_list, i, N);
244  for(size_t i_s : index_list) if (rho_grid[i_s] > rho_grid[i]) return false;
245 
246  // if current point has the highest density, fix chameleon value
247  return true;
248  }
void get_neighbor_gridindex(std::vector< size_t > &index_list, size_t i, size_t ngrid)
template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::chi_a ( a) const
inline

Definition at line 200 of file chameleon.cpp.

References pow().

201  {
202  return chi_0*pow(a, 3/(1-n));
203  }
float pow(float base, unsigned long int exp)
Definition: precision.hpp:39
template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::chi_force_units ( a) const
inline

Definition at line 205 of file chameleon.cpp.

206  {
207  return beta/MPL*chi_a(a)/phi_prefactor;
208  }
constexpr double MPL
mass & chi in units of Planck mass
Definition: chameleon.cpp:38
const T beta
Chameleon coupling constant.
Definition: chameleon.cpp:161
const T phi_prefactor
prefactor for Poisson equation for gravitational potential
Definition: chameleon.cpp:163
template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::chi_min ( delta) const
inline

Definition at line 664 of file chameleon.cpp.

References anonymous_namespace{chameleon.cpp}::CHI_MIN, and pow().

665  {/* get chi_bulk for given overdensity */
666  if (delta > -1) return std::pow(1+delta, 1/(n-1)) + CHI_MIN;
667  else if (delta == -1) return 1 + CHI_MIN;
668  else throw std::range_error("invalid values of density: " + std::to_string(delta) + " < -1)");
669  }
constexpr CHI_PREC_t CHI_MIN
minimum value of chameleon field, in chi_a units it is &#39;0&#39;, in phi units it is &#39;-1&#39; ...
Definition: chameleon.cpp:66
float pow(float base, unsigned long int exp)
Definition: precision.hpp:39
template<typename T >
void anonymous_namespace{chameleon.cpp}::ChiSolver< T >::correct_sol ( Grid< 3, T > &  f,
const Grid< 3, T > &  corr,
const size_t  level 
)
inlineoverride

Definition at line 391 of file chameleon.cpp.

References anonymous_namespace{test_chameleon.cpp}::get_neighbor_gridindex(), Grid< NDIM, T >::get_Ntot(), ccl_test_distances::h, cl_cmbl_bm::l, and growth_allz::T.

392  {/* Method for correcting solution when going up,
393  check for unphysical values */
394 
395  const size_t Ntot = f.get_Ntot();
396  const T * const rho = this->get_external_field(level, 0);
397 
398  // bisection variables
399  const size_t N = this->get_N(level);
400  const T h = 1.0/T( N );
401  std::vector<size_t> index_list;
402 
403  #pragma omp parallel for private(index_list)
404  for(size_t i = 0; i < Ntot; i++)
405  {
406  // do not change values in screened regions
407  if (rho[i] == MARK_CHI_BOUND_COND) continue;
408  else if (std::abs(corr[i]/(f[i] - CHI_MIN)) < SWITCH_BIS_NEW) f[i] += corr[i];
409  else{
410  this->get_neighbor_gridindex(index_list, i, N);
411  T l = l_operator(level, index_list, true, h);
412  f[i] = bisection(f[i], l, corr[i] / 2, level, index_list, h);
413  }
414  }
415  }
constexpr CHI_PREC_t CHI_MIN
minimum value of chameleon field, in chi_a units it is &#39;0&#39;, in phi units it is &#39;-1&#39; ...
Definition: chameleon.cpp:66
T l_operator(const T chi_i, const size_t level, const std::vector< size_t > &index_list, const bool addsource, const T h) const
Definition: chameleon.cpp:258
T * get_external_field(size_t level, size_t field)
T bisection(T f1, T l1, const T df, const size_t level, const std::vector< size_t > &index_list, const T h) const
Definition: chameleon.cpp:356
size_t get_N(size_t level=0) const
size_t get_Ntot() const
Definition: grid.cpp:141
constexpr CHI_PREC_t MARK_CHI_BOUND_COND
unphysical value of overdensity (< -1) used to indicate that chameleon filed at this point should not...
Definition: chameleon.cpp:52
constexpr CHI_PREC_t SWITCH_BIS_NEW
when the relative change in solution is less than this, use Newton`s method. Bisection method otherwi...
Definition: chameleon.cpp:59
void get_neighbor_gridindex(std::vector< size_t > &index_list, size_t i, size_t ngrid)
template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::dl_operator ( const size_t  level,
const std::vector< size_t > &  index_list,
const T  h 
) const
inlineoverridevirtual

Reimplemented from MultiGridSolver< 3, T >.

Definition at line 293 of file chameleon.cpp.

References ccl_test_distances::h, pow(), and growth_allz::T.

294  {
295  // solution
296  const T chi = this->get_y(level)[ index_list[0] ];
297 
298  // Derivative of source
299  const T dsource = chi_prefactor*(1-n)*pow(chi - CHI_MIN, n-2);
300 
301  // Derivative of kinetic term
302  const T dkinetic = -2.0*3;
303 
304  return dkinetic/(h*h) - dsource;
305  }
constexpr CHI_PREC_t CHI_MIN
minimum value of chameleon field, in chi_a units it is &#39;0&#39;, in phi units it is &#39;-1&#39; ...
Definition: chameleon.cpp:66
T * get_y(size_t level=0)
float pow(float base, unsigned long int exp)
Definition: precision.hpp:39
T chi_prefactor
time-dependent prefactor
Definition: chameleon.cpp:165
template<typename T >
bool anonymous_namespace{chameleon.cpp}::ChiSolver< T >::find_opposite_l_sign ( const T  f1,
const T  l1,
df,
T &  f2,
T &  l2,
const size_t  level,
const std::vector< size_t > &  index_list,
const T  h 
) const
inline

Definition at line 307 of file chameleon.cpp.

References anonymous_namespace{chameleon.cpp}::CONVERGENCE_BI_STEPS_INIT, and growth_allz::T.

308  {/* find such 'f2' that 'l_operator(f2)' has opposite sign than l1
309  use df as a guess in which direction to be looking */
310  f2 = f1;
311  for (size_t j = 0; j < CONVERGENCE_BI_STEPS_INIT; ++j)
312  {
313  f2 += df;
314  if (f2 <= CHI_MIN)
315  {
316  const size_t i = index_list[0];
317  const T rho = this->get_external_field(level, 0)[i];
318 
319  f2 = chi_min(rho);
320  j = CONVERGENCE_BI_STEPS_INIT;//< end of loop but first check for an improvement
321  }
322  l2 = l_operator(f2, level, index_list, true, h);
323  if (l1*l2 <= 0) return true;
324  }
325  return false;
326  }
constexpr CHI_PREC_t CHI_MIN
minimum value of chameleon field, in chi_a units it is &#39;0&#39;, in phi units it is &#39;-1&#39; ...
Definition: chameleon.cpp:66
constexpr size_t CONVERGENCE_BI_STEPS_INIT
maximal number of steps inside bisection initialization method
Definition: chameleon.cpp:78
T l_operator(const T chi_i, const size_t level, const std::vector< size_t > &index_list, const bool addsource, const T h) const
Definition: chameleon.cpp:258
T * get_external_field(size_t level, size_t field)
template<typename T >
void anonymous_namespace{chameleon.cpp}::ChiSolver< T >::get_chi_k ( Mesh rho_k)
inline

Definition at line 210 of file chameleon.cpp.

References get_k_sq(), Mesh_base< T >::length, Mesh::N, PI, pow(), and growth_allz::T.

211  {/* transform input density in k-space into linear prediction for chameleon field,
212  includes w(k) corrections for interpolation of particles */
213  const size_t N = rho_k.N;
214  const size_t l_half = rho_k.length/2;
215  const T mass_sq = (1-n)*chi_prefactor/pow(2*PI, 2); // dimensionless square mass, with derivative factor k* = 2*PI / L
216  const T chi_a_n = -1/(1-n); // prefactor for chi(k), in chi_a units
217 
218  T k2, g_k;
219 
220  #pragma omp parallel for private(k2, g_k)
221  for(size_t i=0; i < l_half;i++){
222  k2 = get_k_sq(N, i);
223  if (k2 == 0)
224  {
225  rho_k[2*i] = 0;
226  rho_k[2*i+1] = 0;
227  }
228  else
229  {
230  g_k = chi_a_n/(k2+mass_sq)*mass_sq; // Green function
231  rho_k[2*i] *= g_k;
232  rho_k[2*i+1] *= g_k;
233  }
234  }
235  }
double get_k_sq(size_t N, size_t index)
Definition: core_mesh.cpp:38
size_t N
Definition: class_mesh.hpp:102
constexpr double PI
Definition: precision.hpp:37
size_t length
Definition: class_mesh.hpp:32
float pow(float base, unsigned long int exp)
Definition: precision.hpp:39
T chi_prefactor
time-dependent prefactor
Definition: chameleon.cpp:165
template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::get_chi_prefactor ( ) const
inline

Definition at line 255 of file chameleon.cpp.

255 { return chi_prefactor; }
T chi_prefactor
time-dependent prefactor
Definition: chameleon.cpp:165
template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::get_phi_prefactor ( ) const
inline

Definition at line 256 of file chameleon.cpp.

256 { return phi_prefactor; }
const T phi_prefactor
prefactor for Poisson equation for gravitational potential
Definition: chameleon.cpp:163
template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::l_operator ( const T  chi_i,
const size_t  level,
const std::vector< size_t > &  index_list,
const bool  addsource,
const T  h 
) const
inline

Definition at line 258 of file chameleon.cpp.

References ccl_test_distances::h, pow(), and growth_allz::T.

259  {/* The dicretized equation L(phi) */
260  // Solution and pde-source grid at current level
261  const size_t i = index_list[0];
262  T const* const chi = this->get_y(level); // solution
263  const T rho = this->get_external_field(level, 0)[i];
264 
265  // do not change values in screened regions
266  if (rho == MARK_CHI_BOUND_COND) return 0;
267 
268  // The right hand side of the PDE
269  T source = (1 + rho - pow(chi_i - CHI_MIN, n - 1)) * chi_prefactor;
270 
271  // Compute the standard kinetic term [D^2 phi] (in 1D this is phi''_i = phi_{i+1} + phi_{i-1} - 2 phi_{i} )
272  T kinetic = -2*chi_i*3; // chi, '-2*3' is factor in 3D discrete laplacian
273  // go through all surrounding points
274  for(auto it = index_list.begin() + 1; it < index_list.end(); ++it) kinetic += chi[*it];
275 
276  // source term arising rom restricting the equation down to the lower level
277  if( level > 0 && addsource ) source += this->get_multigrid_source(level, i);
278 
279  // The discretized equation of motion L_{ijk...}(phi) = 0
280  return kinetic/(h*h) - source;
281  }
constexpr CHI_PREC_t CHI_MIN
minimum value of chameleon field, in chi_a units it is &#39;0&#39;, in phi units it is &#39;-1&#39; ...
Definition: chameleon.cpp:66
T * get_y(size_t level=0)
T * get_external_field(size_t level, size_t field)
constexpr CHI_PREC_t MARK_CHI_BOUND_COND
unphysical value of overdensity (< -1) used to indicate that chameleon filed at this point should not...
Definition: chameleon.cpp:52
T get_multigrid_source(size_t level, size_t i) const
float pow(float base, unsigned long int exp)
Definition: precision.hpp:39
T chi_prefactor
time-dependent prefactor
Definition: chameleon.cpp:165
template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::l_operator ( const size_t  level,
const std::vector< size_t > &  index_list,
const bool  addsource,
const T  h 
) const
inlineoverridevirtual

Reimplemented from MultiGridSolver< 3, T >.

Definition at line 283 of file chameleon.cpp.

References growth_allz::T.

284  {/* The dicretized equation L(phi) */
285  // Solution and pde-source grid at current level
286  const size_t i = index_list[0];
287  T const* const chi = this->get_y(level); // solution
288  const T chi_i = chi[i];
289  return l_operator(chi_i, level, index_list, addsource, h);
290  }
T l_operator(const T chi_i, const size_t level, const std::vector< size_t > &index_list, const bool addsource, const T h) const
Definition: chameleon.cpp:258
T * get_y(size_t level=0)
template<typename T >
void anonymous_namespace{chameleon.cpp}::ChiSolver< T >::set_bisection_convergence ( size_t  max_bi_step,
dchi_stop,
l_stop 
)
inline

Definition at line 538 of file chameleon.cpp.

template<typename T >
void anonymous_namespace{chameleon.cpp}::ChiSolver< T >::set_bulk_field ( )
inline

Definition at line 553 of file chameleon.cpp.

References growth_allz::T.

554  {
555  if (!chi_prefactor) throw std::out_of_range("invalid value of scale factor");
556  if (!this->get_external_field_size()) throw std::out_of_range("overdensity not set");
557  BOOST_LOG_TRIVIAL(debug) << "Setting initial guess for chameleon field...";
558 
559  T* const f = this->get_y(); // initial guess
560  T const* const rho = this->get_external_field(0, 0); // overdensity
561  const size_t N_tot = this->get_Ntot();
562 
563  #pragma omp parallel for
564  for (size_t i = 0; i < N_tot; ++i)
565  {
566  f[i] = chi_min(rho[i]);
567  }
568  }
T * get_y(size_t level=0)
T * get_external_field(size_t level, size_t field)
size_t get_Ntot(size_t level=0) const
size_t get_external_field_size() const
T chi_prefactor
time-dependent prefactor
Definition: chameleon.cpp:165
template<typename T >
void anonymous_namespace{chameleon.cpp}::ChiSolver< T >::set_convergence ( double  eps,
double  err_stop,
double  err_stop_min,
double  rms_stop_min,
size_t  num_fail 
)
inline

Definition at line 529 of file chameleon.cpp.

530  {
531  this->set_epsilon(eps);
532  m_err_stop = err_stop;
533  m_err_stop_min = err_stop_min;
534  m_rms_stop_min = rms_stop_min;
535  m_num_fail = num_fail;
536  }
void set_epsilon(double eps_converge)
template<typename T >
void anonymous_namespace{chameleon.cpp}::ChiSolver< T >::set_def_convergence ( )
inline

Definition at line 545 of file chameleon.cpp.

546  {// set convergence -- compensate for units in which we compute laplace operator
547  const double err_mod = get_chi_prefactor();
550  }
constexpr size_t CONVERGENCE_BI_STEPS_INIT
maximal number of steps inside bisection initialization method
Definition: chameleon.cpp:78
constexpr double CONVERGENCE_ERR_MIN
do not stop if solution is still improving
Definition: chameleon.cpp:75
void set_bisection_convergence(size_t max_bi_step, T dchi_stop, T l_stop)
Definition: chameleon.cpp:538
constexpr size_t CONVERGENCE_NUM_FAIL
stop when number of failed steps is over
Definition: chameleon.cpp:76
void set_convergence(double eps, double err_stop, double err_stop_min, double rms_stop_min, size_t num_fail)
Definition: chameleon.cpp:529
constexpr double CONVERGENCE_RES
stop when total (rms) residual below
Definition: chameleon.cpp:72
constexpr double CONVERGENCE_ERR
stop when improvements between steps slow below
Definition: chameleon.cpp:74
constexpr CHI_PREC_t CONVERGENCE_BI_L
stop bisection method when residual below
Definition: chameleon.cpp:80
constexpr CHI_PREC_t CONVERGENCE_BI_DCHI
stop bisection method when chi doesn`t chanege
Definition: chameleon.cpp:79
constexpr double CONVERGENCE_RES_MIN
do not stop if solution didn`t converge below
Definition: chameleon.cpp:73
template<typename T >
void anonymous_namespace{chameleon.cpp}::ChiSolver< T >::set_linear ( Mesh rho,
const FFTW_PLAN_TYPE p_F,
const FFTW_PLAN_TYPE p_B 
)
inline

Definition at line 614 of file chameleon.cpp.

615  {/* set chameleon guess to linear prediction */
616 
617  // solve level = 0, use already allocated space and created plans
618  set_linear_sol_at_level(rho, p_F, p_B, 0);
619 
620  // recursively solve at level > 0, create new grids and plans (small)
622  }
void set_linear_sol_at_level(Mesh &rho, const FFTW_PLAN_TYPE &p_F, const FFTW_PLAN_TYPE &p_B, size_t level)
Definition: chameleon.cpp:570
template<typename T >
void anonymous_namespace{chameleon.cpp}::ChiSolver< T >::set_linear_recursively ( size_t  level)
inline

Definition at line 591 of file chameleon.cpp.

References Mesh::complex(), FFTW_PLAN_C2R, FFTW_PLAN_R2C, FFTW_PLAN_TYPE, Mesh_base< T >::real(), and anonymous_namespace{chameleon.cpp}::transform_Grid_to_Mesh().

592  {
593  // we are at the bottom level
594  if (level >= this->get_Nlevel()) return;
595 
596  // extract parameters
597  const size_t N = this->get_N(level);
598 
599  // create temporary Mesh to compute linear potential, copy density
600  Mesh rho(N);
601  transform_Grid_to_Mesh(rho, this->get_external_grid(level, 0));
602 
603  // initialize FFTW
604  const FFTW_PLAN_TYPE p_F = FFTW_PLAN_R2C(N, N, N, rho.real(), rho.complex(), FFTW_ESTIMATE);
605  const FFTW_PLAN_TYPE p_B = FFTW_PLAN_C2R(N, N, N, rho.complex(), rho.real(), FFTW_ESTIMATE);
606 
607  // set linear prediction
608  set_linear_sol_at_level(rho, p_F, p_B, level);
609 
610  // solve linear prediction for the next level
611  set_linear_recursively(level + 1);
612  }
size_t get_Nlevel() const
: creates a mesh of N*N*(N+2) cells
Definition: class_mesh.hpp:95
size_t get_N(size_t level=0) const
void transform_Grid_to_Mesh(Mesh &mesh, const Grid< 3, T > &grid)
Definition: chameleon.cpp:115
Grid< NDIM, T > & get_external_grid(size_t level, size_t field)
#define FFTW_PLAN_C2R
Definition: precision.hpp:30
void set_linear_sol_at_level(Mesh &rho, const FFTW_PLAN_TYPE &p_F, const FFTW_PLAN_TYPE &p_B, size_t level)
Definition: chameleon.cpp:570
#define FFTW_PLAN_TYPE
Definition: precision.hpp:26
#define FFTW_PLAN_R2C
Definition: precision.hpp:29
template<typename T >
void anonymous_namespace{chameleon.cpp}::ChiSolver< T >::set_linear_sol_at_level ( Mesh rho,
const FFTW_PLAN_TYPE p_F,
const FFTW_PLAN_TYPE p_B,
size_t  level 
)
inline

Definition at line 570 of file chameleon.cpp.

References anonymous_namespace{chameleon.cpp}::CHI_MIN, fftw_execute_dft_c2r(), fftw_execute_dft_r2c(), Mesh::N, and anonymous_namespace{chameleon.cpp}::transform_Mesh_to_Grid().

571  {/* set chameleon guess to linear prediction at specific level */
572  // check we have the right grids
573  if (this->get_N(level) != rho.N) throw std::range_error("Mesh of a different size than Grid at current level!");
574 
575  // get delta(k)
576  fftw_execute_dft_r2c(p_F, rho);
577 
578  // get dchi(k)
579  get_chi_k(rho);
580 
581  // get dchi(x)
582  fftw_execute_dft_c2r(p_B, rho);
583 
584  // transform dchi into chi, in chi_a units this means only 'chi = 1 + dchi' */
585  rho += 1 + CHI_MIN;
586 
587  // copy dchi(x) onto Grid at level
588  transform_Mesh_to_Grid(rho, this->get_grid(level));
589  }
constexpr CHI_PREC_t CHI_MIN
minimum value of chameleon field, in chi_a units it is &#39;0&#39;, in phi units it is &#39;-1&#39; ...
Definition: chameleon.cpp:66
Grid< NDIM, T > & get_grid(size_t level=0)
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
size_t get_N(size_t level=0) const
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
size_t N
Definition: class_mesh.hpp:102
void transform_Mesh_to_Grid(const Mesh &mesh, Grid< 3, T > &grid)
Definition: chameleon.cpp:89
template<typename T >
void anonymous_namespace{chameleon.cpp}::ChiSolver< T >::set_screened ( size_t  level = 0)
inline

< we are at the bottom level

< CHI_MIN to indicate high-density region

< recursive call to fix all levels

Definition at line 624 of file chameleon.cpp.

References anonymous_namespace{chameleon.cpp}::CHI_MIN, anonymous_namespace{chameleon.cpp}::MARK_CHI_BOUND_COND, and growth_allz::T.

625  {/* check solution for invalid values (non-linear regime), fix values in high density regions, try to improve guess in others */
626  if (level >= this->get_Nlevel()) return;
627 
628  Grid<3, T>& chi = this->get_grid(level); // guess
629  const size_t N_tot = this->get_Ntot(level);
630  const size_t N = this->get_N(level);
631  T* const rho_grid = this->get_external_field(level, 0); // overdensity
632  std::vector<size_t> index_list;
633 
634  #pragma omp parallel for private(index_list)
635  for (size_t i = 0; i < N_tot; ++i)
636  {
637  if (chi[i] <= CHI_MIN) // non-linear regime
638  {
639  if (check_surr_dens(rho_grid, index_list, i, N)) chi[i] = CHI_MIN;
640  else chi[i] = rho_grid[i] > 0 ? chi_min(rho_grid[i]) : 1/2. + CHI_MIN;//< phi_s / 2 in underdense region as starting point
641  }
642  }
643 
644  fix_vals[level].clear();
645 
646  // writing into map, do not use omp
647  for (size_t i = 0; i < N_tot; ++i)
648  {
649  if (chi[i] == CHI_MIN) // fix chameleon to bulk value, set unphysical density to indicate screened regime
650  {
651 
652  chi[i] = chi_min(rho_grid[i]);
653  rho_grid[i] = MARK_CHI_BOUND_COND;
654  fix_vals[level].emplace(i, chi[i]);
655  }
656  }
657 
658  size_t num_high_density = fix_vals[level].size();
659  BOOST_LOG_TRIVIAL(debug) << "Identified and fixed " << num_high_density << "(" << std::setprecision(2) << num_high_density*100.0/N_tot << "%) points at level " << level;
660 
661  set_screened(level + 1);
662  }
constexpr CHI_PREC_t CHI_MIN
minimum value of chameleon field, in chi_a units it is &#39;0&#39;, in phi units it is &#39;-1&#39; ...
Definition: chameleon.cpp:66
Grid< NDIM, T > & get_grid(size_t level=0)
T * get_external_field(size_t level, size_t field)
size_t get_Nlevel() const
size_t get_N(size_t level=0) const
size_t get_Ntot(size_t level=0) const
Definition: grid.h:21
constexpr CHI_PREC_t MARK_CHI_BOUND_COND
unphysical value of overdensity (< -1) used to indicate that chameleon filed at this point should not...
Definition: chameleon.cpp:52
std::vector< std::map< size_t, T > > fix_vals
<index, value>
Definition: chameleon.cpp:180
bool check_surr_dens(T const *const rho_grid, std::vector< size_t > index_list, size_t i, size_t N)
Definition: chameleon.cpp:237
template<typename T >
void anonymous_namespace{chameleon.cpp}::ChiSolver< T >::set_time ( a,
const Cosmo_Param cosmo 
)
inline

Definition at line 250 of file chameleon.cpp.

References pow().

251  {
252  chi_prefactor = chi_prefactor_0*pow(a, -3.*(2.-n)/(1.-n));
253  }
const T chi_prefactor_0
dimensionless prefactor to poisson equation at a = 1
Definition: chameleon.cpp:164
float pow(float base, unsigned long int exp)
Definition: precision.hpp:39
T chi_prefactor
time-dependent prefactor
Definition: chameleon.cpp:165
template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::upd_operator ( const T  f,
const size_t  level,
const std::vector< size_t > &  index_list,
const T  h 
) const
inlineoverridevirtual

Reimplemented from MultiGridSolver< 3, T >.

Definition at line 377 of file chameleon.cpp.

References cl_cmbl_bm::l, and growth_allz::T.

378  {/* Method for updating solution:
379  if df is large, try bisection, otherwise Newton`s method
380  try Newton`s method and check for unphysical values */
381  T l = l_operator(level, index_list, true, h);
382  T dl = dl_operator(level, index_list, h);
383  T df = -l/dl;
384  T df_rel = std::abs(df/(f - CHI_MIN));
385 
386  static_assert((SWITCH_BIS_NEW < 1), "Newton`s method cannot be allowed with negative values. Adjust 'SWITCH_BIS_NEW < 1'.");
387 
388  return df_rel < SWITCH_BIS_NEW ? f + df : bisection(f, l, df / 2, level, index_list, h);
389  }
constexpr CHI_PREC_t CHI_MIN
minimum value of chameleon field, in chi_a units it is &#39;0&#39;, in phi units it is &#39;-1&#39; ...
Definition: chameleon.cpp:66
T dl_operator(const size_t level, const std::vector< size_t > &index_list, const T h) const override
Definition: chameleon.cpp:293
T l_operator(const T chi_i, const size_t level, const std::vector< size_t > &index_list, const bool addsource, const T h) const
Definition: chameleon.cpp:258
T bisection(T f1, T l1, const T df, const size_t level, const std::vector< size_t > &index_list, const T h) const
Definition: chameleon.cpp:356
constexpr CHI_PREC_t SWITCH_BIS_NEW
when the relative change in solution is less than this, use Newton`s method. Bisection method otherwi...
Definition: chameleon.cpp:59

Member Data Documentation

template<typename T >
const T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::beta

Chameleon coupling constant.

Definition at line 161 of file chameleon.cpp.

template<typename T >
const T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::chi_0

2*beta*Mpl*phi_scr

Definition at line 162 of file chameleon.cpp.

template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::chi_prefactor

time-dependent prefactor

Definition at line 165 of file chameleon.cpp.

template<typename T >
const T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::chi_prefactor_0

dimensionless prefactor to poisson equation at a = 1

Definition at line 164 of file chameleon.cpp.

template<typename T >
std::vector<std::map<size_t, T> > anonymous_namespace{chameleon.cpp}::ChiSolver< T >::fix_vals

<index, value>

Definition at line 180 of file chameleon.cpp.

template<typename T >
size_t anonymous_namespace{chameleon.cpp}::ChiSolver< T >::m_conv_stop = 0

Definition at line 168 of file chameleon.cpp.

template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::m_dchi_stop

Definition at line 176 of file chameleon.cpp.

template<typename T >
double anonymous_namespace{chameleon.cpp}::ChiSolver< T >::m_err_stop

Definition at line 170 of file chameleon.cpp.

template<typename T >
double anonymous_namespace{chameleon.cpp}::ChiSolver< T >::m_err_stop_min

Definition at line 171 of file chameleon.cpp.

template<typename T >
T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::m_l_stop

Definition at line 177 of file chameleon.cpp.

template<typename T >
size_t anonymous_namespace{chameleon.cpp}::ChiSolver< T >::m_max_bisection_steps

Definition at line 175 of file chameleon.cpp.

template<typename T >
size_t anonymous_namespace{chameleon.cpp}::ChiSolver< T >::m_num_fail

Definition at line 172 of file chameleon.cpp.

template<typename T >
double anonymous_namespace{chameleon.cpp}::ChiSolver< T >::m_rms_stop_min

Definition at line 169 of file chameleon.cpp.

template<typename T >
const T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::n

Hu-Sawicki paramater.

Definition at line 160 of file chameleon.cpp.

template<typename T >
const T anonymous_namespace{chameleon.cpp}::ChiSolver< T >::phi_prefactor

prefactor for Poisson equation for gravitational potential

Definition at line 163 of file chameleon.cpp.


The documentation for this class was generated from the following file: