diff options
Diffstat (limited to 'fg21sim/extragalactic/clusters')
| -rw-r--r-- | fg21sim/extragalactic/clusters/halo.py | 165 | 
1 files changed, 119 insertions, 46 deletions
| diff --git a/fg21sim/extragalactic/clusters/halo.py b/fg21sim/extragalactic/clusters/halo.py index b2f935e..dc02ee7 100644 --- a/fg21sim/extragalactic/clusters/halo.py +++ b/fg21sim/extragalactic/clusters/halo.py @@ -76,15 +76,52 @@ class RadioHalo:      Parameters      ---------- -    M0 : float -        Cluster virial mass at redshift z0 +    M_obs : float +        Cluster virial mass at the current observation (simulation end) time.          Unit: [Msun] -    z0 : float -        Redshift from where to simulate former merging history. +    z_obs : float +        Redshift of the current observation (simulation end) time. +    M_main, M_sub : float +        The main and sub cluster masses before the (major) merger. +        Unit: [Msun] +    z_merger : float +        The redshift when the (major) merger begins. +    tau_merger : float +        The timescale of the merger-induced disturbance. +        Unit: [Gyr] +    ...      """ -    def __init__(self, M0, z0): -        self.M0 = M0 -        self.z0 = z0 +    def __init__(self, M_obs, z_obs, +                 M_main, M_sub, z_merger, tau_merger, +                 eta_turb, eta_e, gamma_min, gamma_max, gamma_np, +                 buffer_np, time_step, injection_rate, injection_index): +        self.M_obs = M_obs +        self.z_obs = z_obs +        self.M_main = M_main +        self.M_sub = M_sub +        self.z_merger = z_merger +        self.eta_turb = eta_turb +        self.eta_e = eta_e +        self.gamma_min = gamma_min +        self.gamma_max = gamma_max +        self.gamma_np = gamma_np +        self.buffer_np = buffer_np +        self.time_step = time_step +        self.injection_rate = injection_rate +        self.injection_index = injection_index + +    @property +    def age_obs(self): +        return cosmo.age(self.z_obs) + +    @property +    def age_merger(self): +        return cosmo.age(self.z_merger) + +    @property +    def time_crossing(self): +        return helper.time_crossing(self.M_main, self.M_sub, +                                    z=self.z_merger)      def calc_electron_spectrum(self, zbegin=None, zend=None, n0_e=None):          """ @@ -95,10 +132,10 @@ class RadioHalo:          ----------          zbegin : float, optional              The redshift from where to solve the Fokker-Planck equation. -            Default: ``self.zmax``. +            Default: ``self.z_merger``.          zend : float, optional              The redshift where to stop solving the Fokker-Planck equation. -            Default: ``self.z0``. +            Default: ``self.z_obs``.          n0_e : 1D `~numpy.ndarray`, optional              The initial electron number distribution.              Unit: [cm^-3]. @@ -158,10 +195,12 @@ class RadioHalo:              z_end = cosmo.redshift(t_end)          return z_end -    def fp_injection(self, p, t=None): +    def fp_injection(self, gamma, t=None):          """ -        Electron injection term for the Fokker-Planck equation. +        Electron injection (rate) term for the Fokker-Planck equation. +        NOTE +        ----          The injected electrons are assumed to have a power-law spectrum          and a constant injection rate. @@ -170,8 +209,8 @@ class RadioHalo:          Parameters          ---------- -        p : float -            Electron momentum (unit: mec), i.e., Lorentz factor +        gamma : float +            Lorentz factor of electrons          t : None              Currently a constant injection rate is assumed, therefore              this parameter is not used.  Keep it for the consistency @@ -180,59 +219,40 @@ class RadioHalo:          Returns          -------          Qe : float -            Current electron injection rate at specified energy (p). -            Unit: [cm^-3 Gyr^-1 mec^-1] +            Current electron injection rate at specified energy (gamma). +            Unit: [cm^-3 Gyr^-1]          References          ---------- -        [1] Cassano & Brunetti 2005, MNRAS, 357, 1313 -            http://adsabs.harvard.edu/abs/2005MNRAS.357.1313C -            Eqs.(31-33)          """ -        if not hasattr(self, "_electron_injection_rate"): -            e_th = self.e_thermal  # [erg/cm^3] -            age = cosmo.age(self.z0) -            term1 = (self.injection_index-2) * self.eta_e -            term2 = e_th / (self.pmin * self.mec * AC.c)  # [cm^-3] -            term3 = 1.0 / (age * self.pmin)  # [Gyr^-1 mec^-1] -            Ke = term1 * term2 * term3 -            self._electron_injection_rate = Ke -        else: -            Ke = self._electron_injection_rate -        Qe = Ke * (p/self.pmin) ** (-self.injection_index) +        Qe = ValueError          return Qe -    def fp_diffusion(self, p, t): +    def fp_diffusion(self, gamma, t):          """          Diffusion term/coefficient for the Fokker-Planck equation.          Parameters          ---------- -        p : float -            Electron momentum (unit: mec), i.e., Lorentz factor +        gamma : float +            The Lorentz factor of electrons          t : float -            Current time when solving the equation (unit: Gyr) +            Current (cosmic) time when solving the equation +            Unit: [Gyr]          Returns          ------- -        Dpp : float +        diffusion : float              Diffusion coefficient -            Unit: [mec^2/Gyr] +            Unit: [Gyr^-1]          References          ---------- -        [1] Cassano & Brunetti 2005, MNRAS, 357, 1313 -            http://adsabs.harvard.edu/abs/2005MNRAS.357.1313C -            Eq.(36) -        [2] Donnert 2013, AN, 334, 615 -            http://adsabs.harvard.edu/abs/2013AN....334..515D -            Eq.(15) +        Ref.[donnert2013],Eq.(15)          """ -        z = cosmo.redshift(t) -        chi = self._coef_acceleration(z)  # [Gyr^-1] -        # NOTE: Cassano & Brunetti's formula misses a factor of 2. -        Dpp = chi * p**2 / 4  # [mec^2/Gyr] -        return Dpp +        tau_acc = self._tau_acceleration(t)  # [Gyr] +        diffusion = gamma**2 / (4 * tau_acc) +        return diffusion      def fp_advection(self, gamma, t):          """ @@ -255,6 +275,59 @@ class RadioHalo:                       (self.fp_diffusion(gamma, t) * 2 / gamma))          return advection +    def _mass(self, t): +        """ +        Calculate the main cluster mass at the given (cosmic) time. + +        NOTE +        ---- +        We assume that the main cluster grows (i.e., gains mass) linearly +        in time from (M_main, z_merge) to (M_obs, z_obs). + +        Parameters +        ---------- +        t : float +            The (cosmic) time/age. +            Unit: [Gyr] + +        Returns +        ------- +        mass : float +            The mass of the main cluster. +            Unit: [Msun] +        """ +        t_merger = self.age_merger +        rate = (self.M_obs - self.M_main) / (self.age_obs - t_merger) +        mass = rate * (t - t_merger) + self.M_main +        return mass + +    def _tau_acceleration(self, t): +        """ +        Calculate the systematic acceleration timescale at the +        given (cosmic) time. + +        NOTE +        ---- +        A reference value of the acceleration time due to TTD +        (transit-time damping) resonance is ~0.1 Gyr (Ref.[brunetti2011], +        Eq.(27) below); the formula derived by [cassano2005] (Eq.(40)) +        has a dependence on eta_turb. + +        Returns +        ------- +        tau : float +            The acceleration timescale. +            Unit: [Gyr] +        """ +        # The reference/typical acceleration timescale +        tau_ref = 0.1  # [Gyr] + +        if t > self.age_merger + self.time_crossing: +            tau = np.inf +        else: +            tau = tau_ref / self.eta_turb +        return tau +      def _loss_ion(self, gamma, t):          """          Energy loss through ionization and Coulomb collisions. | 
