Cloud and aerosol optics
Cloud and aerosol optics are separate stages: they fill their own containers, which are then composed onto gas optical properties before the solver runs. This keeps gas optics, cloud optics, and solvers independently testable.
Containers
CloudOpticsstores grid-mean layer cloud optical depths: longwave absorption, shortwave absorption, shortwave scattering, and the shortwave scattering asymmetry factor.CloudyRegionCloudOpticsstores the same channels for the cloudy region only, withcloud_fractionandoverlap_parametercarried separately. This matches the all-sky solver convention: cloud cover must not be encoded by weakening in-cloud optical depth.AerosolOpticsmirrors the cloud container for aerosols.
Layer models
LayerCloudOpticsModel converts a condensed water path CWP (kg m⁻²; scalar, per-layer vector, or read from atmosphere.cloud_water_path) with mass absorption/extinction coefficients (m² kg⁻¹):
\[\tau^\mathrm{lw} = \kappa^\mathrm{lw}\,\mathrm{CWP}, \qquad \tau^\mathrm{sw}_\mathrm{absorption} = (1 - \omega)\,\kappa^\mathrm{sw}\,\mathrm{CWP}, \qquad \tau^\mathrm{sw}_\mathrm{scattering} = \omega\,\kappa^\mathrm{sw}\,\mathrm{CWP}.\]
LayerLiquidIceCloudOpticsModel keeps liquid water path, ice water path, and cloud fraction separate, with per-phase coefficients, albedos, and asymmetry factors. It fills either container:
cloud_optical_properties!returns grid-mean optical depth (scaled by cloud fraction raised tocloud_fraction_exponent) — the shortcut for homogeneous-column smoke tests;cloudy_region_optical_properties!fills cloudy-region optical depths without cloud-fraction scaling, plus the fraction and overlap fields, for the all-sky solvers.
LayerAerosolOpticsModel is the aerosol analogue driven by aerosol_path.
Composition onto gas optics
add_cloud_optical_depths! and add_aerosol_optical_depths! add the layer absorption channels to the gas absorption arrays (broadcast across g-points when the gas optics are spectral) and mix the scattering channel into the shortwave scattering optical depth, updating the asymmetry factor as a scattering-optical-depth-weighted mean. After composition, the shortwave solver sees a single absorption/scattering/asymmetry triple per layer and g-point, and needs no cloud-specific logic.
Scattering tables
For spectrally resolved cloud optics, the package reads ecRad's droplet and ice scattering tables and maps them onto ecCKD g-point grids:
CloudScatteringTablestores mass extinction, single-scattering albedo, and asymmetry factor as functions of wavenumber (cm⁻¹) and effective radius (m), read byread_cloud_scattering_table(requires the NCDatasets extension). The reference files are the Mie liquid-droplet and Baum ice tables from the pinned ecRad data artifact.EcCKDSpectralMappingstores the resolved spectral intervals and thegpoint_fractionmatrix from a CKD-definition file — ecCKD's fixed wavenumber-to-g mapping — read byread_ecckd_spectral_mapping. Interval weights are the solar spectral irradiance (shortwave) or a Planck weight (longwave).
cloud_scattering_properties interpolates a table linearly in effective radius at one wavenumber index. cloud_scattering_gpoint_properties produces per-g-point mass extinction, single-scattering albedo, and asymmetry: extinction is weight-averaged, single-scattering albedo extinction-weighted, and asymmetry scattering-weighted. Two mapping methods are available: :midpoint samples the nearest table wavenumber at each interval midpoint, while :ecrad reproduces ecRad's spectral averaging matrix; optional delta-Eddington and optically-thick averaging follow ecRad's conventions.
add_mapped_cloud_scattering! then puts per-g-point liquid and ice scattering into (Ng, Nz) shortwave optical properties from layer liquid/ice water paths and cloud fraction, with optional delta-Eddington forward-scattering scaling.