7 namespace SPHERICALCOLLAPSE {
14 Spline & growthfactor_of_x_spline,
15 Spline & growthrate_of_x_spline,
22 return model.ode_system_linear_growth(
x,
y, dydx);
28 ode.
solve(deriv, x_array, y_initial);
31 auto growthrate_array = delta_prime_lin_array;
32 for(
size_t i = 0; i < growthfactor_array.size(); i++){
33 growthrate_array[i] /= growthfactor_array[i];
35 growthfactor_of_x_spline =
Spline(x_array, growthfactor_array,
"Growthfactor D(loga)");
36 growthrate_of_x_spline =
Spline(x_array, growthrate_array,
"Growthrate f(loga)");
48 return (RH0) * std::pow((1.0+delta_ini)/(1.0+delta),1.0/3.0)*
std::exp(
x);
63 const double delta_ini,
68 DVector & delta_lin_prime_array,
69 const bool get_arrays,
71 const double xcollapse,
73 const double delta_infinity) {
76 const double hstart = 1e-3;
77 const double epsilon_abs = 1e-6;
78 const double epsilon_rel = 1e-6;
81 double xminover = xcollapse;
85 for(
auto &
x : x_array)
x = std::log(
x);
87 ODEFunction deriv = [&
model,&xminover,&delta_infinity](
double x,
const double *
y,
double * dydx) ->
int {
89 if(
y[0] > delta_infinity){
90 if(
x < xminover) xminover =
x;
91 dydx[0] = dydx[1] = 0.0;
94 return model.ode_system_non_linear_growth(
x,
y, dydx);
98 DVector y_initial{delta_ini, delta_ini, delta_ini, delta_ini};
101 ode.
solve(deriv, x_array, y_initial, gsl_odeiv2_step_rkck);
120 const double xcollapse,
122 const double epsilon_delta){
124 auto condition = [&](
double delta_ini){
125 DVector x_array, delta_array, delta_prime_array, delta_lin_array, delta_lin_prime_array;
133 delta_lin_prime_array,
138 return xminover - xcollapse;
149 const double xcollapse,
151 const Spline & delta_spline,
152 const Spline & delta_prime_spline) -> std::tuple<double, double, double, double> {
155 const double epsilon_x = 1e-8;
158 auto turnaround_condition = [&delta_spline, &delta_prime_spline](
double x){
159 const double delta = delta_spline(
x), delta_prime = delta_prime_spline(
x);
160 return 1.0 - delta_prime/3.0/(1.0+delta);
165 auto virial_condition = [&
model, &delta_spline, &delta_prime_spline](
double x) {
166 const double delta = delta_spline(
x), delta_prime = delta_prime_spline(
x);
168 return model.virial_condition(delta, delta_prime, roverR,
x);
171 double x_search = xturnaround;
172 const double deltax = 0.01;
173 const int sign = virial_condition(x_search) > 0 ? 1 : -1;
175 const int sign1 = virial_condition(x_search) > 0 ? 1 : -1;
176 if(sign * sign1 == -1)
break;
182 auto nonlinear_condition = [&
model, &delta_spline, &delta_prime_spline](
double x){
183 const double delta = delta_spline(
x), delta_prime = delta_prime_spline(
x);
185 return model.nonlinear_condition(delta, delta_prime, roverR,
x);;
191 auto halfturnaround_condition = [&roverR_turnaround, &delta_spline](
double x) {
192 const double delta = delta_spline(
x);
194 return roverR - roverR_turnaround/2.0;
198 return std::tuple(xturnaround, xvir, xnl, xhalfturnaround);
208 Spline & deltac_of_x_spline,
209 Spline & DeltaVir_of_x_spline,
212 Spline & xvir_of_x_spline,
213 Spline & delta_ini_of_x_spline,
219 auto run_and_generate_delta_splines = [](
221 const double xcollapse,
225 Spline & delta_prime_spline,
226 Spline & delta_lin_spline,
227 double delta_ini = -1.0){
230 DVector x_array, delta_array, delta_prime_array, delta_lin_array, delta_lin_prime_array;
238 delta_lin_prime_array,
243 delta_spline =
Spline(x_array, delta_array,
"delta(loga)");
244 delta_prime_spline =
Spline(x_array, delta_prime_array,
"ddelta/dloga(loga)");
245 delta_lin_spline =
Spline(x_array, delta_lin_array,
"deltaLin(loga)");
250 const double zini = 10.0;
251 const double zend = 0.0;
252 const int npts_z = 100;
255 DVector deltac_array(xcollapse_array.size());
256 DVector DeltaVir_array(xcollapse_array.size());
257 DVector xta_array(xcollapse_array.size());
258 DVector xvir_array(xcollapse_array.size());
259 DVector xnl_array(xcollapse_array.size());
260 DVector delta_ini_array(xcollapse_array.size());
263#pragma omp parallel for schedule(dynamic,1)
265 for(
size_t i = 0; i < xcollapse_array.size(); i++){
266 auto xcollapse = xcollapse_array[i];
270 Spline delta_prime_spline;
272 const double delta_ini = run_and_generate_delta_splines(
282 const auto times =
compute_times(xini, xcollapse,
model, delta_spline, delta_prime_spline);
283 const double xta = std::get<0>(times);
284 const double xvir = std::get<1>(times);
285 const double xnl = std::get<2>(times);
286 const double xta2 = std::get<3>(times);
287 const double DeltaVir = (1.0+delta_spline(xvir))*
std::exp(3.0*xcollapse-3.0*xvir);
288 const double deltac = delta_lin_spline(xcollapse);
290 if(xcollapse == 0.0 and
verbose){
291 std::cout <<
"\n#=====================================================\n";
292 std::cout <<
"# For collapse at z=0 we get:\n";
293 std::cout <<
"#=====================================================\n";
294 std::cout <<
" deltac = " <<
deltac <<
"\n";
295 std::cout <<
" DeltaVir = " << DeltaVir <<
"\n";
299 std::cout <<
"#=====================================================\n";
304 xvir_array[i] = xvir;
306 DeltaVir_array[i] = DeltaVir;
307 delta_ini_array[i] = delta_ini;
310 if(
model.muofx(xcollapse) <= 0.0){
311 throw std::runtime_error(
"Spherical collapse. Negative Geff/G encountere. Problem not well posed!");
314 xta_of_x_spline =
Spline(xcollapse_array, xta_array,
"loga_turnaround(loga_collapse)");
315 xnl_of_x_spline =
Spline(xcollapse_array, xnl_array,
"loga_nonlinear(loga_collapse)");
316 xvir_of_x_spline =
Spline(xcollapse_array, xvir_array,
"loga_virialization(loga_collapse)");
317 deltac_of_x_spline =
Spline(xcollapse_array, deltac_array,
"deltac(loga_collapse)");
318 DeltaVir_of_x_spline =
Spline(xcollapse_array, DeltaVir_array,
"DeltaVir(loga_collapse)");
319 delta_ini_of_x_spline =
Spline(xcollapse_array, delta_ini_array,
"delta_ini(loga_collapse)");
The class contains all the info about the model needed to run the spherical collapse and halomodel Co...
This is a wrapper class for easy use of GSL splines It is (OpenMP) thread safe as long as splines are...
This is a wrapper around the GSL library to easily solve ODEs and return the data in whatever format ...
DVector get_data_by_component(int icomponent) const
Get the data for a particular component y_i(xarr)
void solve(ODEFunctionPointer ode_equation, void *parameters, DVector &xarr, DVector &yinitial, const gsl_odeiv2_step_type *stepper=ODESOLVER_FIDUCIAL_STEPPER, ODEFunctionPointerJacobian jacobian=nullptr)
void set_accuracy(const double hstart, const double abserr, const double relerr)
Set the accuracy parameters (first guess for the step-size, the absolute and relative error)
double evolve_spherical_collapse_equations(const SphericalCollapseModel &model, const double delta_ini, DVector &x_array, DVector &delta_array, DVector &delta_prime_array, DVector &delta_lin_array, DVector &delta_lin_prime_array, const bool get_arrays, const double xini, const double xcollapse, const int npts, const double delta_infinity)
Evolve the spherical collapse equation + linear for a given set of IC delta_ini over a given range [x...
void compute_growthfactor(const SphericalCollapseModel &model, Spline &growthfactor_of_x_spline, Spline &growthrate_of_x_spline, const double xini, const double xend, const int npts)
Computes the growth factor (not normalized) and growth rate for a given model and returns splines wit...
auto compute_times(const double xini, const double xcollapse, const SphericalCollapseModel &model, const Spline &delta_spline, const Spline &delta_prime_spline) -> std::tuple< double, double, double, double >
Extract useful times from spherical collapse evolution like turnaround, virialization and non-linear ...
double find_delta_ini(const SphericalCollapseModel &model, const double xini, const double xcollapse, const int npts, const double epsilon_delta)
Do root finding to figure out the delta_ini that gives collapse at x=xcollapse.
FML::INTERPOLATION::SPLINE::Spline Spline
double roverR_of_delta_and_x(double delta, double x, double RH0, double delta_ini)
This is the dimensionless quantity (the radius of the tophat) for spherical collapse evolution,...
void compute_sphericalcollapse_splines(const SphericalCollapseModel &model, Spline &deltac_of_x_spline, Spline &DeltaVir_of_x_spline, Spline &xnl_of_x_spline, Spline &xta_of_x_spline, Spline &xvir_of_x_spline, Spline &delta_ini_of_x_spline, const double xini, const int npts, bool verbose)
Do spherical collapse for all times.
FML::SOLVERS::ODESOLVER::DVector DVector
FML::SOLVERS::ODESOLVER::ODEFunction ODEFunction
DVector linspace(double xmin, double xmax, int num)
Python linspace. Generate a lineary spaced array.
double find_root_bisection(const std::function< double(double)> &function, std::pair< double, double > xrange, double epsilon)
Find roots using bisection.