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

> Learn how ExoJAX's AmpAmcloud class models cloud properties using the Ackerman & Marley (2001) framework. Understand particle size distributions and mixing ratios.

- Repository: [Hajime Kawahara/exojax](https://github.com/hajimekawahara/exojax)
- Tags: internals
- Published: 2026-03-03

---

**ExoJAX models cloud properties using the `AmpAmcloud` class in [`src/exojax/atm/atmphys.py`](https://github.com/hajimekawahara/exojax/blob/main/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`](https://github.com/hajimekawahara/exojax/blob/main/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`](https://github.com/hajimekawahara/exojax/blob/main/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`](https://github.com/hajimekawahara/exojax/blob/main/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`](https://github.com/hajimekawahara/exojax/blob/main/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:

```python
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`](https://github.com/hajimekawahara/exojax/blob/main/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`](https://github.com/hajimekawahara/exojax/blob/main/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`](https://github.com/hajimekawahara/exojax/blob/main/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`](https://github.com/hajimekawahara/exojax/blob/main/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`](https://github.com/hajimekawahara/exojax/blob/main/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.