Source code for amoeba.Classes.blr_streamline

import numpy as np
from astropy import units as u
from astropy import constants as const


[docs]class Streamline: def __init__( self, launch_radius, launch_theta, max_height, characteristic_distance, asymptotic_poloidal_velocity, height_step=10, launch_height=1, poloidal_launch_velocity=1e-3, alpha_acceleration_value=1, velocity_vector=None, radial_vector=None, ): """Object that carries information about the position and velocity of (in)outflowing material. These get added to the BLR or Torus object to define boundaries of line emitting or obscuring material, respectively. velocity model follows Yong et al. 2017, such that in the poloidal direction: v = v_0 + (v_asy - v_0) (r^alpha / (r^alpha + 1)) with: v = outflowing velocity v_0 = initial (launch_velocity) v_asy = asymptotic velocity r = l / R_v l = poloidal distance R_v = characteristic distance alpha = power law index that determines acceleraton of wind :param launch_radius: position radius of the streamline in R_g :param launch_theta: launch angle of the streamline in degrees. Note that zero degrees is normal to the accretion disk. Also, must be positive and less than 90 degrees. :param max_height: maximum height of the BLR in units R_g :param characteristic_distance: a measure of how quickly the asymptotic velocity is reached, in R_g. This is the value of R_v in above equation :param asymptotic_poloidal_velocity: maximum velocity attained by the streamline when l -> inf. This is v_asy in the equation. Must be normalized units w.r.t. the speed of light :param height_step: resolution of the BLR in the Z direction, in R_g :param launch_height: Z coordinate of the origin in R_g. Should be greater than zero to avoid divide by zero errors. :param poloidal_launch_velocity: speed at which material at the base of the streamline starts at. This is parameter v_0 in the above equation. Must be normalized units w.r.t. the speed of light :param alpha_acceleration_value: Power law index which determines acceleration. This is alpha in the equation, and must be positive. :param velocity_vector: an optional list which may be used to input any user defined velocities, as opposed to using the equation above. Must be 1 dimensional of length (max_height // height_step) :param radial_vector: an optional list which may be used to input any user defined radial coordinates, as opposed to assuming a straight line in R-Z coordinates. Must be the same length of velocity_vector, and must be in units R_g. """ self.launch_radius = launch_radius self.launch_height = launch_height self.poloidal_launch_velocity = poloidal_launch_velocity self.height_step = height_step self.poloidal_launch_velocity = poloidal_launch_velocity self.asymptotic_poloidal_velocity = asymptotic_poloidal_velocity self.max_height = max_height assert abs(poloidal_launch_velocity) >= 0 and abs(poloidal_launch_velocity) < 1 assert launch_radius > 1 assert launch_theta < 90 and launch_theta >= 0 self.launch_theta = launch_theta * np.pi / 180 self.radial_launch_velocity = poloidal_launch_velocity * np.sin( self.launch_theta ) assert abs(asymptotic_poloidal_velocity) < 1 length = max_height // height_step + 1 self.height_values = np.linspace(0, max_height, length) if velocity_vector is not None: if radial_vector is not None: assert len(radial_vector) == len(velocity_vector) assert len(radial_vector) == length self.radii_values = radial_vector else: vector = np.linspace( launch_radius, max_height * np.tan(self.launch_theta) + launch_radius, length, ) self.radii_values = vector self.poloidal_velocity = velocity_vector else: vector = np.zeros(length) for jj in range(length): if jj * self.height_step >= launch_height: pol_position = ( ((jj + 0.5) * height_step * np.tan(self.launch_theta)) ** 2 + (((jj + 0.5) * height_step) ** 2) ) ** 0.5 vector[jj] = self.poloidal_launch_velocity + ( self.asymptotic_poloidal_velocity - self.poloidal_launch_velocity ) * ( (pol_position / characteristic_distance) ** alpha_acceleration_value / ( (pol_position / characteristic_distance) ** alpha_acceleration_value + 1 ) ) self.poloidal_velocity = vector vector = np.zeros(length) for jj in range(length): if jj > 0: vector[jj] = ( self.poloidal_velocity[jj] - self.poloidal_velocity[jj - 1] ) / self.poloidal_velocity[jj] else: vector[jj] = ( self.poloidal_velocity[jj + 1] - self.poloidal_velocity[jj] ) / self.poloidal_velocity[jj + 1] self.dpol_vel_dz_on_vel = vector if radial_vector is not None: self.radii_values = radial_vector else: vector = np.linspace( launch_radius, max_height * np.tan(self.launch_theta) + launch_radius, length, ) self.radii_values = vector