Skip to content
13 changes: 12 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Breeze
using RRTMGP, CloudMicrophysics # to load Breeze extensions
using Documenter
using DocumenterCitations
using Literate
Expand Down Expand Up @@ -68,9 +69,19 @@ semaphore = Base.Semaphore(Threads.nthreads(:interactive))
end
end

modules = Module[]
BreezeRRTMGPExt = isdefined(Base, :get_extension) ? Base.get_extension(Breeze, :BreezeRRTMGPExt) : Breeze.BreezeRRTMGPExt
BreezeCloudMicrophysicsExt = isdefined(Base, :get_extension) ? Base.get_extension(Breeze, :BreezeCloudMicrophysicsExt) : Breeze.BreezeCloudMicrophysicsExt

for m in [Breeze, BreezeRRTMGPExt, BreezeCloudMicrophysicsExt]
if !isnothing(m)
push!(modules, m)
end
end

makedocs(
;
modules = [Breeze],
modules,
sitename = "Breeze",
plugins = [bib],
format = Documenter.HTML(
Expand Down
28 changes: 28 additions & 0 deletions docs/src/api.md
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this works

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Locally it does

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, wait, you define the module names in docs/make.jl, this may work then!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you think of a cleaner/better way to do it then go for it!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I think this is the strategy @asinghvi17 suggested the other day on Slack.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That probably works. Autodocs is also executed in Main iirc, so you can just run Base.get_extension within there if you want extra clarity.

Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ Modules = [Breeze.CelestialMechanics]
Private = false
```

### BreezeRRTMGPExt

```@autodocs
Modules = [BreezeRRTMGPExt]
Private = false
```

### BreezeCloudMicrophysicsExt

```@autodocs
Modules = [BreezeCloudMicrophysicsExt]
Private = false
```

## Private API

```@autodocs
Expand Down Expand Up @@ -125,3 +139,17 @@ Public = false
Modules = [Breeze.CelestialMechanics]
Public = false
```

### BreezeRRTMGPExt

```@autodocs
Modules = [BreezeRRTMGPExt]
Public = false
```

### BreezeCloudMicrophysicsExt

```@autodocs
Modules = [BreezeCloudMicrophysicsExt]
Public = false
```
14 changes: 8 additions & 6 deletions docs/src/appendix/notation.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ The following table also uses a few conventions that suffuse the source code and
| ``\mathcal{L}^l(T)`` | `ℒˡ` | `liquid_latent_heat(T, constants)` | Temperature-dependent latent heat of condensation |
| ``\mathcal{L}^i(T)`` | `ℒⁱ` | `ice_latent_heat(T, constants)` | Temperature-dependent latent heat of deposition |
| ``θ₀`` | `θ₀` | `RS.potential_temperature` | (Constant) reference potential temperature for the anelastic formulation |
| ``p₀`` | `p₀` | `RS.surface_pressure` | Base (surface) reference pressure |
| ``p₀`` | `p₀` | `RS.surface_pressure` | Base (surface) reference pressure |
| ``ρᵣ`` | `ρᵣ` | `RS.density` | Density of a dry reference state for the anelastic formulation |
| ``αᵣ`` | `αᵣ` | | Specific volume of a dry reference state, ``αᵣ = Rᵈ θ₀ / pᵣ`` |
| ``pᵣ`` | `pᵣ` | `RS.pressure` | Pressure of a dry adiabatic reference pressure for the anelastic formulation |
Expand All @@ -89,20 +89,22 @@ The following table also uses a few conventions that suffuse the source code and
| ``θˡⁱ`` | `θˡⁱ` | | Liquid-ice potential temperature |
| ``θᵇ`` | `θᵇ` | | Stability-equivalent potential temperature (for moist Brunt-Väisälä) |
| ``θ`` | `θ` | | Shorthand for liquid-ice potential temperature (used in [`set!`](https://clima.github.io/OceananigansDocumentation/stable/appendix/library/#Oceananigans.Fields.set!)) |
| ``\Delta t`` | `Δt` | `Simulation.Δt` | Time step |
| ``\Delta t`` | `Δt` | `Simulation.Δt` | Time step. |
| ``\boldsymbol{\tau}`` | `τ` | | Kinematic subgrid/viscous stress tensor (per unit mass) |
| ``\boldsymbol{\mathcal{T}}`` | `𝒯` | | Dynamic stress tensor used in anelastic momentum, ``\mathcal{T} = ρᵣ τ`` |
| ``\boldsymbol{J}`` | `J` | | Dynamic diffusive flux for scalars |
| ``τˣ`` | `τˣ` | | Surface momentum flux (x-component), ``τˣ = -ρ₀ Cᴰ U ρu / |U|`` |
| ``τʸ`` | `τʸ` | | Surface momentum flux (y-component), ``τʸ = -ρ₀ Cᴰ U ρv / |U|`` |
| ``τˣ`` | `τˣ` | | Surface momentum flux (``x``-component), N/m² |
| ``τʸ`` | `τʸ` | | Surface momentum flux (``y``-component), N/m² |
| ``\mathcal{Q}^T`` | `𝒬ᵀ` | | Surface sensible heat flux, ``\mathcal{Q}^T = cᵖᵐ Jᵀ`` |
| ``\mathcal{Q}^v`` | `𝒬ᵛ` | | Surface latent heat flux, ``\mathcal{Q}^v = \mathcal{L}^l Jᵛ`` |
| ``Jᵀ`` | `Jᵀ` | | Surface temperature flux, ``Jᵀ = -ρ₀ Cᵀ U (θ - θ_0)`` |
| ``Jᵛ`` | `Jᵛ` | | Surface moisture flux, ``Jᵛ = -ρ₀ Cᵛ U (q - q_0^{v+})`` |
| ``Jᵀ`` | `Jᵀ` | | Surface temperature flux, kg K/m²s |
| ``Jᵛ`` | `Jᵛ` | | Surface moisture flux, kg/m²s |
| ``Cᴰ`` | `Cᴰ` | | Surface drag coefficient |
| ``Cᵀ`` | `Cᵀ` | | Surface sensible heat transfer coefficient (Stanton number) |
| ``Cᵛ`` | `Cᵛ` | | Surface vapor transfer coefficient (Dalton number) |
| ``T_0`` | `T₀` | | Sea surface temperature |
| ``qᵛ₀`` | `qᵛ₀` | | Saturation specific humidity at sea surface |
| ``\mathscr{I}`` | `ℐ` | | Radiative flux (intensity), W/m² |
| ``F_{\mathscr{I}}`` | `Fℐ` | | Radiative flux divergence (heating rate), K/s |
| ``τˡʷ`` | `τˡʷ` | | Atmosphere optical thickness for longwave |
| ``τˢʷ`` | `τˢʷ` | | Atmosphere optical thickness for shortwave |
10 changes: 10 additions & 0 deletions docs/src/breeze.bib
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,13 @@ @article{vanZanten2011
year = {2011},
doi = {10.1029/2011MS000056}
}

@article{spencer1971fourier,
title={Fourier series representation of the position of the sun},
author={Spencer, J. W.},
journal={Search},
volume={2},
number={5},
pages={162-172},
year={1971}
}
8 changes: 5 additions & 3 deletions docs/src/radiative_transfer.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,23 @@ The [`RadiativeTransferModel`](@ref) model computes:
- **Longwave radiation**: Both upwelling and downwelling thermal radiation using RRTMGP's two-stream solver
- **Shortwave radiation**: Direct beam solar radiation

The gray atmosphere optical thickness follows the parameterization by [OGormanSchneider2008](@citet):
The gray atmosphere optical thickness for longwave follows the parameterization by [OGormanSchneider2008](@citet)š

```math
τ_{lw} = α \frac{Δp}{p} \left[ f_l \frac{p}{p_0} + 4 (1 - f_l) \left(\frac{p}{p_0}\right)^4 \right] \left[ τ_e + (τ_p - τ_e) \sin^2 φ \right]
τ_{lw} = α \frac{Δp}{p_0} \left[ f_l + 4 (1 - f_l) \left(\frac{p}{p_0}\right)^3 \right] \left[ τ_e + (τ_p - τ_e) \sin^2 φ \right]
```

where ``φ`` is latitude and ``α``, ``f_l``, ``τ_e``, ``τ_p`` are empirical parameters.

For shortwave:
```math
τ_{sw} = 2 τ_0 \frac{p}{p_0} \frac{Δp}{p_0}
τ_{sw} = 2 τ_0 \frac{Δp}{p_0} \frac{p}{p_0}
Comment thread
glwagner marked this conversation as resolved.
```

where ``τ_0 = 0.22`` is the shortwave optical depth parameter.

The above two expressions are identical to those in the [RRTMGP documentation](https://clima.github.io/RRTMGP.jl/latest/Optics/#Gray-atmosphere-optics).

### Radiative Fluxes

After running [`set!`](@ref), the radiative fluxes are available from the radiation model:
Expand Down
1 change: 0 additions & 1 deletion examples/single_column_radiation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,4 @@ Legend(fig[1, 6], ax_I, orientation=:horizontal, nbanks=2, framevisible=false)
title = "Single Column Gray Radiation with O'Gorman & Schneider (2008) optical thickness"
fig[1, :] = Label(fig, title, fontsize=18, tellwidth=false)

save("single_column_radiation.png", fig)
fig
3 changes: 1 addition & 2 deletions ext/BreezeCloudMicrophysicsExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,7 @@ and _either_
- `S_0`: supersaturation threshold (default: 0)
- `qc_0`: cloud liquid water threshold for precipitation (default: 5×10⁻⁴ kg/kg)

For more information see the
[`CloudMicrophysics.jl` documentation](https://clima.github.io/CloudMicrophysicsDocumentation.jl/dev/parameters/parameters0m/).
For more information see the [CloudMicrophysics.jl documentation](https://clima.github.io/CloudMicrophysics.jl/stable/Microphysics0M).
"""
function ZeroMomentCloudMicrophysics(FT::DataType = Oceananigans.defaults.FloatType;
nucleation = SaturationAdjustment(FT),
Expand Down
15 changes: 9 additions & 6 deletions ext/BreezeRRTMGPExt/gray_radiative_transfer_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,10 @@ function RadiativeTransferModel(grid, constants,

grid_parameters = RRTMGPGridParams(FT; context, nlay=Nz, ncol=Nc)

longwave_solver = NoScatLWRTE(grid_parameters;
params = radiative_transfer_parameters,
sfc_emis = rrtmgp_ε₀,
inc_flux = nothing)
longwave_solver = NoScatLWRTE(grid_parameters;
params = radiative_transfer_parameters,
sfc_emis = rrtmgp_ε₀,
inc_flux = nothing)

shortwave_solver = NoScatSWRTE(grid_parameters;
cos_zenith = cos_zenith,
Expand Down Expand Up @@ -485,7 +485,10 @@ $(TYPEDSIGNATURES)

Copy RRTMGP flux arrays to Oceananigans ZFaceFields.

Applies sign convention: positive = upward, negative = downward.
Applies sign convention:
* positive = upward
* negative = downward.

For the non-scattering shortwave solver, only the direct beam flux is computed.
"""
function copy_fluxes_to_fields!(rtm::GrayRadiativeTransferModel, grid)
Expand Down Expand Up @@ -525,4 +528,4 @@ end
end

# Default no-op for models without radiation
update_radiation!(::Nothing, model) = nothing
update_radiation!(::Nothing, model) = nothing
3 changes: 1 addition & 2 deletions src/CelestialMechanics/CelestialMechanics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ export cos_solar_zenith_angle,
day_of_year

using Dates: DateTime, Dates

using DocStringExtensions: TYPEDSIGNATURES
using Oceananigans.Grids: RectilinearGrid, Flat, Bounded, Center, xnode, ynode

include("solar_zenith_angle.jl")

end # module

28 changes: 16 additions & 12 deletions src/CelestialMechanics/solar_zenith_angle.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,20 @@
##### - Latitude (in degrees)
##### - Longitude (in degrees)
#####
##### Reference:
##### Spencer, J. W. (1971). Fourier series representation of the position of the sun.
##### Search, 2(5), 172.
#####

"""
day_of_year(dt::DateTime)
$(TYPEDSIGNATURES)

Return the day of year (1-365/366) for a given DateTime.
"""
day_of_year(dt::DateTime) = Dates.dayofyear(dt)

"""
solar_declination(day_of_year)
$(TYPEDSIGNATURES)

Compute the solar declination angle (in radians) for a given day of year.

Uses the approximation from Spencer (1971):
Uses the approximation by [spencer1971fourier](@citet):

```math
δ = 0.006918 - 0.399912 \\cos(γ) + 0.070257 \\sin(γ)
Expand All @@ -33,6 +29,10 @@ Uses the approximation from Spencer (1971):

where ``γ = 2π (d - 1) / 365`` is the fractional year in radians
and ``d`` is the day of year.

# References

* Spencer, J. W. (1971) Fourier series representation of the position of the sun. Search, 2, 162-172.
"""
function solar_declination(day_of_year)
# Fractional year in radians
Expand All @@ -47,14 +47,18 @@ function solar_declination(day_of_year)
end

"""
equation_of_time(day_of_year)
$(TYPEDSIGNATURES)

Compute the equation of time (in minutes) for a given day of year.

This accounts for the difference between mean solar time and apparent solar time
due to the eccentricity of Earth's orbit and the obliquity of the ecliptic.

Uses the Spencer (1971) approximation.
Uses the approximation by [spencer1971fourier](@citet); see [`solar_declination`](@ref).

# References

* Spencer, J. W. (1971) Fourier series representation of the position of the sun. Search, 2, 162-172.
"""
function equation_of_time(day_of_year)
# Fractional year in radians
Expand All @@ -68,7 +72,7 @@ function equation_of_time(day_of_year)
end

"""
hour_angle(datetime::DateTime, longitude)
$(TYPEDSIGNATURES)

Compute the hour angle (in radians) for a given datetime and longitude.

Expand Down Expand Up @@ -101,7 +105,7 @@ function hour_angle(datetime::DateTime, longitude)
end

"""
cos_solar_zenith_angle(datetime::DateTime, latitude, longitude)
$(TYPEDSIGNATURES)

Compute the cosine of the solar zenith angle for a given datetime and location.

Expand Down Expand Up @@ -138,7 +142,7 @@ end
const SingleColumnGrid = RectilinearGrid{<:Any, <:Flat, <:Flat, <:Bounded}

"""
cos_solar_zenith_angle(grid::AbstractGrid, datetime::DateTime)
$(TYPEDSIGNATURES)

Compute the cosine of the solar zenith angle for the grid's location.

Expand Down