How ExoJAX's Atmospheric Microphysics (AMP) Class Models Cloud Properties

ExoJAX models cloud properties using the AmpAmcloud class in src/exojax/atm/atmphys.py, which implements the Ackerman & Marley (2001) cloud model to compute particle size distributions and condensate mixing ratios through a sedimentation-diffusion balance framework.

The ExoJAX open-source library provides a fully differentiable atmospheric modeling toolkit for exoplanet spectroscopy. Its Atmospheric Microphysics (AMP) subsystem specifically handles the vertical distribution of cloud condensates and particle sizes according to the hajimekawahara/exojax source code. The implementation centers on the AmpAmcloud class, which translates atmospheric temperature-pressure profiles into measurable cloud properties using the Ackerman & Marley (2001) formalism.

Architecture of the AMP Class Hierarchy

The AMP implementation uses a two-layer class structure defined in src/exojax/atm/atmphys.py.

  • AmpCloud (lines 23–58): The base class holds common attributes including cloudmodel, bkgatm (background atmosphere), and helper methods for temperature-range checks and dynamic viscosity. It initializes the logarithmically spaced condensate size grid via set_condensates_scale_array(size_min, size_max, nsize), which constructs self.rcond_arr in centimeters.
  • AmpAmcloud (lines 59–178): The derived class implements the Ackerman & Marley (2001) physics. It instantiates with a particulate database (pdb, typically PdbCloud) and computes the specific microphysical profiles.

During initialization, the class stores the condensate database and prepares the radius grid used for terminal velocity calculations across the atmospheric column.

Core Cloud Physics Implementation

The high-level entry point calc_ammodel (lines 73–86) returns two critical outputs used in radiative transfer:

  1. rg: The median radius of the log-normal particle size distribution (cm).
  2. MMR_condensate: The vertical profile of condensate mass mixing ratio.

This method delegates the physics computation to calc_ammodel_rw, which executes the following vectorized pipeline:

  1. Density difference: Computes drho as condensate_density – gas_density using the ideal gas law (lines 44–47).
  2. Saturation pressure: Calls self.pdb.saturation_pressure(temperatures) to obtain species-specific vapor pressure curves (line 49).
  3. Cloud-base identification: Uses smooth_index_base_pressure and get_pressure_at_cloud_base to locate the altitude where saturation equals the partial pressure of the condensate (lines 52–57).
  4. Cloud scale height: Calculates L_cloud via pressure_scale_height(gravity, T_base, μ) from atmprof.py (lines 58–61).
  5. Dynamic viscosity: Computes eta_dvisc through self.dynamic_viscosity(temperatures), which internally uses calc_vfactor and eta_Rosner (line 63).
  6. Terminal velocity: Vectorizes terminal_velocity across self.rcond_arr using vmap for JAX compatibility (lines 66–68).
  7. Condensate size rw: Calls find_rw to locate the radius where sedimentation balances eddy diffusion (vterminal = Kzz / L_cloud) (lines 70–72).
  8. Mixing ratio profile: Constructs MMR_condensate via mixing_ratio_cloud_profile using the sedimentation efficiency parameter fsed and the cloud-base mixing ratio MMR_base (lines 73–76).

The rw parameter represents the equivalent radius in the Ackerman & Marley formalism, which is then converted to the log-normal median radius rg using the relationship defined by the alphav and sigmag shape parameters.

Low-Level Microphysics Utilities

The src/exojax/atm/amclouds.py module contains pure-JAX helper functions that perform the numerical heavy lifting:

  • mixing_ratio_cloud_profile: Implements Equation 12 of Ackerman & Marley (2001) to build the vertical condensate profile from the cloud base upward.
  • get_rg: Converts the equivalent radius rw to the log-normal median radius rg using the power-law relationship from Equations 9 and 13 of AM01.
  • find_rw: Efficiently searches the radius grid to find where terminal_velocity matches the eddy diffusion velocity Kzz/L_cloud.
  • effective_radius and geometric_radius: Provide post-processing options for opacity calculations.

These utilities are decorated with @jit where appropriate and operate on the entire atmospheric column simultaneously via JAX vectorization.

Integration with ExoJAX Databases

The AMP class interacts with two primary data sources:

  • PdbCloud (src/exojax/database/pardb.py): Supplies condensate material properties including condensate_substance_density and temperature-dependent saturation vapor pressure curves. The database is passed during AmpAmcloud initialization as the pdb argument.
  • Background atmosphere (bkgatm): Provides the temperature-pressure profile, mean molecular weight, and gravity required for gas density and viscosity calculations. The background atmosphere object ensures consistency between the cloud microphysics and the bulk atmospheric structure.

The resulting rg and MMR_condensate arrays feed directly into ExoJAX's opacity modules to compute wavelength-dependent cloud extinction.

End-to-End Cloud Modeling Example

The following example demonstrates computing cloud properties for a silicate (MgSiO3) cloud in a planetary atmosphere:

import jax.numpy as jnp
from exojax.atm.atmphys import AmpAmcloud
from exojax.database.pardb import PdbCloud
from exojax.utils.constants import G

# Define atmospheric grid

pressures = jnp.logspace(-5, 2, 150)  # bar

temperatures = jnp.full_like(pressures, 1500.0)  # K

mean_molecular_weight = 2.33  # H2-rich atmosphere

gravity = G * 1e2  # convert m/s^2 to cm/s^2

# Load MgSiO3 condensate database

pdb = PdbCloud('MgSiO3')

# Initialize AMP model

amp = AmpAmcloud(pdb=pdb, bkgatm=None)

# Define cloud parameters

fsed = 2.0  # sedimentation efficiency

sigmag = 2.0  # geometric standard deviation

Kzz = jnp.full_like(pressures, 1e7)  # cm^2/s, eddy diffusion

MMR_base = 1e-4  # mass mixing ratio at cloud base

alphav = 2.0  # log-normal shape factor

# Compute cloud properties

rg, MMR_condensate = amp.calc_ammodel(
    pressures=pressures,
    temperatures=temperatures,
    mean_molecular_weight=mean_molecular_weight,
    molecular_mass_condensate=pdb.molecular_mass,
    gravity=gravity,
    fsed=fsed,
    sigmag=sigmag,
    Kzz=Kzz,
    MMR_base=MMR_base,
    alphav=alphav,
)

print(f"Median radius (rg): {rg:.2e} cm")
print(f"Condensate MMR at base: {MMR_condensate[0]:.2e}")

This workflow initializes the particulate database, instantiates AmpAmcloud, and computes the vertical profiles required for radiative transfer calculations.

Summary

  • AmpAmcloud implements the Ackerman & Marley (2001) cloud model in src/exojax/atm/atmphys.py (lines 59–178).
  • The calc_ammodel method returns the median particle radius rg and the condensate mass mixing ratio MMR_condensate for the full atmospheric column.
  • Core physics in calc_ammodel_rw determines the condensate size rw by balancing terminal velocity against eddy diffusion (Kzz/L_cloud).
  • Helper functions in src/exojax/atm/amclouds.py convert between equivalent and median radii (get_rg) and construct vertical mixing ratio profiles (mixing_ratio_cloud_profile).
  • The entire pipeline is JAX-compatible, enabling automatic differentiation through cloud microphysics for gradient-based atmospheric retrievals.

Frequently Asked Questions

What cloud model does ExoJAX's AMP class implement?

The AmpAmcloud class implements the Ackerman & Marley (2001) cloud model as defined in src/exojax/atm/atmphys.py. This model assumes a steady-state balance between upward eddy diffusion and downward gravitational sedimentation of condensate particles. The implementation computes the cloud base location, vertical extent, and particle size distribution assuming a log-normal distribution of spherical particles.

How does the AMP class determine cloud particle sizes?

The class calculates the representative particle size rw by finding the radius where terminal velocity equals the eddy diffusion velocity (Kzz / L_cloud). This occurs in the find_rw function within src/exojax/atm/amclouds.py, which searches the logarithmically spaced radius grid rcond_arr initialized by set_condensates_scale_array. The resulting rw is then converted to the median radius rg via get_rg using the sigmag and alphav parameters.

What parameters control the cloud properties in ExoJAX?

Key control parameters include the sedimentation efficiency fsed, the eddy diffusion coefficient Kzz, the geometric standard deviation sigmag, and the condensate mass mixing ratio at the cloud base MMR_base. The alphav parameter governs the conversion between the model equivalent radius and the log-normal median radius. These are passed to calc_ammodel along with the atmospheric temperature-pressure profile and gravity.

Can ExoJAX's cloud microphysics be used with automatic differentiation?

Yes, the entire AMP pipeline is implemented in pure JAX using vmap for vectorization and @jit for compilation. All operations in calc_ammodel_rw and the helper utilities in amclouds.py support forward-mode and reverse-mode automatic differentiation. This allows gradient-based optimizers to adjust cloud parameters such as fsed and MMR_base during atmospheric retrieval workflows.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →