GithubHelp home page GithubHelp logo

cosmology-project-au-21's People

Contributors

samgrund avatar

Stargazers

 avatar

Watchers

 avatar

cosmology-project-au-21's Issues

Few issues in Evolver RK.ipynb

Hi

Evolver RK looks really good, nice work! However, I noticed a few mistakes and some things that can be improved:

The ODE for growth,

def dudt(t, p):
    H = dadt(t,p)/p[2]
    return 3/2 * H**2 * omega0M * p[0] - 2*H*p[1]

seems wrong. Probably omega0M should really be the dreaded time-dependent function $\Omega_m(a)$ as defined by Ryden. I think the substitution should be H**2 * omega0M -> omega0M/p[2]**3 where we are using units of $H_0^{-1}$. But please check against Rydens definition.

The initial time,

tstart   = 1/(np.sqrt(omega0R)*70) * 1/2 * astart**2

has a small error. The "70" should be removed, since we are using units of $H_0^{-1}$. Furthermore, this relation assumes radiation domination, so it is probably better to set a_start to something even lower, perhaps 1e-7.

When initialising a model in CLASSpp, there are two options:
Either initialise on construction (preferred method) like this:

Omega_b = 0.05
cosmo = Class({'Omega_b':Omega_b, 'Omega_cdm':omega0M - Omega_b, 'H0':70})

or initialise CLASS with the default model, call the .set() method repeatedly with a final call to .compute():

cosmo = Class()
Omega_b = 0.05
cosmo.set({'Omega_b':Omega_b, 'Omega_cdm':omega0M - Omega_b, 'H0':70})
cosmo.compute()

Without the final compute, CLASS was using default values for $H_0$ and $\Omega_m$. (I think I might be responsible for introducing that mistake in your notebook!)

Now everything is working I think. There are a few more points however:

  • To properly normalise delta(a), you need to divide by the value of delta(a) today, i.e. delta(a==1). The easiest way to get it is to interpolate. Something like np.interp(1, yvals[:,2], yvals[:,0]. (Spline interpolation with scipy is also an option.)
  • tstop should be set to a value larger than 1 to make sure that a=1 is part of the solution output.

Cheers,
Thomas

Analytical computation of delta

Hi

Perhaps it would be nice to add a line with the analytical approximation of delta? It is given by equation B.2 in the appendix of this paper. The definition of $x$ in B.2 is given by equation B.1, and $\delta$ is denoted by $D$. The function 2F1(a, b, c, x) is called Gauss' hypergeometric function, and it is available in scipy.special:

import scipy.special
scipy.special.hyp2f1(a, b, c, x)

One more thing: Instead of plotting the time-derivative of delta, it is more customary to plot the logarithmic derivative of delta w.r.t. a which is denoted f:

image

This quantity is also available in CLASS. And if you are courageous, you may also find an analytical solution for f by finding a formula for the analytic derivative of Gauss hypergeometric function. (Or the equivalent Legendre function!). DLMF might be handy!

Critical bug in Evolver RK

Hi

I just checked the growth equation, and it did not work at all. The problem is in the implementation of RK4. Consider this loop:

        for (j,dydt) in enumerate(dydts):
            k1 = dt * dydt(ts[i],yvals[i])
            k2 = dt * dydt(ts[i] + dt/2, yvals[i] + k1/2)
            k3 = dt * dydt(ts[i] + dt/2, yvals[i] + k2/2)
            k4 = dt * dydt(ts[i] + dt, yvals[i] + k3)
            yn[j] = yn[j] + k1/6 + k2/3 + k3/3 + k4/6

dydt depends on the full solution vector in yvals but returns only a single value. That means that a sum like yvals[i] + k1/2 adds k1/2 to all entries in yvals[i] before sending it to the function! Thus, when dudt needs access to a = p[2], p[2] is completely wrong! The Friedmann equation is still OK however, since it does not depend on other values.

One might then choose to construct a temporary variable ytmp which is a .copy() of yvals[i] with k1/2 added on the j'th position. However, that is still not ideal, since the "intermediate" values would not all be updated at the same time.

The most elegant way to solve this problem is to create a function that returns the full dydt array. Then k_i become proper arrays of the same size as y, and the inner loop can be eliminated completely.

It is also possible to remove the two np.delete statements in RK4 and simply make the assignment in the outer loop like this:

yvals[i + 1] = yvals[i] + k1/6 + k2/3 + k3/3 + k4/6

If yvals[0] is initialised to p0, you can also get rid of yn completely. ๐Ÿ‘

Let me know if this makes sense!

Cheers,
Thomas

Various suggestions

Excellent, great work!! The code reproduces the correct solution after a few minor tweaks:

  • The initial scale factor a0 has a default value of 1, but it should be set to a value close to zero, e.g. 1e-16.
  • tstart and a0 are not independent, but they should be set using the exact solution in radiation domination. However, as long as they are both "small", it does not matter at late times.

Here is the plot I get:
image

Note that I have added two additional curves. One is the relationship computed by CLASS and the other is the analytical solution in a flat Matter + Lambda Universe, see equation (5) in this exercise.

Here are the lines of code that computes the CLASS curve:

from classy import Class
cosmo = Class()
Omega_b = 0.05
cosmo.set({'Omega_b':Omega_b, 'Omega_cdm':omega0M - Omega_b, 'H0':70})
bg = cosmo.get_background()
ax.plot(bg['proper time [Gyr]']*0.001022*70, 1/(1 + bg['z']), label='CLASS', ls='--')

A few additional tweaks that you may consider:

  • Define the right-hand-side (RHS) of the differential equation as a function dy/dt = f(t, y), and rewrite solveFriedmann() to take such a function as input. That way, you can easily play with other forms of the Friedmann equation (e.g. including curvature or ignoring Lambda), and you can even use this function to solve other differential equations. (For instance the growth equation which we shall solve later.) It will also make it easy to compare against methods included in SciPy).
  • The x-axis label is not completely correct: What you plot can be either considered as H0*t or t in the units of H0^(-1).
  • You can use ** instead of np.power().

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.