Dust evolution in protoplanetary disks
Helper classes and functions for boundary conditions, data handling, and simulation utilities. The utilities module provides essential support functionality for DustPy simulations including boundary condition management, data extraction, and version checking.
Class for managing and applying boundary conditions to simulation quantities.
from dustpy import utils
class utils.Boundary:
"""
Boundary condition management class.
Provides flexible boundary condition specification and application
for simulation variables including constant values, gradients,
and power-law conditions.
"""
def __init__(self, r, ri, S, condition=None, value=None):
"""
Initialize boundary condition object.
Parameters:
- r: Radial grid
- ri: Radial grid cell interfaces
- S: Field on which boundary condition is imposed
- condition: Boundary condition type (optional)
- value: Boundary condition value (optional)
"""
def setcondition(self, condition):
"""
Set the boundary condition type.
Parameters:
- condition: Boundary condition type
- "val": Constant value
- "const_val": Alias for constant value
- "grad": Constant gradient
- "const_grad": Alias for constant gradient
- "pow": Power-law condition
- "const_pow": Alias for power-law condition
"""
def setboundary(self, value):
"""
Set the boundary condition value.
Parameters:
- value: Boundary condition value
For "val"/"const_val": the constant value
For "grad"/"const_grad": the gradient value
For "pow"/"const_pow": the power-law exponent
"""
def __repr__(self):
"""String representation of boundary condition."""
# Properties
condition: str # Current boundary condition type
value: float # Current boundary condition valueFunction for extracting and processing simulation data for analysis and plotting.
def utils.read_data(data, filename="data", extension="hdf5", Na=50):
"""
Extract simulation data for analysis and plotting.
Processes simulation output into a convenient format with
derived quantities and metadata for visualization and analysis.
Parameters:
- data: Simulation object or None (to read from file)
- filename: Data file name (default: "data")
- extension: File extension ("hdf5", "h5", or "dump")
- Na: Number of particle size bins for processing (default: 50)
Returns:
utils.SimpleNamespace: Object containing processed data arrays
- r: Radial grid [cm]
- a: Particle sizes [cm]
- Sigma_gas: Gas surface density [g/cm²]
- Sigma_dust: Dust surface density [g/cm²]
- T: Temperature [K]
- St: Stokes numbers
- v_rad: Radial velocities [cm/s]
- Additional derived quantities for plotting
"""Restricted namespace class that prevents accidental attribute addition.
class utils.SimpleNamespace:
"""
Simple namespace that restricts adding new attributes.
Provides a container for grouped attributes while preventing
accidental addition of new attributes after initialization.
Used throughout DustPy for organizing simulation parameters.
"""
def __init__(self, **kwargs):
"""
Initialize namespace with given keyword arguments.
Parameters:
- kwargs: Initial attributes to set
"""
def __setattr__(self, name, value):
"""Controlled attribute setting."""
def __repr__(self):
"""String representation showing all attributes."""Function for checking and warning about package version updates.
def utils.print_version_warning(timeout=0.5):
"""
Check for package updates and print warnings if outdated.
Queries PyPI to check if a newer version of DustPy is available
and prints a warning message if the current installation is outdated.
Parameters:
- timeout: Request timeout in seconds (default: 0.5)
Returns:
None
Note:
- Requires internet connection to check PyPI
- Fails silently if network request times out
- Called automatically when importing dustpy
"""from dustpy import Simulation, utils
sim = Simulation()
sim.makegrids()
# Set up dust boundary conditions
inner_boundary = utils.Boundary()
inner_boundary.setcondition("val") # Constant value
inner_boundary.setboundary(0.0) # Zero dust influx
outer_boundary = utils.Boundary()
outer_boundary.setcondition("grad") # Constant gradient
outer_boundary.setboundary(0.0) # Zero gradient (closed)
# Apply to dust surface density
sim.dust.boundary.inner = inner_boundary
sim.dust.boundary.outer = outer_boundary# Power-law boundary condition
power_boundary = utils.Boundary()
power_boundary.setcondition("pow")
power_boundary.setboundary(-1.5) # Power-law exponent
# Check boundary condition
print(power_boundary) # Shows condition type and value
# Access boundary properties
condition_type = power_boundary.condition # "pow"
exponent_value = power_boundary.value # -1.5from dustpy import utils
import numpy as np
# Extract data from simulation
sim = Simulation()
# ... run simulation ...
data = utils.read_data(sim)
# Access processed data
radial_grid = data.r # [cm]
particle_sizes = data.a # [cm]
gas_density = data.Sigma_gas # [g/cm²]
dust_density = data.Sigma_dust # [g/cm²]
# Perform analysis
total_gas_mass = np.trapz(gas_density * 2 * np.pi * radial_grid, radial_grid)
total_dust_mass = np.trapz(dust_density * 2 * np.pi * radial_grid, radial_grid)
dust_to_gas = total_dust_mass / total_gas_mass
print(f"Total gas mass: {total_gas_mass:.2e} g")
print(f"Total dust mass: {total_dust_mass:.2e} g")
print(f"Dust-to-gas ratio: {dust_to_gas:.3f}")# Process data from HDF5 file
data_from_file = utils.read_data(None,
filename="simulation_output",
extension="hdf5",
Na=100) # Higher resolution
# Process dump file
data_from_dump = utils.read_data(None,
filename="snapshot_001",
extension="dump")
# Access metadata
print(f"Simulation time: {data_from_file.t}")
print(f"Number of radial points: {len(data_from_file.r)}")
print(f"Number of size bins: {len(data_from_file.a)}")# Create organized parameter groups
initial_conditions = utils.SimpleNamespace(
gas_mass=0.01,
dust_ratio=0.01,
temperature=100,
alpha_turb=1e-3
)
# Access parameters
print(f"Gas mass: {initial_conditions.gas_mass}")
print(f"Dust ratio: {initial_conditions.dust_ratio}")
# Namespace prevents accidental additions
# This would raise an AttributeError:
# initial_conditions.new_param = 5.0from dustpy import utils
# Check for updates (called automatically on import)
utils.print_version_warning()
# With custom timeout
utils.print_version_warning(timeout=2.0) # 2 second timeoutdef setup_custom_boundaries(sim, inner_type="val", outer_type="grad"):
"""Helper function to set up standard boundary conditions."""
# Inner boundary
inner_bc = utils.Boundary()
inner_bc.setcondition(inner_type)
inner_bc.setboundary(0.0)
# Outer boundary
outer_bc = utils.Boundary()
outer_bc.setcondition(outer_type)
outer_bc.setboundary(0.0)
# Apply to simulation
sim.dust.boundary.inner = inner_bc
sim.dust.boundary.outer = outer_bc
sim.gas.boundary.inner = inner_bc
sim.gas.boundary.outer = outer_bc
# Usage
sim = Simulation()
sim.makegrids()
setup_custom_boundaries(sim)
sim.initialize()def analyze_simulation(sim_or_file, filename=None):
"""Complete analysis pipeline for DustPy results."""
# Extract data
if filename:
data = utils.read_data(None, filename=filename, extension="hdf5")
else:
data = utils.read_data(sim_or_file)
# Calculate derived quantities
results = utils.SimpleNamespace(
total_gas_mass=np.trapz(data.Sigma_gas * 2 * np.pi * data.r, data.r),
total_dust_mass=np.trapz(data.Sigma_dust * 2 * np.pi * data.r, data.r),
max_particle_size=np.max(data.a),
drift_barrier_location=data.r[np.argmax(data.St)],
)
results.dust_to_gas_ratio = results.total_dust_mass / results.total_gas_mass
return results
# Use analysis pipeline
results = analyze_simulation(sim)
print(f"Dust-to-gas ratio: {results.dust_to_gas_ratio:.4f}")
print(f"Maximum particle size: {results.max_particle_size:.2e} cm")Install with Tessl CLI
npx tessl i tessl/pypi-dustpy