Source code for pyrt.eos

"""This module provides functions for working with equation of state variables.
"""
import numpy as np
from numpy.typing import ArrayLike
from scipy.constants import Boltzmann
from scipy.integrate import quad


[docs] def column_density(pressure: ArrayLike, temperature: ArrayLike, altitude: ArrayLike) -> np.ndarray: r"""Create the column density from a given grid of equation of state variables, assuming each grid point can be hydrostatically approximated. Parameters ---------- pressure: ArrayLike The 1-dimensional pressure [Pa] of the grid. temperature: ArrayLike The 1-dimensional temperature [K] of the grid. altitude: ArrayLike The 1-dimensional altitude [m] of each point in the grid. It must be monotonically decreasing, otherwise this function will give nonsense. Returns ------- The column density [:math:`\frac{\text{particles}}{m^2}`] of each point in the vertical column. Notes ----- This function assumes the ideal gas law applies to each point in the grid. Additionally, it linearly interpolates each grid point vertically so that it can do the vertical integration, which may or may not be desirable if the pressure varies exponentially. The finer the vertical resolution, the more accurate this function will be. Examples -------- Get the column density of each 1 km layer of an 80-boundary atmosphere representing Mars where the surface pressure is 600 Pa, the temperature is 180 K everywhere, and the scale height is 10 km. >>> import numpy as np >>> from scipy.constants import Boltzmann >>> import pyrt >>> altitude = np.linspace(80000, 0, num=81) >>> pressure = 600 * np.exp(-altitude / 10000) >>> temperature = np.ones((81,)) * 180 >>> colden = column_density(pressure, temperature, altitude) >>> colden.shape (80,) Get the column-integrated column density. >>> total_colden = np.sum(colden) >>> f'{total_colden:.2e}' '2.42e+27' Compute the analytical result of this scenario. >>> analytical_result = 600 * 10000 * (1 - np.exp(-80000/10000)) / 180 / Boltzmann >>> f'{analytical_result:.2e}' '2.41e+27' """ pressure = np.flip(np.asarray(pressure)) temperature = np.flip(np.asarray(temperature)) altitude = np.flip(np.asarray(altitude)) def hydrostatic_profile(alt): return linear_grid(alt, pressure) / linear_grid(alt, temperature) / \ Boltzmann def linear_grid(alt, grid): return np.interp(alt, altitude, grid) n = [quad(hydrostatic_profile, altitude[i], altitude[i + 1])[0] for i in range(len(altitude) - 1)] return np.flip(np.array(n))
[docs] def scale_height(temperature: ArrayLike, mass: ArrayLike, gravity: float) -> np.ndarray: r"""Compute the scale height of each model layer. Parameters ---------- temperature: ArrayLike The 1-dimensional temperature [K] of the grid. mass: ArrayLike The 1-dimensional particle mass [kg] of the grid. gravity: float The gravitational acceleration [:math:`\frac{m}{s^2}`]. Returns ------- The scale height [m] in each model layer. Examples -------- Get the scale height of Mars's atmosphere, where the temperature is 210 K. Note the atmosphere is primarily carbon dioxide and the gravitational acceleration is 3.71 :math:`\frac{m}{s^2}`. >>> import numpy as np >>> from scipy.constants import m_u >>> import pyrt >>> int(np.rint(pyrt.scale_height(210, 44*m_u, 3.71))) 10696 """ return Boltzmann * temperature / (mass * gravity)