Module diskchef.physics.parametrized
Expand source code
from collections import namedtuple
from dataclasses import dataclass
from typing import List, Union
import numpy as np
from astropy import units as u
from diskchef.physics.base import PhysicsModel
@dataclass
class ParametrizedPhysics(PhysicsModel):
"""Base class for all parameter-based physics"""
pass
_PowerLawPiece = namedtuple("PowerLawPiece", ["r_in", "r_out", "slope", "value_1au"])
@u.quantity_input
def powerlawpiece(
r_in: u.au, r_out: u.au,
slope: float, value_1au: u.Quantity
):
"""
Return namedtuple with parameter for a piece power law with astropy units
Args:
r_in: inner radius (if r < r_in: return 0), in astropy.units length
r_out: outer radius (if r > r_out: return 0), in astropy.units length
slope: slope of the power law
value_1au: value at r == 1 au
"""
slope = float(slope)
return _PowerLawPiece(r_in=r_in, r_out=r_out, slope=slope, value_1au=value_1au)
class PieceWisePowerLaw:
def __init__(self, pieces: Union[List[_PowerLawPiece], List[List]]):
"""
Callable class that returns a piecewise power law profile
Args:
pieces: list of PowerLawPiece(r_in, r_out, slope, value_1au)
"""
try:
self.unit = pieces[0][-1].unit
except AttributeError:
self.unit = u.dimensionless_unscaled
self.pieces = [
piece if isinstance(piece, _PowerLawPiece)
else powerlawpiece(
*piece[:-1],
(piece[-1] * u.dimensionless_unscaled).to(self.unit))
for piece in pieces
]
@u.quantity_input
def __call__(self, r: u.au):
out = np.zeros(r.shape) * self.unit
for piece in self.pieces:
mask = (r >= piece.r_in) & (r < piece.r_out)
out[mask] += piece.value_1au * np.power(
(r[mask].to(u.au) / u.au).value,
piece.slope)
return out
@dataclass
class PowerLawPhysics(ParametrizedPhysics):
"""Class that outputs a physical model of the disk built as a collection of power laws"""
column_density_profile: PieceWisePowerLaw = PieceWisePowerLaw(
[[0.1 * u.au, 500 * u.au, -1.5, 100 * u.g / u.cm ** 2]]
)
midplane_temperature_profile: PieceWisePowerLaw = PieceWisePowerLaw(
[[0.1 * u.au, 500 * u.au, -2, 100 * u.K]]
)
flaring_power: float = 1.26
scale_hight_1au = 0.106 * u.au
@u.quantity_input
def density_scalehight(self, r: u.au) -> u.au:
"""Density scalehight of a flared disk from
Pierre-Olivier Lagage1,*, Coralie Doucet1, Eric Pantin1, Emilie Habart2, Gaspard Duchêne3, François Ménard3, Christophe Pinte3, Sébastien Charnoz1, Jan-Willem Pel4,5
Science 27 Oct 2006:
Vol. 314, Issue 5799, pp. 621-623
DOI: 10.1126/science.1131436
default is 0.106 * r ** 1.26
"""
return self.scale_hight_1au * (r / u.au) ** self.flaring_power
@u.quantity_input(r=u.au, z=u.au)
def gas_density(self, r, z) -> u.g / u.cm ** 3:
"""Calculates gas density at given r, z
Assumes the PieceWisePowerLaw column density profile
gaussian-scaled with the density scalehight
"""
density_scalehight = self.density_scalehight(r)
return (
self.column_density_profile(r) /
np.sqrt(2 * np.pi) / density_scalehight *
np.exp(-z ** 2 / 2 / density_scalehight ** 2)
)
@u.quantity_input(r=u.au, z=u.au)
def dust_temperature(self, r, z) -> u.K:
"""Calculates dust temperature at given r, z"""
return self.midplane_temperature_profile(r)
Functions
def powerlawpiece(r_in: Unit("AU"), r_out: Unit("AU"), slope: float, value_1au: astropy.units.quantity.Quantity)
-
Return namedtuple with parameter for a piece power law with astropy units
Args
r_in
- inner radius (if r < r_in: return 0), in astropy.units length
r_out
- outer radius (if r > r_out: return 0), in astropy.units length
slope
- slope of the power law
value_1au
- value at r == 1 au
Expand source code
@u.quantity_input def powerlawpiece( r_in: u.au, r_out: u.au, slope: float, value_1au: u.Quantity ): """ Return namedtuple with parameter for a piece power law with astropy units Args: r_in: inner radius (if r < r_in: return 0), in astropy.units length r_out: outer radius (if r > r_out: return 0), in astropy.units length slope: slope of the power law value_1au: value at r == 1 au """ slope = float(slope) return _PowerLawPiece(r_in=r_in, r_out=r_out, slope=slope, value_1au=value_1au)
Classes
class ParametrizedPhysics (star_mass: Unit("solMass") = <Quantity 1. solMass>, xray_plasma_temperature: Unit("K") = <Quantity 10000000. K>, xray_luminosity: Unit("erg / s") = <Quantity 1.e+31 erg / s>, cr_padovani_use_l: bool = False, r_min: Unit("AU") = <Quantity 0.1 AU>, r_max: Unit("AU") = <Quantity 500. AU>, zr_max: float = 0.7, radial_bins: int = 100, vertical_bins: int = 100, dust_to_gas: float = 0.01)
-
Base class for all parameter-based physics
Expand source code
@dataclass class ParametrizedPhysics(PhysicsModel): """Base class for all parameter-based physics""" pass
Ancestors
Subclasses
Class variables
var dust_to_gas : float
var r_max : Unit("AU")
var r_min : Unit("AU")
var radial_bins : int
var vertical_bins : int
var zr_max : float
Inherited members
class PieceWisePowerLaw (pieces: Union[List[diskchef.physics.parametrized.PowerLawPiece], List[List]])
-
Callable class that returns a piecewise power law profile
Args
pieces
- list of PowerLawPiece(r_in, r_out, slope, value_1au)
Expand source code
class PieceWisePowerLaw: def __init__(self, pieces: Union[List[_PowerLawPiece], List[List]]): """ Callable class that returns a piecewise power law profile Args: pieces: list of PowerLawPiece(r_in, r_out, slope, value_1au) """ try: self.unit = pieces[0][-1].unit except AttributeError: self.unit = u.dimensionless_unscaled self.pieces = [ piece if isinstance(piece, _PowerLawPiece) else powerlawpiece( *piece[:-1], (piece[-1] * u.dimensionless_unscaled).to(self.unit)) for piece in pieces ] @u.quantity_input def __call__(self, r: u.au): out = np.zeros(r.shape) * self.unit for piece in self.pieces: mask = (r >= piece.r_in) & (r < piece.r_out) out[mask] += piece.value_1au * np.power( (r[mask].to(u.au) / u.au).value, piece.slope) return out
class PowerLawPhysics (star_mass: Unit("solMass") = <Quantity 1. solMass>, xray_plasma_temperature: Unit("K") = <Quantity 10000000. K>, xray_luminosity: Unit("erg / s") = <Quantity 1.e+31 erg / s>, cr_padovani_use_l: bool = False, r_min: Unit("AU") = <Quantity 0.1 AU>, r_max: Unit("AU") = <Quantity 500. AU>, zr_max: float = 0.7, radial_bins: int = 100, vertical_bins: int = 100, dust_to_gas: float = 0.01, column_density_profile: PieceWisePowerLaw = <diskchef.physics.parametrized.PieceWisePowerLaw object>, midplane_temperature_profile: PieceWisePowerLaw = <diskchef.physics.parametrized.PieceWisePowerLaw object>, flaring_power: float = 1.26)
-
Class that outputs a physical model of the disk built as a collection of power laws
Expand source code
@dataclass class PowerLawPhysics(ParametrizedPhysics): """Class that outputs a physical model of the disk built as a collection of power laws""" column_density_profile: PieceWisePowerLaw = PieceWisePowerLaw( [[0.1 * u.au, 500 * u.au, -1.5, 100 * u.g / u.cm ** 2]] ) midplane_temperature_profile: PieceWisePowerLaw = PieceWisePowerLaw( [[0.1 * u.au, 500 * u.au, -2, 100 * u.K]] ) flaring_power: float = 1.26 scale_hight_1au = 0.106 * u.au @u.quantity_input def density_scalehight(self, r: u.au) -> u.au: """Density scalehight of a flared disk from Pierre-Olivier Lagage1,*, Coralie Doucet1, Eric Pantin1, Emilie Habart2, Gaspard Duchêne3, François Ménard3, Christophe Pinte3, Sébastien Charnoz1, Jan-Willem Pel4,5 Science 27 Oct 2006: Vol. 314, Issue 5799, pp. 621-623 DOI: 10.1126/science.1131436 default is 0.106 * r ** 1.26 """ return self.scale_hight_1au * (r / u.au) ** self.flaring_power @u.quantity_input(r=u.au, z=u.au) def gas_density(self, r, z) -> u.g / u.cm ** 3: """Calculates gas density at given r, z Assumes the PieceWisePowerLaw column density profile gaussian-scaled with the density scalehight """ density_scalehight = self.density_scalehight(r) return ( self.column_density_profile(r) / np.sqrt(2 * np.pi) / density_scalehight * np.exp(-z ** 2 / 2 / density_scalehight ** 2) ) @u.quantity_input(r=u.au, z=u.au) def dust_temperature(self, r, z) -> u.K: """Calculates dust temperature at given r, z""" return self.midplane_temperature_profile(r)
Ancestors
Class variables
var column_density_profile : PieceWisePowerLaw
var flaring_power : float
var midplane_temperature_profile : PieceWisePowerLaw
var scale_hight_1au
Methods
def density_scalehight(self, r: Unit("AU")) ‑> Unit("AU")
-
Density scalehight of a flared disk from Pierre-Olivier Lagage1,*, Coralie Doucet1, Eric Pantin1, Emilie Habart2, Gaspard Duchêne3, François Ménard3, Christophe Pinte3, Sébastien Charnoz1, Jan-Willem Pel4,5
Science 27 Oct 2006: Vol. 314, Issue 5799, pp. 621-623 DOI: 10.1126/science.1131436
default is 0.106 * r ** 1.26
Expand source code
@u.quantity_input def density_scalehight(self, r: u.au) -> u.au: """Density scalehight of a flared disk from Pierre-Olivier Lagage1,*, Coralie Doucet1, Eric Pantin1, Emilie Habart2, Gaspard Duchêne3, François Ménard3, Christophe Pinte3, Sébastien Charnoz1, Jan-Willem Pel4,5 Science 27 Oct 2006: Vol. 314, Issue 5799, pp. 621-623 DOI: 10.1126/science.1131436 default is 0.106 * r ** 1.26 """ return self.scale_hight_1au * (r / u.au) ** self.flaring_power
def gas_density(self, r, z) ‑> Unit("g / cm3")
-
Calculates gas density at given r, z
Assumes the PieceWisePowerLaw column density profile gaussian-scaled with the density scalehight
Expand source code
@u.quantity_input(r=u.au, z=u.au) def gas_density(self, r, z) -> u.g / u.cm ** 3: """Calculates gas density at given r, z Assumes the PieceWisePowerLaw column density profile gaussian-scaled with the density scalehight """ density_scalehight = self.density_scalehight(r) return ( self.column_density_profile(r) / np.sqrt(2 * np.pi) / density_scalehight * np.exp(-z ** 2 / 2 / density_scalehight ** 2) )
Inherited members