Air–Sea Interaction¶
The pygotm.airsea package computes the surface boundary conditions for every
physics timestep: wind stress, sensible heat, latent heat, shortwave and longwave
radiation, freshwater flux (precipitation and evaporation), and bottom drag. It is
a direct Python translation of the GOTM Fortran module hierarchy under
gotm-model/code/src/airsea/.
All functions are pure Python (no Numba) and operate on scalar float64 values.
They are called from within the compiled Numba time loop by first extracting the
per-step forcing scalars, computing fluxes, and then passing the results back as
pre-computed arrays.
Modules at a glance¶
Module |
Purpose |
|---|---|
Integration driver: |
|
Shared state object |
|
Dispatcher that routes to Kondo or Fairall bulk flux routines |
|
Kondo (1975) bulk momentum, sensible, and latent heat fluxes |
|
Fairall et al. (1996) COARE bulk fluxes with cool-skin / warm-layer corrections |
|
Saturation vapour pressure, specific humidity, and air density |
|
Net longwave (back-radiation) by six parameterisation methods |
|
Shortwave radiation at the surface (Reed 1977 / Rosati–Miyakoda 1988) |
|
Solar zenith angle from time, longitude, and latitude |
|
Sea-surface albedo (constant, Payne 1972, or Cogley 1979) |
Integration Driver — airsea¶
airsea.py is the entry point called by the GOTM time loop. It owns
AirSeaDriverState, the full air-sea configuration and runtime state, and
exposes the high-level functions do_airsea and surface_fluxes that are
called once per timestep.
Per-timestep sequence executed by do_airsea¶
On each physics timestep the driver performs the following operations in order:
Humidity — calls
humidity()to update saturation vapour pressure at SST (es,qs), actual vapour pressure at air temperature (ea,qa), and moist-air density (rhoa).Shortwave radiation — if
shortwave_methodis not 0, callssolar_zenith_angle()andshortwave_radiation(), then subtracts the reflected fraction viaalbedo_water().Longwave radiation — if
longwave_methodis not 0, callslongwave_radiation()to compute the net back-radiationql.Bulk fluxes — calls
airsea_fluxes()(which dispatches to Kondo or Fairall) to compute evaporation, wind stress \((\tau_x, \tau_y)\), latent heatqe, and sensible heatqh.Net heat flux — assembles
heat = shortwave + longwave + qe + qh.SST observation nudge — optionally overwrites
sstfrom an observational forcing series.
Air-sea flux driver — translation of airsea.F90.
Calculates heat, momentum, and freshwater fluxes between the ocean and the
atmosphere, and the incoming solar radiation. Fluxes and solar radiation may
be prescribed directly or computed from meteorological parameters using bulk
formulae. Albedo correction is applied when shortwave_type == 2.
Public interface: init_airsea(), post_init_airsea(),
do_airsea(), clean_airsea(), set_sst(), set_ssuv(),
surface_fluxes(), integrated_fluxes().
- class pygotm.airsea.airsea.AirSeaDriverState[source]¶
Bases:
AirSeaStateState and configuration for the translated
airsea.F90driver.
- pygotm.airsea.airsea.clean_airsea(state)[source]¶
Finalize the air-sea module.
The translated Phase 4 driver has no open-file resources yet, so this is a no-op.
- Return type:
- Parameters:
state (AirSeaDriverState)
- pygotm.airsea.airsea.do_airsea(state, *, yearday, secs, airp=None, airt=None, hum=None, cloud=0.0, u10=0.0, v10=0.0, precip=0.0, shortwave=None, heat=None, tx=None, ty=None, longwave=None, sst_obs=None)[source]¶
Perform one air-sea update using either bulk formulae or prescribed fluxes.
- Return type:
- Parameters:
- pygotm.airsea.airsea.init_airsea(state, *, overrides=None, **keyword_overrides)[source]¶
Apply scalar configuration overrides to
state.
- pygotm.airsea.airsea.integrated_fluxes(state, dt, *, shortwave=None)[source]¶
Integrate freshwater and heat fluxes over
dtseconds.- Return type:
- Parameters:
state (AirSeaDriverState)
dt (float)
shortwave (float | None)
- pygotm.airsea.airsea.post_init_airsea(state, lat, lon)[source]¶
Reset runtime air-sea state and store latitude/longitude.
- Return type:
- Parameters:
state (AirSeaDriverState)
lat (float)
lon (float)
- pygotm.airsea.airsea.set_sst(state, temp)[source]¶
Set the model sea-surface temperature used by bulk flux calculations.
- Return type:
- Parameters:
state (AirSeaDriverState)
temp (float)
- pygotm.airsea.airsea.set_ssuv(state, uvel, vvel)[source]¶
Set the surface current used to form relative wind speed.
- Return type:
- Parameters:
state (AirSeaDriverState)
uvel (float)
vvel (float)
Bulk Momentum and Heat Flux Schemes¶
Bulk flux dispatcher — airsea_fluxes¶
airsea_fluxes.py is the thin dispatcher that routes to the selected bulk
scheme. It translates airsea_fluxes.F90 and its two selector constants:
Constant |
Value |
Scheme |
|---|---|---|
|
1 |
Kondo (1975) — five wind-speed regimes, stability correction |
|
2 |
Fairall et al. (1996) COARE — Liu–Katsaros–Businger iteration |
All bulk schemes return the tuple (evap, taux, tauy, qe, qh):
Output |
Units |
Description |
|---|---|---|
|
m s⁻¹ |
Evaporation rate (positive upward); non-zero only when |
|
N m⁻² |
Eastward wind stress |
|
N m⁻² |
Northward wind stress |
|
W m⁻² |
Latent heat flux (negative = ocean loses heat) |
|
W m⁻² |
Sensible heat flux (negative = ocean loses heat) |
Dispatcher for air-sea bulk flux calculations — translation of airsea_fluxes.F90.
Routes to either the Kondo (1975) or Fairall et al. (1996) bulk-flux routine
based on the integer method selector. Returns evaporation rate, wind
stress components (taux, tauy), latent heat flux qe, and sensible heat
flux qh. Shortwave and longwave radiation are handled separately by their
own modules.
Kondo (1975) bulk fluxes — kondo¶
Translates kondo.F90. Transfer coefficients \(C_{dd}\), \(C_{hd}\),
and \(C_{ed}\) are selected from five wind-speed regimes (0–2.2, 2.2–5,
5–8, 8–25, and >25 m s⁻¹) and then modified by a bulk Richardson-number
stability correction. Rain impact on sensible heat and wind stress is applied
optionally when state.rain_impact is True.
Latent heat of vaporisation depends on SST:
Stability parameter:
For stable conditions (\(s < 0\)), transfer coefficients are multiplied by \(0.1 + 0.03s + 0.9 e^{4.8s}\) (clamped to zero for \(s < -3.3\)). For unstable conditions (\(s > 0\)), they are multiplied by \(1 + 0.47\sqrt{s}\) (drag) and \(1 + 0.63\sqrt{s}\) (heat/moisture).
Kondo (1975) bulk flux parameterisation — translation of kondo.F90.
Computes transfer coefficients for the surface momentum flux vector \((\tau_x, \tau_y)\) (\(c_{dd}\)), latent heat flux \(Q_e\) (\(c_{ed}\)), and sensible heat flux \(Q_h\) (\(c_{hd}\)) following the Kondo (1975) bulk formulae.
Transfer coefficients are selected from five wind-speed regimes
(0–2.2, 2.2–5, 5–8, 8–25, and >25 m s⁻¹) and then modified by a bulk
Richardson-number stability correction. Rain impact on sensible heat and wind
stress is applied optionally when state.rain_impact is True.
Fairall et al. (1996) COARE bulk fluxes — fairall¶
Translates fairall.F90. Implements the COARE 2.0 algorithm of
Fairall et al. (1996a, b), adapted from the original COARE code by
David Rutgers and Frank Bradley. The algorithm is built on the
Liu–Katsaros–Businger (Liu et al. 1979) roughness Reynolds number method
with up to 20 iterations (_ITERMAX = 20) to converge the Obukhov-length
stability correction.
Key internal parameters:
Parameter |
Value |
Description |
|---|---|---|
|
10.0 m |
Wind reference height |
|
2.0 m |
Temperature and humidity reference heights |
|
600.0 m |
Atmospheric boundary layer height for gustiness |
|
1.2 |
Gustiness coefficient |
|
0.0 m s⁻¹ |
Minimum gustiness wind speed (disabled) |
|
20 |
Maximum Obukhov-length iterations |
The stability function psi() handles both
unstable (zol < 0, Paulson / convective blending) and stable (zol > 0,
linear \(-4.7\,\zeta\)) regimes. For zol >= 0.25 (strongly stable),
bulk fluxes are set to zero and no iteration is performed.
Fairall et al. (1996) COARE bulk fluxes — translation of fairall.F90.
Computes the surface momentum flux vector \((\tau_x, \tau_y)\) [N m⁻²], latent heat flux \(Q_e\) [W m⁻²], and sensible heat flux \(Q_h\) [W m⁻²] according to Fairall et al. (1996a), built on the Liu–Katsaros–Businger (Liu et al. 1979) method. Cool-skin and warm-layer effects follow Fairall et al. (1996b).
Temperature inputs (airt, sst) may be in Celsius or Kelvin; values
above 100 are treated as Kelvin.
Adapted from the COARE code originally written by David Rutgers and Frank Bradley. Original GOTM Python port by Adolf Stips.
Humidity — humidity¶
Translates humidity.F90. Updates AirSeaState with:
es— saturation vapour pressure at SST [Pa] (corrected by factor 0.98 for seawater following Kraus 1972)qs— saturation specific humidity at SST [kg kg⁻¹]ea— actual vapour pressure at air temperature [Pa]qa— actual specific humidity [kg kg⁻¹]rhoa— moist-air density [kg m⁻³]
Saturation vapour pressure is computed from the Lowe (1977) polynomial
(coefficients _A1 … _A7) converted from millibar to Pascal.
Four humidity input methods are supported (gotm.yaml key hum_method):
Method |
Input |
Conversion |
|---|---|---|
1 |
Relative humidity [%] |
\(e_a = (hum/100) \cdot e_\mathrm{sat}(T_a)\) |
2 |
Wet-bulb temperature [°C or K] |
Smithsonian psychrometer formula (Met. Tables 6th ed., p. 366) |
3 |
Dew-point temperature [°C or K] |
\(e_a = e_\mathrm{sat}(T_\mathrm{dew})\) |
4 |
Specific humidity [kg kg⁻¹] |
\(e_a = q_a p / (\varepsilon + 0.378 q_a)\) |
Moist-air density:
where \(\varepsilon = 0.622\) (const06) and \(R_\mathrm{air}\)
is the specific gas constant for dry air (rgas).
Humidity and air-density calculation — translation of humidity.F90.
Updates an AirSeaState object with:
es— saturation vapour pressure at SST [Pa], corrected for seawater salinity (factor 0.98, Kraus 1972).qs— saturation specific humidity at SST [kg kg⁻¹].ea— actual vapour pressure at air temperature [Pa].qa— actual specific humidity [kg kg⁻¹].rhoa— moist-air density [kg m⁻³].
Saturation vapour pressure uses the Lowe (1977, J. Appl. Met.) seven-term polynomial, converted from millibar to Pascal.
Four humidity input methods are supported via hum_method (gotm.yaml
key hum_method):
Relative humidity in percent.
Wet-bulb temperature [°C or K]; psychrometer formula from Smithsonian Meteorological Tables, 6th edition, p. 366, eq. 3.
Dew-point temperature [°C or K].
Specific humidity in kg kg⁻¹ (direct input).
Temperature inputs > 100 are treated as Kelvin; values ≤ 100 as Celsius.
Original FORTRAN authors: Adolf Stips, Hans Burchard, Karsten Bolding.
- pygotm.airsea.humidity.humidity(state, hum_method, hum, airp, tw, ta)[source]¶
Update
statewith humidity variables followinghumidity.F90.- Return type:
- Parameters:
Parameters¶
- state:
Shared air-sea module state updated in place.
- hum_method:
GOTM humidity selector. 1: relative humidity in percent. 2: wet-bulb temperature. 3: dew-point temperature. 4: specific humidity in kg/kg.
- hum:
Humidity input associated with
hum_method.- airp:
Air pressure [Pa].
- tw:
Sea-surface temperature [Celsius].
- ta:
Air temperature [Celsius].
Radiation¶
Longwave radiation — longwave_radiation¶
Translates longwave_radiation.F90. Returns the net longwave (back)
radiation in W m⁻² (sign convention: negative when the ocean loses heat).
Six methods are available, selected by longwave_method (see
Shared State and Constants — airsea_variables for the integer constants):
Method |
Formula summary |
|---|---|
|
\(Q_l = -\varepsilon\sigma[(1-f_{ccf}C^2)T_w^4(0.39-0.05\sqrt{e_a}) + 4T_w^3(T_w-T_a)]\) |
|
As Clark but uses \(0.056\sqrt{1000\,q_a}\) instead of \(0.05\sqrt{e_a}\) |
|
\(Q_l = -\sigma[-\varepsilon_B T_a^4(0.653 + 0.00535\,e_a)(1+0.1762C^2) + \varepsilon T_w^4]\) |
|
\(Q_l = -\varepsilon\sigma[(1-0.6823C^2)T_a^4(0.39-0.05\sqrt{0.01e_a}) + 4T_a^3(T_w-T_a)]\) |
|
Josey et al. (2003) eq. 9; effective sky temperature from cloud cover only |
|
Josey et al. (2003) eq. 14; effective sky temperature from cloud cover and dew-point |
The cloud correction factor ccf in Clark/Hastenrath_Lamb/Berliand_Berliand
is read from a 91-element look-up table indexed by integer latitude (degrees).
All methods require state.ea and/or state.qa to be set by a prior call
to humidity().
Net longwave (back) radiation — translation of longwave_radiation.F90.
Computes the net outgoing longwave radiation at the sea surface [W m⁻²] using one of six parameterisation methods, selected by an integer constant:
CLARK(3) — Clark et al. (1974)HASTENRATH_LAMB(4) — Hastenrath & Lamb (1978)BIGNAMI(5) — Bignami et al. (1995)BERLIAND_BERLIAND(6) — Berliand & Berliand (1952)JOSEY1(7) — Josey et al. (2003), equation J1 (eq. 9)JOSEY2(8) — Josey et al. (2003), equation J2 (eq. 14)
The latitude must be provided in degrees. A 91-element cloud correction
factor table indexed by integer absolute latitude is used by the Clark,
Hastenrath–Lamb, and Berliand–Berliand methods. The vapour pressure ea
(or specific humidity qa) must be set in the AirSeaState object by a
prior call to humidity().
Original FORTRAN authors: Adolf Stips, Hans Burchard, Karsten Bolding.
Shortwave radiation — shortwave_radiation¶
Translates shortwave_radiation.F90. Implements the Reed (1977) /
Rosati–Miyakoda (1988) formula for the net shortwave flux at the surface:
where \(Q_\mathrm{tot} = Q_\mathrm{dir} + Q_\mathrm{diff}\) is the clear-sky total (direct + diffuse) radiation, \(C\) is fractional cloud cover (0–1), and \(\beta\) is the solar noon altitude in degrees.
Internal constants: atmospheric transmittance \(\tau = 0.7\), ozone
absorption \(A_\mathrm{oz} = 0.09\), solar constant
\(S_0\) from SOLAR_CONSTANT_W_M2.
The result does not include the albedo correction; the caller subtracts
the reflected fraction using albedo_water().
Shortwave radiation at the sea surface — translation of shortwave_radiation.F90.
Computes the net downwelling shortwave flux [W m⁻²] from solar zenith angle,
year-day, longitude, latitude, and fractional cloud cover. No albedo
correction is included; the caller must subtract the reflected fraction via
albedo_water().
The formula follows Reed (1977) and Rosati & Miyakoda (1988, eq. 3.8), adapted from the MOM-I implementation at INGV:
where \(Q_{\mathrm{tot}} = Q_{\mathrm{dir}} + Q_{\mathrm{diff}}\) is the clear-sky total radiation, \(C\) is fractional cloud cover, and \(\beta\) is the solar noon altitude in degrees. Internal constants: atmospheric transmittance \(\tau = 0.7\), ozone absorption \(A_{\mathrm{oz}} = 0.09\).
Original FORTRAN authors: Karsten Bolding, Hans Burchard.
Solar zenith angle — solar_zenith_angle¶
Translates solar_zenith_angle.F90. Returns the solar zenith angle in
degrees from day-of-year, decimal hour UTC, longitude, and latitude. Called
by both the shortwave and albedo routines.
Sun declination (in radians) from Spencer (1971) four-term Fourier series:
where \(\theta_0 = 2\pi\,d/365.25\) and \(d\) is day-of-year. The hour-angle is \(h = (hh - 12)\cdot 15° + \lambda\) (longitude in degrees). Cosine of zenith angle:
Clamped to zero (below horizon) before taking the arc-cosine.
Solar zenith angle — translation of the corresponding function in shortwave_radiation.F90.
Returns the solar zenith angle in degrees from day-of-year, decimal UTC hour,
longitude, and latitude. Used by both
shortwave_radiation() and
albedo_water().
Solar declination is computed from a four-term Fourier series (Spencer 1971):
where \(\theta_0 = 2\pi\,d / 365.25\). The hour angle accounts for the observer’s longitude. \(\cos\zeta\) is clamped to zero below the horizon before the arc-cosine is taken.
Original FORTRAN author: Karsten Bolding.
Water-Surface Albedo — albedo_water¶
Translates albedo_water.F90. Returns the fractional sea-surface albedo for
the three methods selected by the albedo_method integer constant (see
Shared State and Constants — airsea_variables):
CONST(0)Always returns 0.0. Used when shortwave forcing is supplied as net radiation (albedo already removed in the observational product).
PAYNE(1)Payne (1972) table of albedo values for 30°–40° N Atlantic. The table has 20 entries covering zenith angles from 90° down to 0° with non-uniform spacing (2° bins near the horizon, 10° bins near zenith). Linear interpolation is performed within each bin. This is the default for most GOTM test cases.
COGLEY(2)Cogley (1979) table with bilinear interpolation in both solar zenith angle (10 entries, 10°-bin spacing) and month-of-year (12 monthly midpoints). Provides more accurate latitudinal and seasonal variation than Payne.
Sea-surface albedo — translation of albedo_water.F90.
Returns the fractional albedo over water as a function of solar zenith angle and year-day. Three methods are available, selected by an integer constant:
CONST(0) — fixed zero albedo; use when shortwave forcing is already net (albedo removed in the observational product).PAYNE(1) — Payne (1972) look-up table (20 entries, 30°–40° N Atlantic) interpolated linearly in zenith angle.COGLEY(2) — Cogley (1979) table with bilinear interpolation in zenith angle (10° bins) and month-of-year (12 monthly midpoints).
Original FORTRAN authors: Karsten Bolding, Hans Burchard.
- pygotm.airsea.albedo_water.albedo_water(method, zenith_angle, yday)[source]¶
Return the sea-surface albedo for the selected GOTM method.
See Also¶
Air–Sea Interaction — physics derivation and sign conventions
Biogeochemistry and FABM Coupling — how
shortwaveandwind_speedare passed to pyfabmGOTM Runtime —
AirSeaDriverStateis owned byRuntimeStateand its fields are written to NetCDF output