-
Notifications
You must be signed in to change notification settings - Fork 10
Extension to RRTMGP.jl and implement RadiativeTransferModel
#176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
81 commits
Select commit
Hold shift + click to select a range
7c4c47a
start implementing rrtmgp interface
glwagner 3232955
Merge branch 'main' into glw/rrtmgp
glwagner f5ecb5b
Update docs/src/radiative_transfer.md
glwagner ef1a99a
Update docs/src/radiative_transfer.md
glwagner 5cc92b3
Update docs/src/radiative_transfer.md
glwagner 95ff722
Update docs/src/radiative_transfer.md
glwagner bd386ed
Merge branch 'main' into glw/rrtmgp
glwagner 83aeb6d
updates
glwagner 9771b81
Merge branch 'main' into glw/rrtmgp
glwagner 836340a
implement a single column radiation example
glwagner 34de9ec
add to examples
glwagner c71fbf5
fix plots
glwagner cf7d174
Merge branch 'main' into glw/rrtmgp
glwagner c278eaf
update projects
glwagner dfbc019
Merge branch 'glw/rrtmgp' of https://github.com/NumericalEarth/Breeze…
glwagner fa3620d
Update src/RadiativeTransfer/radiative_transfer_model.jl
glwagner 7e36b5d
fixes
glwagner a4eaae8
Merge branch 'glw/rrtmgp' of https://github.com/NumericalEarth/Breeze…
glwagner 24bbae5
rm Dates from Project
glwagner 618098f
add RelativeHumidity diagnostic (blame @navidcy for the scope creep)
glwagner 836b392
Merge branch 'main' into glw/rrtmgp
glwagner 6731428
Fix imports in RRTMGP extension
giordano 655628b
Merge branch 'main' into glw/rrtmgp
glwagner fb9100f
`base_` -> `surface_`
giordano 2e83e7d
reorganize
glwagner 101b5de
Merge branch 'glw/rrtmgp' of https://github.com/NumericalEarth/Breeze…
glwagner c036fc5
updates
glwagner 9932746
Merge branch 'main' into glw/rrtmgp
glwagner 44c19dc
Apply suggestions from code review
giordano 2f249d0
Fix import
giordano 044900c
Apply suggestions from code review
giordano ee6946f
Remove duplicate include
giordano 432e128
Remove stale imports
giordano 8a67b0d
Add missing compat bound for `Dates`
giordano d49ff68
[docs] Add docstrings of `CelestialMechanics`
giordano c36b08f
[docs] Load RRTMGP to be able to include `update_state!` docstring
giordano f8191b4
fixes
glwagner 825c9e5
Merge branch 'glw/rrtmgp' of https://github.com/NumericalEarth/Breeze…
glwagner d7f6894
Move GrayRadiativeTransferModel to src
glwagner fdcc688
deleted orphaned module
glwagner 4cab27d
Remove stale imports
giordano f20106c
clean up
glwagner 707fe92
Merge branch 'glw/rrtmgp' of https://github.com/NumericalEarth/Breeze…
glwagner 5618153
update
glwagner 9905e4a
Update docs/make.jl
glwagner a4d4394
fix tests
glwagner b9f2b9d
Merge branch 'glw/rrtmgp' of https://github.com/NumericalEarth/Breeze…
glwagner e241230
Update docs/src/radiative_transfer.md
glwagner 908cc05
fix docs
glwagner f520e02
edit comment
glwagner 4c6035d
comment
glwagner ad597a1
wrong date
glwagner 4b37d96
delete unused example
glwagner 240b329
Update src/AtmosphereModels/atmosphere_model.jl
glwagner 24d71dd
fixes
glwagner f4f3abb
Merge branch 'glw/rrtmgp' of https://github.com/NumericalEarth/Breeze…
glwagner e135f8e
jeez
glwagner 1264428
remoeve refs to radiative transfer model
glwagner dfaf629
redesign interface for radiation
glwagner f23c5b8
refactor to generic RadiativeTransferModel interface
glwagner d6c154f
Merge branch 'main' into glw/rrtmgp
glwagner 79139ad
dont import Face
glwagner 3cc0bce
fix show method
glwagner dc28ded
fix docs
glwagner adef7c5
fix
glwagner 01edcb9
undefined export!
glwagner 6b20e9d
Merge branch 'main' into glw/rrtmgp
glwagner 5fc0971
probel bibtex ref
navidcy b36f44e
fix some citations
navidcy eda8556
don't define σ; reserve for Stefan-Boltzman
navidcy 1a8d6d5
few tweaks
navidcy e9df6ab
remove extra const
glwagner 3c398f7
proper docstring
glwagner c4dd760
fix RadiativeTransferModel show method
navidcy da3cbc2
remove unnecessary white space
navidcy 55f1954
Merge branch 'main' into glw/rrtmgp
giordano e36d898
simplify pot temp prof in radiation example
glwagner 4e35b8a
add a basic test for set in unit tests
glwagner 29afe67
rm unused materalize plus tests for Field materiazliation
glwagner 2c88a0e
bugfix
glwagner 8c340b8
clean up radiation tests
glwagner File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| # Radiative Transfer | ||
|
|
||
| Breeze.jl integrates with [RRTMGP.jl](https://github.com/NumericalEarth/RRTMGP.jl) to provide radiative transfer capabilities for atmospheric simulations. The radiative transfer model computes longwave and shortwave radiative fluxes and heating rates, which are then incorporated into the moist static energy tendency equation. | ||
|
|
||
| ## Overview | ||
|
|
||
| The radiative transfer implementation in Breeze uses a column-based approach, where each horizontal column of the 3D grid is treated independently. This allows efficient computation of radiative fluxes using RRTMGP's optimized column radiation solver. | ||
|
|
||
| ## Basic Usage | ||
|
|
||
| To use radiative transfer in a Breeze simulation, create a `RadiativeTransferModel` and pass it to the `AtmosphereModel` constructor: | ||
|
|
||
| ```julia | ||
| using Breeze | ||
| using Oceananigans | ||
|
|
||
| # Create grid | ||
| grid = RectilinearGrid(CPU(), Float64; size=(32, 32, 64), x=(0, 10_000), y=(0, 10_000), z=(0, 20_000)) | ||
|
|
||
| # Create radiative transfer model | ||
| rtm = RadiativeTransferModel( | ||
| grid; | ||
| surface_emissivity = 0.98, | ||
| surface_albedo_direct = 0.1, | ||
| surface_albedo_diffuse = 0.1, | ||
| cos_zenith = 0.5, | ||
| toa_solar_flux = 1360.0, | ||
| toa_longwave_flux = 0.0 | ||
| ) | ||
|
|
||
| # Create atmosphere model with radiative transfer | ||
| model = AtmosphereModel( | ||
| grid; | ||
| radiative_transfer = rtm | ||
| ) | ||
| ``` | ||
|
|
||
| ## Column Model Example | ||
|
|
||
| Here we demonstrate a simple column model calculation of radiative fluxes. This example sets up a single-column atmosphere and computes radiative heating rates. | ||
|
|
||
| ```julia | ||
| using Breeze | ||
| using Oceananigans | ||
| using CairoMakie | ||
|
|
||
| # Create a single-column grid (1x1 horizontal, 64 vertical levels) | ||
|
glwagner marked this conversation as resolved.
Outdated
|
||
| grid = RectilinearGrid(CPU(), Float64; | ||
| size=(1, 1, 64), | ||
| x=(0, 1), | ||
| y=(0, 1), | ||
| z=(0, 20_000) | ||
| ) | ||
|
glwagner marked this conversation as resolved.
Outdated
|
||
|
|
||
| # Thermodynamic constants | ||
| thermo = ThermodynamicConstants(Float64) | ||
|
glwagner marked this conversation as resolved.
Outdated
|
||
|
|
||
| # Reference state | ||
| reference_state = ReferenceState(grid, thermo, | ||
| base_pressure = 101325.0, | ||
| potential_temperature = 288.0 | ||
| ) | ||
|
|
||
| formulation = AnelasticFormulation(reference_state) | ||
|
|
||
| # Create radiative transfer model | ||
| rtm = RadiativeTransferModel( | ||
| grid; | ||
| surface_emissivity = 0.98, | ||
| surface_albedo_direct = 0.1, | ||
| surface_albedo_diffuse = 0.1, | ||
| cos_zenith = 0.5, # Solar zenith angle cosine | ||
| toa_solar_flux = 1360.0, # Top-of-atmosphere solar flux [W/m²] | ||
| toa_longwave_flux = 0.0 | ||
| ) | ||
|
|
||
| # Create atmosphere model | ||
| model = AtmosphereModel( | ||
| grid; | ||
| thermodynamics = thermo, | ||
| formulation = formulation, | ||
| radiative_transfer = rtm | ||
| ) | ||
|
|
||
| # Initialize with a temperature profile | ||
| # Simple linear temperature profile decreasing with height | ||
| set!(model.temperature, (x, y, z) -> 288.0 - 0.0065 * z) | ||
|
|
||
| # Update model state | ||
| update_state!(model) | ||
|
|
||
| # Update radiative fluxes | ||
| Breeze.AtmosphereModels._update_radiative_fluxes!(rtm, model) | ||
|
|
||
| # Extract heating rates | ||
| nz = size(grid, 3) | ||
| heating_rate = zeros(Float64, nz) | ||
|
|
||
| using Oceananigans: interior | ||
| using Oceananigans.Grids: znode | ||
| using GPUArraysCore: @allowscalar | ||
|
|
||
| @allowscalar begin | ||
| ρᵣ = model.formulation.reference_state.density | ||
| for k in 1:nz | ||
| hr = Breeze.AtmosphereModels._radiative_heating_rate( | ||
| 1, 1, k, grid, rtm, | ||
| ρᵣ, | ||
| thermo | ||
| ) | ||
| # Convert from energy density tendency to heating rate per unit mass | ||
| heating_rate[k] = hr / ρᵣ[1, 1, k] | ||
| end | ||
| end | ||
|
|
||
| # Extract height levels for plotting | ||
| z_lev = [znode(1, 1, k, grid, Center(), Center(), Center()) for k in 1:nz] | ||
|
|
||
| # Plot heating rate profile | ||
| using CairoMakie | ||
|
|
||
| fig = Figure(resolution = (600, 400)) | ||
| ax = Axis(fig[1, 1], | ||
| xlabel = "Heating Rate [K/day]", | ||
| ylabel = "Height [m]", | ||
| title = "Radiative Heating Rate Profile" | ||
| ) | ||
|
|
||
| # Convert to K/day | ||
| cp = thermo.dry_air.heat_capacity | ||
| seconds_per_day = 86400.0 | ||
| heating_rate_k_per_day = heating_rate .* seconds_per_day ./ cp | ||
|
|
||
| lines!(ax, heating_rate_k_per_day, z_lev, linewidth = 2) | ||
| fig | ||
| ``` | ||
|
|
||
| ## Surface Properties | ||
|
|
||
| The `RadiativeTransferModel` requires several surface properties that are not part of the `AtmosphereModel`: | ||
|
|
||
| - **Surface temperature**: Temperature at the surface (can be extracted from model or specified) | ||
| - **Surface emissivity**: Longwave emissivity of the surface (typically 0.95-0.99) | ||
| - **Surface albedo (direct)**: Albedo for direct solar radiation | ||
| - **Surface albedo (diffuse)**: Albedo for diffuse solar radiation | ||
| - **Cosine of solar zenith angle**: Determines solar insolation | ||
| - **TOA solar flux**: Top-of-atmosphere solar flux [W/m²] | ||
| - **TOA longwave flux**: Top-of-atmosphere longwave flux [W/m²] (usually 0) | ||
|
|
||
| These properties are stored in the `RadiativeTransferModel` and can be updated as needed during the simulation. | ||
|
|
||
| ## Reference Pressure | ||
|
|
||
| Breeze uses the **reference pressure** from the anelastic formulation for radiative transfer calculations, not the total pressure. This is consistent with the anelastic approximation where pressure perturbations are small compared to the reference state. | ||
|
|
||
| ## Integration with Dynamics | ||
|
|
||
| Radiative heating is automatically added to the moist static energy tendency equation when a `RadiativeTransferModel` is provided. The heating rate is computed from flux differences: | ||
|
|
||
| ```math | ||
| \frac{\partial (\rho e)}{\partial t} = \ldots + \rho_r \frac{g}{c_p} \frac{F_{k+1} - F_k}{\Delta p} | ||
| ``` | ||
|
|
||
| where ``F_k`` is the net radiative flux at level ``k``, ``\Delta p`` is the pressure difference across the layer, ``g`` is gravitational acceleration, ``c_p`` is specific heat capacity, and ``\rho_r`` is the reference density. | ||
|
|
||
| ## Gray Atmosphere Model | ||
|
|
||
| The current implementation uses a gray atmosphere radiation model, which treats the atmosphere as having a single effective absorption coefficient. This is suitable for initial testing and development. Future versions will support full spectral radiation using RRTMGP's band-by-band calculations. | ||
|
|
||
| ## Architecture Support | ||
|
|
||
| The radiative transfer implementation supports both CPU and GPU architectures. The grid conversion utilities automatically handle the conversion between Oceananigans' 3D grid format and RRTMGP's column-based format, including proper handling of CPU and GPU arrays. | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| module RRTMGPExt | ||
|
|
||
| import Breeze | ||
| import RRTMGP | ||
|
|
||
| # Load the RadiativeTransfer module when RRTMGP is available | ||
| include(joinpath(@__DIR__, "..", "src", "RadiativeTransfer", "RadiativeTransfer.jl")) | ||
|
|
||
| using .RadiativeTransfer | ||
|
|
||
| # Re-export RadiativeTransferModel in Breeze module | ||
| const RadiativeTransferModel = RadiativeTransfer.RadiativeTransferModel | ||
|
|
||
| # Make functions available to AtmosphereModels module by adding them to the module | ||
| # This allows the functions to be called from dynamics_kernel_functions.jl | ||
| Breeze.AtmosphereModels.eval(quote | ||
| const _radiative_heating_rate = $(RadiativeTransfer._radiative_heating_rate) | ||
| const _update_radiative_fluxes! = $(RadiativeTransfer._update_radiative_fluxes!) | ||
| end) | ||
|
|
||
| # Export RadiativeTransferModel from Breeze | ||
| Breeze.eval(quote | ||
| export RadiativeTransferModel | ||
| end) | ||
|
|
||
| end # module | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| module RadiativeTransfer | ||
|
|
||
| export RadiativeTransferModel, _radiative_heating_rate, _update_radiative_fluxes! | ||
|
|
||
| include("radiative_transfer_model.jl") | ||
| include("grid_conversion.jl") | ||
| include("atmosphere_model_integration.jl") | ||
|
|
||
| end # module | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| """ | ||
| Integration of RadiativeTransferModel with AtmosphereModel. | ||
| """ | ||
|
|
||
| using Oceananigans: CenterField | ||
| using Oceananigans.Operators: ℑzᵃᵃᶜ | ||
|
|
||
| import ..AtmosphereModels: AtmosphereModel, AnelasticFormulation | ||
| import ..grid_conversion: reshape_from_columns | ||
|
|
||
| """ | ||
| _radiative_heating_rate(i, j, k, grid, rtm::RadiativeTransferModel, | ||
| reference_density, thermo) | ||
|
|
||
| Compute the radiative heating rate contribution to moist static energy tendency | ||
| at grid point (i, j, k). | ||
|
|
||
| The heating rate is computed from flux differences: | ||
| hr = g * (flux_net[k+1] - flux_net[k]) / (cp * Δp) | ||
|
|
||
| and the contribution to energy density tendency is: | ||
| ρᵣ * hr | ||
|
|
||
| where ρᵣ is the reference density. | ||
| """ | ||
| @inline function _radiative_heating_rate(i, j, k, grid, rtm, reference_density, thermo) | ||
| # Get net fluxes | ||
| flux_net_lw = rtm.flux_lw.flux_net | ||
| flux_net_sw = rtm.flux_sw.flux_net | ||
|
|
||
| # Combine longwave and shortwave | ||
| flux_net_total = flux_net_lw .+ flux_net_sw | ||
|
|
||
| # Convert grid indices to column index | ||
| nx, ny, nz = size(grid) | ||
| icol = (j - 1) * nx + i | ||
|
|
||
| # Get flux at levels k and k+1 (fluxes are at levels, k is cell index) | ||
| # Level k corresponds to bottom of cell k | ||
| # Level k+1 corresponds to top of cell k | ||
| flux_bottom = @inbounds flux_net_total[k, icol] | ||
| flux_top = @inbounds flux_net_total[k+1, icol] | ||
|
|
||
| # Get pressure difference from atmospheric state | ||
| p_lev = rtm.atmospheric_state.p_lev | ||
| Δp = @inbounds p_lev[k+1, icol] - p_lev[k, icol] | ||
|
|
||
| # Get constants from thermodynamics | ||
| g = thermo.gravitational_acceleration | ||
| cp = thermo.dry_air.heat_capacity | ||
|
|
||
| # Compute heating rate per unit mass | ||
| hr = g * (flux_top - flux_bottom) / (cp * Δp) | ||
|
|
||
| # Get reference density at this point | ||
| ρᵣ = @inbounds reference_density[i, j, k] | ||
|
|
||
| # Return contribution to energy density tendency | ||
| return ρᵣ * hr | ||
| end | ||
|
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.