Source code for pychangcooper.scenarios.synchrotron_cooling

import numpy as np

from pychangcooper.chang_cooper import ChangCooper, log_grid_generator
from pychangcooper.photons.photon_emitter import PhotonEmitter
from pychangcooper.photons.synchrotron_emission import (
    SynchrotronEmission,
    synchrotron_cooling_constant,
    synchrotron_cooling_time,
)
from pychangcooper.scenarios.continuous_powerlaw_injection import (
    ContinuousPowerlawInjection,
)
from pychangcooper.scenarios.generic_cooling_component import GenericCoolingComponent


[docs]class SynchrotronCoolingComponent(GenericCoolingComponent): def __init__(self, B): """ A synchrotron cooling component that implements the proper cooling terms :param B: magnetic field strength in Gauss """ C0 = synchrotron_cooling_constant(B) super(SynchrotronCoolingComponent, self).__init__(C0, 2.0)
[docs]class SynchrotronCooling_ImpulsivePLInjection( SynchrotronCoolingComponent, PhotonEmitter, ChangCooper ): def __init__( self, B=10.0, index=-2.2, gamma_injection=1e3, gamma_cool=2e3, gamma_max=1e5, n_grid_points=300, max_grid=1e7, store_progress=False, ): """ Synchrotron cooling and radiation from an impulsive power law injection of particles. :param B: the magnetic field strength in Gaussa :param index: the injected electron spectral index :param gamma_injection: the electron injection energy :param gamma_cool: the cooling energy :param gamma_max: the maximum injected energy :param n_grid_points: the number of grid point :param max_grid: the maximum grid energy :param store_progress: to store progress """ self._B = B bulk_gamma = 300.0 # calculate the number of steps to cool the maximum # electron energy to gamma cool ratio = gamma_max / gamma_cool n_steps = np.round(ratio) # assign the properties to the calss self._gamma_max = gamma_max self._gamma_cool = gamma_cool self._gamma_injection = gamma_injection self._index = index # build the initial power law injection initial_distribution = np.zeros(n_grid_points) tmp_grid, _, _ = log_grid_generator(n_grid_points, max_grid) idx = (gamma_injection <= tmp_grid) & (tmp_grid <= gamma_max) # normalize the electrons so that N = number of electrons norm = ( np.power(gamma_max, index + 1) - np.power(gamma_injection, index + 1) ) / (index + 1) initial_distribution[idx] = 1.0 * norm * np.power(tmp_grid[idx], index) # set the time step to be that of the cooling time of # the most energetic electrons delta_t = synchrotron_cooling_time(B, gamma_max) # initialize the cooling terms SynchrotronCoolingComponent.__init__(self, B) # build the solver ChangCooper.__init__( self, n_grid_points, max_grid, delta_t, initial_distribution, store_progress ) # create the emission kernel for producing radiation emission_kernel = SynchrotronEmission(self._grid, self._B) # initialize the radiation production PhotonEmitter.__init__(self, n_steps, emission_kernel)
[docs]class SynchrotronCooling_ContinuousPLInjection( SynchrotronCoolingComponent, ContinuousPowerlawInjection, PhotonEmitter, ChangCooper ): def __init__( self, B=10.0, index=-2.2, gamma_injection=1e3, gamma_cool=2e3, gamma_max=1e5, n_grid_points=300, max_grid=1e7, store_progress=False, ): """ Synchrotron cooling and radiation from continuous power law injection of particles. :param B: the magnetic field strength in Gaussa :param index: the injected electron spectral index :param gamma_injection: the electron injection energy :param gamma_cool: the cooling energy :param gamma_max: the maximum injected energy :param n_grid_points: the number of grid point :param max_grid: the maximum grid energy :param store_progress: to store progress """ self._B = B bulk_gamma = 300.0 # calculate the number of steps to cool the maximum # electron energy to gamma cool ratio = gamma_max / gamma_cool n_steps = np.round(ratio) # assign the properties to the calss self._gamma_max = gamma_max self._gamma_cool = gamma_cool self._gamma_injection = gamma_injection self._index = index # set the time step to be that of the cooling time of # the most energetic electrons delta_t = synchrotron_cooling_time(B, gamma_max) # initialize the cooling terms SynchrotronCoolingComponent.__init__(self, B) # create the injection ContinuousPowerlawInjection.__init__( self, gamma_injection, gamma_max, index, N=1.0 ) # build the solver ChangCooper.__init__( self, n_grid_points, max_grid, delta_t, None, store_progress ) # build the synchrotron emission kernel emission_kernel = SynchrotronEmission(self._grid, self._B) # initialize the photon emission process PhotonEmitter.__init__(self, n_steps, emission_kernel) def _clean(self): if self._iterations <= 1: self._idx_max = np.argmax(self._n_current) self._sync_max = self._n_current[self._idx_max] # now clean anything below idx1 = self._grid < self._gamma_injection idx2 = self._n_current < self._sync_max idx3 = idx1 & idx2 self._n_current[idx3] = 0.0 # now handle cooling if self._gamma_cool < self._gamma_injection: idx = self._grid < self._gamma_cool self._n_current[idx] = 0.0 else: idx = self._grid < self._gamma_injection self._n_current[idx] = 0.0
# lower_bound = min(self._gamma_cool, self._gamma_injection) # lower_bound = self._gamma_cool # idx = self._grid <= lower_bound # self._n_current[:idx] = 0.