Source code for gammaALPs.bfields.cell

# --- Imports --------------------- #
from __future__ import absolute_import, division, print_function
import numpy as np
from numpy.random import rand, seed
from astropy import units as u
from ..utils import trafo
from astropy.cosmology import FlatLambdaCDM
# --------------------------------- #


# ========================================================== #
# === cell-like turbulent magnetic field ================= #
# ========================================================== #
[docs] class Bcell(object): """ Class to calculate a turbulent magnetic field with a cell like structure """
[docs] def __init__(self, B, Lcoh, seed=None): """ Initialize B field with cell like structure. Parameters ---------- B: float rms B field strength in micro Gauss Lcoh: float coherence length in kpc """ # --- Set the defaults self._B = B self._Lcoh = Lcoh self._seed = seed return
@property def B(self): return self._B @property def Lcoh(self): return self._Lcoh @B.setter def B(self,B): if type(B) == u.Quantity: self._B = B.to('10**-6G').value else: self._B = B return @Lcoh.setter def Lcoh(self,Lcoh): if type(B) == u.Quantity: self._Lcoh = Lcoh.to('kpc').value else: self._Lcoh = Lcoh return
[docs] def new_random_numbers(self, Nd, nsim=1): """Generate new random numbers for angle of magnetic field for Nd domains""" # angle between photon propagation on B-field in i-th domain seed(self._seed) return 2. * np.pi * rand(nsim,int(Nd))
[docs] def new_Bn(self, Nd, Bscale=None, nsim=1): """ Calculate two components of a turbulent magnetic field and the angle between the the two. Parameters ---------- Nd: int number of domains Bscale: array-like, float, or None if not None, float or Nd-dim array with scaling factor for magnetic field along distance travelled nsim: int number of random realizations of the magnetic field. Default: 1 Returns ------- B, Psin: tuple with :py:class:`~numpy.ndarray` Two squeezed (nsim,Nd)-dim array with absolute value of transversal field, as well as angles between total transversal magnetic field and the :math:`y` direction. Note ---- If z is not a multiple integer of Lcoh, last not fully crossed domain will be discarded """ # determine number of crossed domains, no expansion assumed Psin = self.new_random_numbers(Nd,nsim = nsim) if nsim == 1: Psin = np.squeeze(Psin) B = np.ones(Nd) * self._B else: B = np.ones(Psin.shape) * self._B if np.isscalar(Bscale) or type(Bscale) == np.ndarray: B *= Bscale return B,Psin
[docs] def new_Bcosmo(self, z, Bscale=None, cosmo=FlatLambdaCDM(H0=70., Om0=0.3), nsim = 1): """ Calculate two components of a cosmological turbulent magnetic field and the angle between the the two. B field will be scaled with (1. + z)^2 and coherence length with (1. + z) Parameters ---------- z: float redshift to source Bscale: array-like, float, or None if not None, float or Nd-dim array with scaling factor for magnetic field along distance travelled cosmo: :py:class:`~astropy.cosmology.core.FlatLambdaCDM` chosen cosmology, default is H0 = 70, Om0 = 0.3 nsim: int number of random realizations of the magnetic field. Default: 1 Returns ------- B, Psin, dL, zstep: tuple with :py:class:`~numpy.ndarray` Squeezed (nsim,Nd)-dim array with absolute value of transversal field, angles between total transversal magnetic field and the :math:`y` direction, coherence lengths of cells in observer's frame and associated steps in redshift """ # determine number of crossed domains, no expansion assumed dL, zstep = trafo.cosmo_cohlength(z,self._Lcoh * u.kpc, cosmo = cosmo) Psin = np.squeeze(self.new_random_numbers(dL.shape[0],nsim = nsim)) zmean = zstep[:-1] B = self._B * (1. + zmean) ** 2. if np.isscalar(Bscale) or type(Bscale) == np.ndarray: B *= Bscale return B, Psin, dL, zstep