diff options
author | Aaron LI <aly@aaronly.me> | 2017-07-26 16:03:33 +0800 |
---|---|---|
committer | Aaron LI <aly@aaronly.me> | 2017-07-26 16:03:33 +0800 |
commit | 43d05744123aee58ac8fad8dc778657c102630ec (patch) | |
tree | a58d3b1e918f2d85093788c8fce76429e1655f71 /fg21sim | |
parent | b6a7445e9a63ac0e834ca7c92c8b0ec1533a8573 (diff) | |
download | fg21sim-43d05744123aee58ac8fad8dc778657c102630ec.tar.bz2 |
clusters/emission.py: Rewrite emissivity calculation
Use 2D grid of (discrete) samples to optimize integration speed,
avoiding the more complicated integration w.r.t. functions.
WARNING:
Current calculation results seems wrong!
Signed-off-by: Aaron LI <aly@aaronly.me>
Diffstat (limited to 'fg21sim')
-rw-r--r-- | fg21sim/extragalactic/clusters/emission.py | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/fg21sim/extragalactic/clusters/emission.py b/fg21sim/extragalactic/clusters/emission.py index 82532ea..b17c00b 100644 --- a/fg21sim/extragalactic/clusters/emission.py +++ b/fg21sim/extragalactic/clusters/emission.py @@ -15,7 +15,6 @@ References import logging import numpy as np -import scipy.integrate import scipy.special from scipy import integrate from scipy import interpolate @@ -147,6 +146,13 @@ class SynchrotronEmission: Calculate the synchrotron emissivity (power emitted per volume and per frequency) at the requested frequency. + NOTE + ---- + Since ``self.gamma`` and ``self.n_e`` are sampled on a logarithmic + grid, we integrate over ``ln(gamma)`` instead of ``gamma`` directly: + I = int_gmin^gmax f(g) d(g) + = int_ln(gmin)^ln(gmax) f(g) g d(ln(g)) + Parameters ---------- nu : float @@ -159,20 +165,23 @@ class SynchrotronEmission: Synchrotron emissivity at frequency ``nu``. Unit: [erg/s/cm^3/Hz] """ - def func(theta, _p, _n_e): - nu_c = self.frequency_crit(_p, theta) - x = nu / nu_c - return (np.sin(theta)**2 * _n_e * self.F(x)) - - coef = np.sqrt(3) * AC.e**3 * self.B / AC.c # multiplied a [mec] - func_p = np.zeros(self.p.shape) - for i in range(len(self.p)): - # Integrate over ``theta`` - func_p[i] = scipy.integrate.quad( - lambda t: func(t, self.p[i], self.n_e[i]), - a=0, b=np.pi/2)[0] - # Integrate over ``p`` - j_nu = coef * scipy.integrate.trapz(func_p, self.p) + # Ignore the zero angle + theta = np.linspace(0, np.pi/2, num=len(self.gamma))[1:] + theta_grid, gamma_grid = np.meshgrid(theta, self.gamma) + nu_c = self.frequency_crit(gamma_grid, theta_grid) + Fv = np.vectorize(self.F, otypes=[np.float]) + x = nu / nu_c + kernel = Fv(x) + + # 2D samples over width to do the integration + s2d = kernel * np.outer(self.n_e, np.sin(theta)**2) + # Integrate over ``theta`` (the last axis) + s1d = integrate.simps(s2d, x=theta) + # Integrate over energy ``gamma`` in logarithmic grid + j_nu = integrate.simps(s1d*self.gamma, np.log(self.gamma)) + + coef = np.sqrt(3) * AC.e**3 * self.B / AC.c + j_nu *= coef return j_nu def power(self, nu): |