Go to notebook file

[1]:

%reload_ext eradiate.notebook.tutorials


Last updated: 2022-10-05 13:34 (eradiate v0.22.4.post102+g84ef86b.d20221005)

# Molecular atmosphere basics#

Overview

In this tutorial, we introduce Eradiate’s molecular atmosphere simulation features.

Prerequisites

What you will learn

• How to configure a standard 1D atmospheric profile.

• How to rescale the atmospheric composition of standard profiles to fit more current data.

## Importing modules#

We start by importing the eradiate, numpy and matplotlib.pyplot modules. Additionally, we load the Eradiate IPython extension for a smoother notebook experience.

[2]:

%load_ext eradiate
import numpy as np
import matplotlib.pyplot as plt


We also import the MolecularAtmosphere class and alias the unit registry for convenience:

[3]:

from eradiate.scenes.atmosphere import MolecularAtmosphere
from eradiate import unit_registry as ureg


We will perform simulations in narrow bands using Eradiate’s correlated-k distribution mode (ckd). There is indeed little point performing monochromatic simulations, at least in this tutorial: running such simulations to compute the signal recorded for a given spectral band is very costly, and the CKD method brings in a significant speed-up.

[4]:

eradiate.set_mode("ckd")


## Creating a standard molecular atmosphere#

The most obvious way to configure a molecular atmospheric profile would be to call the MolecularAtmosphere constructor; however, proper initialisation of standard profiles is supposed to be done using specialised class method constructors. In CKD mode, the AFGL 1986 reference atmospheres [ACC+86] are supported and created using the MolecularAtmosphere.afgl_1986() class method:

[5]:

us_standard_atmosphere = MolecularAtmosphere.afgl_1986()


We just instantiated an molecular atmosphere object with default parameters. It notably uses the “U.S. Standard” reference atmospheric profile, default molecular density values and discretises the atmosphere vertically in 120 1 km-thick layers:

[6]:

us_standard_atmosphere

MolecularAtmosphere(
id='atmosphere',
geometry=None,
scale=None,
_thermoprops=<xarray.Dataset>
Dimensions:  (z_level: 121, z_layer: 120, species: 7)
Coordinates:
* z_level  (z_level) float64 0.0 1.0 2.0 3.0 4.0 ... 117.0 118.0 119.0 120.0
* z_layer  (z_layer) float64 0.5 1.5 2.5 3.5 4.5 ... 116.5 117.5 118.5 119.5
* species  (species) object 'H2O' 'O3' 'N2O' 'CO' 'CH4' 'CO2' 'O2'
Data variables:
p        (z_layer) float64 9.559e+04 8.469e+04 ... 0.002981 0.002687
t        (z_layer) float64 284.9 278.4 271.9 265.4 ... 330.0 342.0 354.0
n        (z_layer) float64 2.43e+25 2.203e+25 ... 6.486e+17 5.571e+17
mr       (species, z_layer) float64 0.00691 0.00535 ... 0.07895 0.07465
Attributes:
convention:  CF-1.8
title:       AFGL (1986) U.S. Standard atmosphere thermophysical properties
history:     2021-05-19 17:37:17 - data creation - shicho.afgl86.make_dat...
source:      Atmospheric model (U.S. Standard Atmosphere) adapted from sa...
references:  Anderson, G.P. and Chetwynd J.H. and Clough S.A. and Shettle...
comment:     raw data was linearly interpolated on a regular layer altitu...
identifier:  afgl_1986-us_standard,
phase=RayleighPhaseFunction(id='phase_atmosphere'),
has_absorption=True,
has_scattering=True,
absorption_data_sets=None
)


Eradiate supports the 6 AFGL reference atmospheres (see the MolecularAtmosphere.afgl_1986() API documentation for the complete list). We can visualise the pressure and temperature profiles:

[7]:

def show_profile(*atmospheres, labels=None):
from matplotlib.ticker import ScalarFormatter

if labels is None:
label_iter = iter([None for _ in atmospheres])
else:
label_iter = iter(labels)

fig, axs = plt.subplots(1, 2, sharey=True)

for atmosphere in atmospheres:

with plt.rc_context({"lines.linestyle": ":", "lines.marker": "."}):
temperature.plot(y="z_layer", ax=axs[0])
pressure.plot(y="z_layer", ax=axs[1], label=next(label_iter))

formatter = ScalarFormatter(useMathText=True)
formatter.set_powerlimits((-3,2))
axs[1].xaxis.set_major_formatter(formatter)
axs[1].set_ylabel("")

if labels is not None:
fig.legend(
bbox_to_anchor=(1.0, 0.5),
loc="center left",
)

plt.tight_layout()
plt.show()
plt.close()

show_profile(us_standard_atmosphere)


The reference atmosphere is controlled by the model parameter. For instance, the Midlatitude Summer reference atmosphere can be obtained with the midlatitude_summer value. Let’s add it to our plot:

[8]:

midlatitude_summer_atmosphere = MolecularAtmosphere.afgl_1986(
model="midlatitude_summer"
)
show_profile(
us_standard_atmosphere,
midlatitude_summer_atmosphere,
labels=["U.S. Standard", "Midlatitude Summer"],
)


## Changing the altitude grid#

The altitude grid can be specified manually using the levels parameter. To change the number of levels to 26 (25 layers) and have the profile extend between 0 and 100 km, we simply have to write:

[9]:

us_standard_atmosphere_custom = MolecularAtmosphere.afgl_1986(
model="us_standard",
levels=np.linspace(0, 100, 26) * ureg.km,
)

[10]:

show_profile(us_standard_atmosphere_custom)


tutorials/getting_started/molecular_atmosphere.ipynb## Rescaling species concentration values

Arguably, reference atmospheric profiles are not always appropriate. In particular, the chemical composition of the atmosphere significantly varies as a function of time and location. Eradiate can vary reference profiles by rescaling species concentrations to account for the effects of a changing atmospheric composition. This is done using the concentrations parameter. The following example varies the U.S. Standard atmosphere by setting:

• the column mass density of water vapour to 15 kg / m²,

• the volume mixing ratio of CO₂ at sea level to 400 ppm,

• the column number density of O₃ to 350 Dobson units.

[11]:

us_standard_atmosphere_custom = MolecularAtmosphere.afgl_1986(
model="us_standard",
concentrations={
"H2O": 15.0 * ureg.kg / ureg.m ** 2,  # column mass density
"CO2": 400e-6 * ureg.dimensionless,  # volume mixing fraction at sea level
"O3": 350.0 * ureg.dobson_units,  # column number density
},
)


## Disabling absorption or scattering#

The absorption or scattering coefficient can be forced to 0 using the has_absorption and has_scattering switches. The following atmosphere definition has no absorption, only Rayleigh scattering:

[12]:

rayleigh_atmosphere = MolecularAtmosphere.afgl_1986(
has_absorption=False, has_scattering=True
)


## What about the monochromatic mode?#

In mono mode, the AFGL 1986 atmospheric profiles are not supported. We provide instead the simpler U.S. Standard Atmosphere (1976) [NNU76], which lacks many species contributing to radiative processes. This profile is accessed using the MolecularAtmosphere.ussa_1976() class method:

[13]:

us76_atmosphere = MolecularAtmosphere.ussa_1976()


Profile customisation options are similar to those of the AFGL 1986 profiles.

## Final words#

The various instantiation and customisation options we explored in this tutorial can be used in all the experiments supporting 1D atmospheric profiles.