Source code for src.Structure.AtmosphereCls

"""
This module defines several class for Solar Atmosphere model.
"""

import numpy as np

from .. import Element as Elem


################################################################################
# parent class of Cartesian atmosphere
################################################################################

[docs]class AtmosphereCartesian: r""" parent class of Cartesion Atmosphere classes. **Don't use this class since it is designed as an abstract parent class.** Attributes ---------- dType : numpy.dtype declare data type of all physical parameters in atmosphere - Te : temparature, np.double, [:math:`K`] - Vt : turbulent velocity, np.double, [:math:`cm \cdot s^{-1}`] - Ne : electron density, np.double, [:math:`cm^{-3}`] - Pg : gas pressure, np.double, [:math:`Ba = g \cdot cm^{-1} \cdot s^{-2}`] - Vd : line of sight Doppler velocity, np.double, [:math:`cm \cdot s^{-1}`] - Mesh : geometry mesh ranging from 0 to 1, np.double, [-] - Spatial : geometry mesh of physical scale, np.double, [:math:`cm`] abun : array-like, dtype of np.double abundance of each element relative to hydrogen BackRad : numpy.2darray, dtype of np.double axis 0 is wavelength in [:math:`cm`], and axis 1 is intensity in [:math:`erg/cm^2/Sr/cm/s`] """
[docs] def __init__(self): r""" decleare attributes `dType` and `abun` """ #: data type of numpy.recarray to store data self.dType = np.dtype([ ('Te',np.double), #: electron temperature ('Vt',np.double), #: turbulent velocity ('Ne',np.double), #: electron density ('Pg',np.double), #: gas pressure ('Vd',np.double), #: doppler velocity ('Mesh',np.double), #: spatial mesh [0,1] ('Spatial',np.double) #: spatial mesh [0,thickness] ]) #: currently, we adapt that abundance is spatial independent --> uniform abundance self.abun = (10.**(np.array(Elem.AbunTuple)-12.) ).astype(np.double)
def __str__(self): return None def __repr__(self): return None def readBackgroundIntensity(self,path): r""" read background intensity from path to `self.BackRad` Parameters ----------- path : str path of background radiation intensity data file Notes ------- Executing this method create an Attribute called `self.BackRad`, which is numpy.2darray, dtype of np.double, - axis 0 : wavelength mesh in [:math:`cm`], - axis 1 : the intensity in [:math:`erg/cm^2/Sr/cm/s`] """ #: [cm] V.S. [erg/s/cm^2/cm/sr] BackRad = np.loadtxt(path, dtype=np.double, skiprows=2) self.BackRad = BackRad.T.copy() self.BackRad[1,:] /= 3 def read_BackRad_QS(self): r""" """ BackRad = np.load("../../data/intensity/atlas/QS/atlas_QS.npy") wave_in_air = np.load("../../data/intensity/atlas/QS/wave_in_air.npy") se = np.load("../../data/intensity/atlas/QS/wave_in_air_se.npy") #BackRad_air = np.zeros( (2,wave_in_air.shape[0]), dtype=np.double ) #BackRad_air[1,:] = BackRad[1,se[0]:se[1]] #BackRad_air[0,:] = wave_in_air[:] self.BackRad_wav = BackRad[0,:] self.BackRad_int = BackRad[1,:] self.BackRadAir_wav = wave_in_air[:] self.BackRadAir_int = BackRad[1,se[0]:se[1]] @property def shape(self): return self.data.Mesh.shape @property def ndim(self): return self.data.Mesh.ndim
################################################################################ # zero dimensional Cartesion atmosphere ################################################################################ class AtmosphereC0d(AtmosphereCartesian): r""" zero dimensional Cartesian Atmosphere, inheritting parent class `AtmosphereCartesian` Attributes ---------- data : numpy.recarray, dtype of dTpye a structured array to store physical parameter dType : numpy.dtype a data type object decleared in parent class `AtmosphereCartesian` """ def __init__(self, Te=1E4, Vt=5.E5, Ne=1E10, Pg=5E-1, Vd=0.E5): r""" initialization method of AtmosphereC0d Parameters ---------- Te : np.double temparature, [:math:`K`] Vt : np.double turbulent velocity, [:math:`cm \cdot s^{-1}`] Ne : np.double electron density, [:math:`cm^{-3}`] Pg : np.double gas pressure, [:math:`Ba = g \cdot cm^{-1} \cdot s^{-2}`] Vd : np.double line of sight Doppler velocity, [:math:`cm \cdot s^{-1}`] """ super().__init__() self.data = np.recarray(1, dtype=self.dType) self.data.Te[:] = Te self.data.Vt[:] = Vt self.data.Ne[:] = Ne self.data.Pg[:] = Pg self.data.Vd[:] = Vd self.data.Mesh[:] = np.nan self.data.Spatial[:] = np.nan ################################################################################ # one dimensional Cartesion atmosphere ################################################################################
[docs]class AtmosphereC1d(AtmosphereCartesian): r""" one dimensional Cartesian Atmosphere, inheritting parent class `AtmosphereCartesian` Attributes ---------- Scale : tuple of float or int a tuple of size 1, specifying the grometry scale along line of sight data : numpy.recarray, dtype of dTpye a structured array to store physical parameter dType : numpy.dtype a data type object decleared in parent class `AtmosphereCartesian` """
[docs] def __init__(self, thickness, isHalf=False, Mesh=None): r""" initialization method. Parameters ---------- thickness : np.double thickness of your model, [:math:`cm`] Mesh : array-like, dtype of np.double, optional default : None - None : construct a 91 points slab Mesh or half slab Mesh automatically - array-like : user-defined mesh grid, with scale from Mesh[0] = 0 to Mesh[1] = 1 isHalf : boolean, optional default : True - False : full slab mesh grid, frequent at lower/upper surface, sparse at the middle, 91 grid points. - True : upper half of the full slab mesh, 46 grid points. """ super().__init__() self.isHalf = isHalf #: a tuple to store spatial scale self.Scale = (thickness,) if Mesh is None : Mesh = self.__defaultSlabSpatialMesh__(isHalf) else: assert Mesh.ndim==1, "keyword argument Mesh must be a one dimensional numpy.ndarray." assert Mesh[0]==0 and Mesh[-1]==1, "Mesh runs from 0 to 1 ." data = np.recarray(Mesh.shape, dtype=self.dType); self.data = data data.Mesh[:] = Mesh[:] data.Spatial[:] = data.Mesh[:] * thickness
def __defaultSlabSpatialMesh__(self, isHalf): r""" construct slab-type spatial mesh automatically Parameters ---------- isHalf : boolean, optional default : True - False : full slab mesh grid, frequent at lower/upper surface, sparse at the middle, 91 grid points. - True : upper half of the full slab mesh, 46 grid points. Returns ------- spMesh : array-like, dtype of np.double spatial mesh ranging from 0. to 1. """ assert isinstance(isHalf, bool), "keyword argument isHalf must be a boolean variable." Mesh = np.empty(91, dtype=np.double) Mesh[:46] = np.array([0.0, 1.E-8, 1.6E-8, 2.5E-8, 4.0E-8, 6.3E-8, 1.E-7, 1.6E-7, 2.5E-7, 4.0E-7, 6.3E-7, 1.E-6, 1.6E-6, 2.5E-6, 4.0E-6, 6.3E-6, 1.E-5, 1.6E-5, 2.5E-5, 4.0E-5, 6.3E-5, 1.E-4, 1.6E-4, 2.5E-4, 4.0E-4, 6.3E-4, 1.E-3, 1.6E-3, 2.5E-3, 4.0E-3, 6.3E-3, 1.E-2, 1.6E-2, 2.5E-2, 4.0E-2, 6.3E-2, .1, .2, .3, .4, .5, .6, .7, .8, .9, 1.0]) if not isHalf: Mesh[46:] = 2*Mesh[45] - Mesh[0:45][::-1] Mesh[:] /= 2 return Mesh else : return Mesh[:46] self.setUniform() def setUniform(self, Te=1E4, Vt=5.E5, Ne=1E10, Pg=5E-1, Vd=0.E5): r""" set all parameters uniform across the space Parameters ---------- Te : np.double temparature, [:math:`K`] Vt : np.double turbulent velocity, [:math:`cm \cdot s^{-1}`] Ne : np.double electron density, [:math:`cm^{-3}`] Pg : np.double gas pressure, [:math:`Ba = g \cdot cm^{-1} \cdot s^{-2}`] Vd : np.double line of sight Doppler velocity, [:math:`cm \cdot s^{-1}`] """ self.data.Te[:] = Te self.data.Vt[:] = Vt self.data.Ne[:] = Ne self.data.Pg[:] = Pg self.data.Vd[:] = Vd def __repr__(self): S = "----------------------------------------\n" S+= "1D Cartesian Atmosphere \n" S+= "----------------------------------------\n" S+= "Z : {0:<.3e} km \n".format(self.Scale[0]*1E-5) S+= "#Depth : {0:<3d} \n".format(self.data.size) S+= "isHalf : {} \n".format(self.isHalf) S+= "----------------------------------------\n" return S def __str__(self): return self.__repr__()
if __name__=='__main__': pass #pwd = './' #atmos = AtmosphereC1d(1) #atmos.readBackgroundIntensity(pwd+'data/IntensityData/ASTM_E490+PROM7_HI_CaII.dat')