diff options
Diffstat (limited to 'fg21sim/extragalactic/clusters')
| -rw-r--r-- | fg21sim/extragalactic/clusters/halo.py | 106 | ||||
| -rw-r--r-- | fg21sim/extragalactic/clusters/main.py | 23 | 
2 files changed, 57 insertions, 72 deletions
| diff --git a/fg21sim/extragalactic/clusters/halo.py b/fg21sim/extragalactic/clusters/halo.py index 9564be3..7887ace 100644 --- a/fg21sim/extragalactic/clusters/halo.py +++ b/fg21sim/extragalactic/clusters/halo.py @@ -44,6 +44,7 @@ import numpy as np  from . import helper  from .solver import FokkerPlanckSolver +from ...configs import configs  from ...utils import cosmo  from ...utils.units import (Units as AU,                              UnitConversions as AUC, @@ -69,6 +70,7 @@ class RadioHalo:      3. Assume the electrons are constantly injected and has a power-law         energy spectrum;      4. Determine the initial electron density +    TODO...      after that, calculate the electron acceleration and time evolution      by solving the Fokker-Planck equation; and finally derive the radio @@ -90,25 +92,55 @@ class RadioHalo:          The timescale of the merger-induced disturbance.          Unit: [Gyr]      ... + +    Attributes +    ---------- +    fpsolver : `~FokkerPlanckSolver` +        The solver instance to calculate the electron spectrum evolution. +    radius : float +        The halo radius (scales with the virial radius) +        Unit: [kpc]      """ -    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): +    def __init__(self, M_obs, z_obs, M_main, M_sub, z_merger, +                 configs=configs):          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 + +        self.configs = configs +        self._set_configs() +        self._set_solver() + +    def _set_configs(self): +        comp = "extragalactic/halos" +        self.eta_turb = self.configs.getn(comp+"/eta_turb") +        self.eta_e = self.configs.getn(comp+"/eta_e") +        self.gamma_min = self.configs.getn(comp+"/gamma_min") +        self.gamma_max = self.configs.getn(comp+"/gamma_max") +        self.gamma_np = self.configs.getn(comp+"/gamma_np") +        self.buffer_np = self.configs.getn(comp+"/buffer_np") +        self.time_step = self.configs.getn(comp+"/time_step") +        self.injection_index = self.configs.getn(comp+"/injection_index") + +    def _set_solver(self): +        self.fpsolver = FokkerPlanckSolver( +            xmin=self.gamma_min, xmax=self.gamma_max, +            x_np=self.gamma_np, +            tstep=self.time_step, +            f_advection=self.fp_advection, +            f_diffusion=self.fp_diffusion, +            f_injection=self.fp_injection, +            buffer_np=self.buffer_np, +        ) + +    @property +    def gamma(self): +        """ +        The logarithmic grid adopted for solving the equation. +        """ +        return self.fpsolver.x      @property      def age_obs(self): @@ -154,58 +186,27 @@ class RadioHalo:          Returns          ------- -        gamma : `~numpy.ndarray` -            The Lorentz factor grid adopted for solving the equation. -        n_e : `~numpy.ndarray` +        electron_spec : `~numpy.ndarray`              The solved electron spectrum at ``zend``.              Unit: [cm^-3]          """          if zbegin is None: -            tstart = cosmo.age(self.zmax) +            tstart = cosmo.age(self.z_merger)          else:              tstart = cosmo.age(zbegin)          if zend is None: -            tstop = cosmo.age(self.z0) +            tstop = cosmo.age(self.z_obs)          else:              tstop = cosmo.age(zend) - -        fpsolver = FokkerPlanckSolver( -            xmin=self.gamma_min, xmax=self.gamma_max, -            x_np=self.gamma_np, -            tstep=self.time_step, -            f_advection=self.fp_advection, -            f_diffusion=self.fp_diffusion, -            f_injection=self.fp_injection, -            buffer_np=self.buffer_np, -        ) -        gamma = fpsolver.x          if n0_e is None:              # Accumulated constantly injected electrons until ``tstart``.              n_inj = np.array([self.fp_injection(gm)                                for gm in self.gamma])              n0_e = n_inj * tstart -        n_e = fpsolver.solve(u0=n0_e, tstart=tstart, tstop=tstop) -        return (gamma, n_e) - -    def _z_end(self, z_begin, time): -        """ -        Calculate the ending redshift from ``z_begin`` after elapsing -        ``time``. -        Parameters -        ---------- -        z_begin : float -            Beginning redshift -        time : float -            Elapsing time (unit: Gyr) -        """ -        t_begin = cosmo.age(z_begin)  # [Gyr] -        t_end = t_begin + time -        if t_end >= cosmo.age(0): -            z_end = 0.0 -        else: -            z_end = cosmo.redshift(t_end) -        return z_end +        self.electron_spec = self.fpsolver.solve(u0=n0_e, tstart=tstart, +                                                 tstop=tstop) +        return self.electron_spec      def fp_injection(self, gamma, t=None):          """ @@ -417,7 +418,8 @@ class RadioHalo:          Ref.[sarazin1999],Eq.(6,7)          """          z = cosmo.redshift(t) +        mass = self._mass(t) +        B = helper.magnetic_field(mass)          coef = -1.37e-20 * AUC.Gyr2s  # [Gyr^-1] -        loss = (coef * gamma**2 * -                ((self.magnetic_field/3.25)**2 + (1+z)**4)) +        loss = coef * gamma**2 * ((B/3.25)**2 + (1+z)**4)          return loss diff --git a/fg21sim/extragalactic/clusters/main.py b/fg21sim/extragalactic/clusters/main.py index db82e78..7d8d494 100644 --- a/fg21sim/extragalactic/clusters/main.py +++ b/fg21sim/extragalactic/clusters/main.py @@ -24,6 +24,7 @@ import pandas as pd  from .formation import ClusterFormation  from .halo import RadioHalo +from ...configs import configs  from ...sky import get_sky  from ...utils import cosmo  from ...utils.io import dataframe_to_csv @@ -57,7 +58,7 @@ class GalaxyClusters:      # Component name      name = "galaxy clusters (halos)" -    def __init__(self, configs): +    def __init__(self, configs=configs):          self.configs = configs          self.sky = get_sky(configs)          self._set_configs() @@ -89,24 +90,6 @@ class GalaxyClusters:          logger.info("Loaded and set up configurations") -    @property -    def halo_configs(self): -        """ -        Configurations for radio halo simulation as a dictionary. -        """ -        comp = "extragalactic/halos" -        haloconf = { -            "eta_turb": self.configs.getn(comp+"/eta_turb"), -            "eta_e": self.configs.getn(comp+"/eta_e"), -            "gamma_min": self.configs.getn(comp+"/gamma_min"), -            "gamma_max": self.configs.getn(comp+"/gamma_max"), -            "gamma_np": self.configs.getn(comp+"/gamma_num"), -            "buffer_np": self.configs.getn(comp+"/buffer_np"), -            "time_step": self.configs.getn(comp+"/time_step"), -            "injection_index": self.configs.getn(comp+"/injection_index"), -        } -        return haloconf -      def _load_catalog(self):          """          Load the sampled (z, mass) catalogs from the Press-Schechter @@ -258,7 +241,7 @@ class GalaxyClusters:          logger.info("{name}: preprocessing ...".format(name=self.name))          self._load_catalog()          self._process_catalog() -        self._simulate_mergers() +        # self._simulate_mergers()          # TODO ??? | 
