diff --git a/.github/workflows/Whitespace.yml b/.github/workflows/Whitespace.yml new file mode 100644 index 00000000..1e99124b --- /dev/null +++ b/.github/workflows/Whitespace.yml @@ -0,0 +1,36 @@ +name: Whitespace + +permissions: {} + +on: + push: + branches: + - 'main' + pull_request: + +jobs: + whitespace: + name: Check whitespace + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - name: Checkout the NumericalEarth/Breeze.jl repository + uses: actions/checkout@v6 + with: + persist-credentials: false + - name: Checkout the JuliaLang/julia repository + uses: actions/checkout@v6 + with: + persist-credentials: false + repository: 'JuliaLang/julia' + # Clone Julia in a subdir. + path: '.julia' + # Check out a fixed revision to avoid surprises in case the script is + # changed in the future. + ref: '3b12a882e887753e4d2e9e9db65d99d3f7d9e26b' + - uses: julia-actions/setup-julia@v2 + with: + version: '1.12.4' + - name: Check whitespace + run: | + .julia/contrib/check-whitespace.jl diff --git a/AGENTS.md b/AGENTS.md index a5e57375..a16a46dd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -390,7 +390,7 @@ serve(dir="docs/build") When implementing a simulation from a published paper: ### 1. Parameter Extraction -- **Read the paper carefully** and extract ALL parameters: domain size, resolution, physical constants, +- **Read the paper carefully** and extract ALL parameters: domain size, resolution, physical constants, boundary conditions, initial conditions, forcing, closure parameters - Look for parameter tables (often "Table 1" or similar) - Check figure captions for additional details @@ -433,11 +433,11 @@ Before running a long simulation: - Quantitative comparison: compute the same diagnostics as the paper ### 7. Common Issues -- **NaN blowups**: Usually from timestep too large, unstable initial conditions, +- **NaN blowups**: Usually from timestep too large, unstable initial conditions, or if-else statements on GPU (use `ifelse` instead) -- **Nothing happening**: Check that buoyancy anomaly has the right sign, +- **Nothing happening**: Check that buoyancy anomaly has the right sign, that initial conditions are actually applied, that forcing is active -- **Wrong direction of flow**: Check coordinate conventions (is y increasing +- **Wrong direction of flow**: Check coordinate conventions (is y increasing upslope or downslope?) - **GPU issues**: Avoid branching, ensure type stability, use `randn()` carefully diff --git a/docs/src/contributing.md b/docs/src/contributing.md index 1d11b648..b760b681 100644 --- a/docs/src/contributing.md +++ b/docs/src/contributing.md @@ -90,7 +90,7 @@ See [`ExplicitImports.jl` documentation](https://juliatesting.github.io/Explicit ## Building the documentation locally `Breeze.jl` [documentation](https://numericalearth.github.io/BreezeDocumentation/) is generated using [`Documenter.jl`](https://github.com/JuliaDocs/Documenter.jl). -You can preview how the documentation will look like with your changes by building the documentation locally. +You can preview how the documentation will look like with your changes by building the documentation locally. From the top-level directory of your local repository run ```sh diff --git a/docs/src/developer/microphysics_interface.md b/docs/src/developer/microphysics_interface.md index 6531eb6b..23ea88b1 100644 --- a/docs/src/developer/microphysics_interface.md +++ b/docs/src/developer/microphysics_interface.md @@ -34,7 +34,7 @@ a microphysics implementation in `AtmosphereModel`: ## Example implementation -To illustrate the development of a new microphysics scheme, we implement a +To illustrate the development of a new microphysics scheme, we implement a simple microphysics scheme that represents droplet and ice particle nucleation with constant-rate relaxation of specific humidity to saturation. @@ -59,7 +59,7 @@ prognostic_field_names(::ExplicitMicrophysics) = (:ρqᵛ, :ρqˡ, :ρqⁱ) ``` !!! note - The names of prognostic fields defined by `prognostic_field_names` + The names of prognostic fields defined by `prognostic_field_names` **are crucial to the user interface**, because users can interact them and [`set!`](https://clima.github.io/OceananigansDocumentation/stable/appendix/library/#Oceananigans.Fields.set!) their initial conditions. The names of variables should be carefully chosen to be concise, mathematical forms that are consistent with Breeze conventions. @@ -78,7 +78,7 @@ function materialize_microphysical_fields(::ExplicitMicrophysics, grid, boundary return (; ρqˡ, ρqⁱ, ρqᵛ, qᵛ) end ``` -The tendencies for +The tendencies for ```@example microphysics_interface import Breeze.AtmosphereModels: microphysical_tendency diff --git a/examples/boussinesq_bomex.jl b/examples/boussinesq_bomex.jl index 05f7c2f0..08f3f4a1 100644 --- a/examples/boussinesq_bomex.jl +++ b/examples/boussinesq_bomex.jl @@ -143,7 +143,7 @@ set!(Fθ_field, z -> dTdt_bomex(1, z)) θ_forcing = (θ_radiation_forcing, θ_subsidence_forcing) model = NonhydrostaticModel(; grid, buoyancy, coriolis, - advection = WENO(order=5), + advection = WENO(order=5), tracers = (:θ, :qᵗ), forcing = (; qᵗ=qᵗ_forcing, u=u_forcing, v=v_forcing, θ=θ_forcing), boundary_conditions = (θ=θ_bcs, qᵗ=qᵗ_bcs, u=u_bcs, v=v_bcs)) diff --git a/examples/cloudy_thermal_bubble.jl b/examples/cloudy_thermal_bubble.jl index 95319beb..45f1ef54 100644 --- a/examples/cloudy_thermal_bubble.jl +++ b/examples/cloudy_thermal_bubble.jl @@ -149,7 +149,7 @@ nothing #hide # following the methodology described by Bryan and Fritsch (2002). This simulation # includes moisture processes, where excess water vapor condenses to liquid water, # releasing latent heat that enhances the buoyancy of the rising bubble. -# +# # For pedagogical purposes, we build a new model with warm-phase saturation adjustment microphysics. # (We coudl have also used this model for the dry simulation): diff --git a/examples/prescribed_sea_surface_temperature.jl b/examples/prescribed_sea_surface_temperature.jl index 84be9bbc..75f02e1c 100644 --- a/examples/prescribed_sea_surface_temperature.jl +++ b/examples/prescribed_sea_surface_temperature.jl @@ -111,9 +111,9 @@ Uᵍ = 1e-2 # Minimum wind speed (m/s) # # For `BulkVaporFlux`, the saturation specific humidity is computed from the surface # temperature. Surface temperature can be provided as a `Field`, a `Function`, or a `Number`. -# +# # In this example, we specify the sea surface temperature as a top hat function -# i.e. representing a pair of ocean fronts in a periodic domain, with a +# i.e. representing a pair of ocean fronts in a periodic domain, with a # difference of 4 degrees K, ΔT = 4 # K diff --git a/examples/rico.jl b/examples/rico.jl index 88eac2bf..625f8763 100644 --- a/examples/rico.jl +++ b/examples/rico.jl @@ -148,7 +148,7 @@ set!(∂t_ρqᵗ_large_scale, ρᵣ * ∂t_ρqᵗ_large_scale) # This is the key simplification that allows us to avoid interactive radiation. ∂t_ρθ_large_scale = Field{Nothing, Nothing, Center}(grid) -∂t_θ_large_scale = - 2.5 / day # K / day +∂t_θ_large_scale = - 2.5 / day # K / day set!(∂t_ρθ_large_scale, ρᵣ * ∂t_θ_large_scale) ρθ_large_scale_forcing = Forcing(∂t_ρθ_large_scale) diff --git a/ext/BreezeCloudMicrophysicsExt/one_moment_helpers.jl b/ext/BreezeCloudMicrophysicsExt/one_moment_helpers.jl index f37256c7..8da35862 100644 --- a/ext/BreezeCloudMicrophysicsExt/one_moment_helpers.jl +++ b/ext/BreezeCloudMicrophysicsExt/one_moment_helpers.jl @@ -92,7 +92,7 @@ Adapt.adapt_structure(to, k::SurfacePrecipitationFluxKernel) = # wʳ < 0 (downward), so -wʳ * ρqʳ > 0 represents flux out of domain @inbounds wʳ = kernel.terminal_velocity[i, j, 1] @inbounds ρqʳ = kernel.rain_density[i, j, 1] - + # Return positive flux for rain leaving domain (downward) return -wʳ * ρqʳ end diff --git a/ext/BreezeCloudMicrophysicsExt/two_moment_helpers.jl b/ext/BreezeCloudMicrophysicsExt/two_moment_helpers.jl index e7341466..a0496470 100644 --- a/ext/BreezeCloudMicrophysicsExt/two_moment_helpers.jl +++ b/ext/BreezeCloudMicrophysicsExt/two_moment_helpers.jl @@ -138,4 +138,3 @@ function Base.show(io::IO, bμp::BulkMicrophysics{<:Any, <:CM2MCategories}) end Base.summary(bμp::TwoMomentCloudMicrophysics) = "TwoMomentCloudMicrophysics" - diff --git a/ext/BreezeRRTMGPExt/BreezeRRTMGPExt.jl b/ext/BreezeRRTMGPExt/BreezeRRTMGPExt.jl index b36566bb..f076fab2 100644 --- a/ext/BreezeRRTMGPExt/BreezeRRTMGPExt.jl +++ b/ext/BreezeRRTMGPExt/BreezeRRTMGPExt.jl @@ -15,7 +15,7 @@ using Oceananigans.Fields: ZFaceField # RRTMGP imports (external types - cannot modify) # GrayAtmosphericState: atmospheric state arrays (t_lay, p_lay, t_lev, p_lev, z_lev, t_sfc) -# NoScatLWRTE, NoScatSWRTE: longwave/shortwave RTE solvers +# NoScatLWRTE, NoScatSWRTE: longwave/shortwave RTE solvers # FluxLW, FluxSW: flux storage (flux_up, flux_dn, flux_net, flux_dn_dir) # RRTMGPParameters: physical constants for RRTMGP @@ -76,4 +76,3 @@ include("clear_sky_radiative_transfer_model.jl") include("all_sky_radiative_transfer_model.jl") end # module - diff --git a/ext/BreezeRRTMGPExt/all_sky_radiative_transfer_model.jl b/ext/BreezeRRTMGPExt/all_sky_radiative_transfer_model.jl index 77342095..a8fca82f 100644 --- a/ext/BreezeRRTMGPExt/all_sky_radiative_transfer_model.jl +++ b/ext/BreezeRRTMGPExt/all_sky_radiative_transfer_model.jl @@ -51,7 +51,7 @@ RRTMGP loads lookup tables from netCDF via an extension. # Keyword Arguments - `background_atmosphere`: Background atmospheric gas composition (default: `BackgroundAtmosphere{FT}()`). - `surface_temperature`: Surface temperature in Kelvin (required). -- `coordinate`: Tuple of (longitude, latitude) in degrees. If `nothing` (default), +- `coordinate`: Tuple of (longitude, latitude) in degrees. If `nothing` (default), extracted from grid coordinates. - `epoch`: Optional epoch for computing time with floating-point clocks. - `surface_emissivity`: Surface emissivity, 0-1 (default: 0.98). Scalar. diff --git a/ext/BreezeRRTMGPExt/clear_sky_radiative_transfer_model.jl b/ext/BreezeRRTMGPExt/clear_sky_radiative_transfer_model.jl index ffc5cba1..adbec1ff 100644 --- a/ext/BreezeRRTMGPExt/clear_sky_radiative_transfer_model.jl +++ b/ext/BreezeRRTMGPExt/clear_sky_radiative_transfer_model.jl @@ -34,7 +34,7 @@ RRTMGP loads lookup tables from netCDF via an extension. # Keyword Arguments - `background_atmosphere`: Background atmospheric gas composition (default: `BackgroundAtmosphere{FT}()`). - `surface_temperature`: Surface temperature in Kelvin (required). -- `coordinate`: Tuple of (longitude, latitude) in degrees. If `nothing` (default), +- `coordinate`: Tuple of (longitude, latitude) in degrees. If `nothing` (default), extracted from grid coordinates. - `epoch`: Optional epoch for computing time with floating-point clocks. - `surface_emissivity`: Surface emissivity, 0-1 (default: 0.98). Scalar. diff --git a/ext/BreezeRRTMGPExt/gray_radiative_transfer_model.jl b/ext/BreezeRRTMGPExt/gray_radiative_transfer_model.jl index c430ebe1..dc1ec9b4 100644 --- a/ext/BreezeRRTMGPExt/gray_radiative_transfer_model.jl +++ b/ext/BreezeRRTMGPExt/gray_radiative_transfer_model.jl @@ -42,11 +42,11 @@ Construct a gray atmosphere radiative transfer model for the given grid. # Keyword Arguments - `optical_thickness`: Optical thickness parameterization (default: `GrayOpticalThicknessOGorman2008(FT)`). - `surface_temperature`: Surface temperature in Kelvin (required). -- `coordinate`: Tuple of (longitude, latitude) in degrees. If `nothing` (default), +- `coordinate`: Tuple of (longitude, latitude) in degrees. If `nothing` (default), extracted from grid coordinates. - `epoch`: Optional epoch for computing time with floating-point clocks. - `surface_emissivity`: Surface emissivity, 0-1 (default: 0.98). Scalar. -- `surface_albedo`: Surface albedo, 0-1. Can be scalar or 2D field. +- `surface_albedo`: Surface albedo, 0-1. Can be scalar or 2D field. Alternatively, provide both `direct_surface_albedo` and `diffuse_surface_albedo`. - `direct_surface_albedo`: Direct surface albedo, 0-1. Can be scalar or 2D field. - `diffuse_surface_albedo`: Diffuse surface albedo, 0-1. Can be scalar or 2D field. diff --git a/ext/BreezeRRTMGPExt/rrtmgp_shared_utilities.jl b/ext/BreezeRRTMGPExt/rrtmgp_shared_utilities.jl index f0bd2d88..6e304300 100644 --- a/ext/BreezeRRTMGPExt/rrtmgp_shared_utilities.jl +++ b/ext/BreezeRRTMGPExt/rrtmgp_shared_utilities.jl @@ -134,4 +134,3 @@ end ℐ_sw_dn[i, j, k] = -sw_flux_dn[k, col] end end - diff --git a/src/AnelasticEquations/AnelasticEquations.jl b/src/AnelasticEquations/AnelasticEquations.jl index 665fed46..6c3bbbab 100644 --- a/src/AnelasticEquations/AnelasticEquations.jl +++ b/src/AnelasticEquations/AnelasticEquations.jl @@ -45,4 +45,3 @@ const AnelasticModel = AtmosphereModel{<:AnelasticDynamics} include("anelastic_time_stepping.jl") end # module - diff --git a/src/AnelasticEquations/anelastic_buoyancy.jl b/src/AnelasticEquations/anelastic_buoyancy.jl index f5d3dffb..962eec5e 100644 --- a/src/AnelasticEquations/anelastic_buoyancy.jl +++ b/src/AnelasticEquations/anelastic_buoyancy.jl @@ -47,4 +47,3 @@ where `pᵣ` is the reference pressure, `Rᵐ` is the mixture gas constant, and return - g * ρ′ end - diff --git a/src/AnelasticEquations/anelastic_dynamics.jl b/src/AnelasticEquations/anelastic_dynamics.jl index 54c57acd..6072e27c 100644 --- a/src/AnelasticEquations/anelastic_dynamics.jl +++ b/src/AnelasticEquations/anelastic_dynamics.jl @@ -164,4 +164,3 @@ function AtmosphereModels.materialize_momentum_and_velocities(dynamics::Anelasti return momentum, velocities end - diff --git a/src/AnelasticEquations/anelastic_pressure_solver.jl b/src/AnelasticEquations/anelastic_pressure_solver.jl index 3e436972..db0d3b1f 100644 --- a/src/AnelasticEquations/anelastic_pressure_solver.jl +++ b/src/AnelasticEquations/anelastic_pressure_solver.jl @@ -102,4 +102,3 @@ end δ = divᶜᶜᶜ(i, j, k, grid, ρu, ρv, ρw) @inbounds rhs[i, j, k] = active * Δzᶜᶜᶜ(i, j, k, grid) * δ / Δt end - diff --git a/src/AnelasticEquations/anelastic_time_stepping.jl b/src/AnelasticEquations/anelastic_time_stepping.jl index 9fc69a9a..c8d12687 100644 --- a/src/AnelasticEquations/anelastic_time_stepping.jl +++ b/src/AnelasticEquations/anelastic_time_stepping.jl @@ -75,4 +75,3 @@ function TimeSteppers.make_pressure_correction!(model::AnelasticModel, Δt) return nothing end - diff --git a/src/AtmosphereModels/Diagnostics/saturation_specific_humidity.jl b/src/AtmosphereModels/Diagnostics/saturation_specific_humidity.jl index 7709063a..a28cbdf8 100644 --- a/src/AtmosphereModels/Diagnostics/saturation_specific_humidity.jl +++ b/src/AtmosphereModels/Diagnostics/saturation_specific_humidity.jl @@ -131,4 +131,3 @@ end const SaturationSpecificHumidityField = Field{C, C, C, <:SaturationSpecificHumidity} SaturationSpecificHumidityField(model, flavor_symbol=:prognostic) = Field(SaturationSpecificHumidity(model, flavor_symbol)) - diff --git a/src/AtmosphereModels/Diagnostics/static_energy.jl b/src/AtmosphereModels/Diagnostics/static_energy.jl index 64b4fde1..518e214b 100644 --- a/src/AtmosphereModels/Diagnostics/static_energy.jl +++ b/src/AtmosphereModels/Diagnostics/static_energy.jl @@ -118,4 +118,3 @@ function (d::StaticEnergyKernelFunction)(i, j, k, grid) return ρᵣ * e end end - diff --git a/src/AtmosphereModels/dynamics_interface.jl b/src/AtmosphereModels/dynamics_interface.jl index 0201488e..deaa14ae 100644 --- a/src/AtmosphereModels/dynamics_interface.jl +++ b/src/AtmosphereModels/dynamics_interface.jl @@ -140,7 +140,7 @@ function validate_velocity_boundary_conditions(dynamics, user_boundary_condition velocity_names = (:u, :v, :w) user_bc_names = keys(user_boundary_conditions) provided_velocity_bcs = filter(name -> name ∈ user_bc_names, velocity_names) - + if !isempty(provided_velocity_bcs) throw(ArgumentError( "Boundary conditions for velocity components $(provided_velocity_bcs) are not supported " * diff --git a/src/Breeze.jl b/src/Breeze.jl index bc0199a9..a164c5bf 100644 --- a/src/Breeze.jl +++ b/src/Breeze.jl @@ -34,7 +34,7 @@ export mixture_heat_capacity, dynamics_density, dynamics_pressure, - + # Diagnostics compute_hydrostatic_pressure!, PotentialTemperature, diff --git a/src/CompressibleEquations/compressible_buoyancy.jl b/src/CompressibleEquations/compressible_buoyancy.jl index 5cc89c6b..cb280daf 100644 --- a/src/CompressibleEquations/compressible_buoyancy.jl +++ b/src/CompressibleEquations/compressible_buoyancy.jl @@ -34,4 +34,3 @@ in the momentum equation without subtraction of a reference state. return -g * ρ end - diff --git a/src/CompressibleEquations/compressible_dynamics.jl b/src/CompressibleEquations/compressible_dynamics.jl index 482b7789..1f37799d 100644 --- a/src/CompressibleEquations/compressible_dynamics.jl +++ b/src/CompressibleEquations/compressible_dynamics.jl @@ -179,4 +179,3 @@ function AtmosphereModels.materialize_momentum_and_velocities(dynamics::Compress return momentum, velocities end - diff --git a/src/CompressibleEquations/compressible_time_stepping.jl b/src/CompressibleEquations/compressible_time_stepping.jl index 2b92a25b..095a53dd 100644 --- a/src/CompressibleEquations/compressible_time_stepping.jl +++ b/src/CompressibleEquations/compressible_time_stepping.jl @@ -150,4 +150,3 @@ end return T, p end - diff --git a/src/Forcings/subsidence_forcing.jl b/src/Forcings/subsidence_forcing.jl index aab511dd..b77dc1d8 100644 --- a/src/Forcings/subsidence_forcing.jl +++ b/src/Forcings/subsidence_forcing.jl @@ -111,7 +111,7 @@ end # Strip the ρ prefix from density variable names # e.g., :ρu → :u, :ρθ → :θ, :ρe → :e function strip_density_prefix(name::Symbol) - chars = string(name) |> collect + chars = string(name) |> collect prefix = popfirst!(chars) return Symbol(chars...) end diff --git a/src/KinematicDriver/kinematic_driver_time_stepping.jl b/src/KinematicDriver/kinematic_driver_time_stepping.jl index a8fe157a..6f9fc958 100644 --- a/src/KinematicDriver/kinematic_driver_time_stepping.jl +++ b/src/KinematicDriver/kinematic_driver_time_stepping.jl @@ -34,11 +34,11 @@ AtmosphereModels.set_velocity!(model::KinematicModel, name::Symbol, value) = set_velocity!(velocity::AbstractField, value) = set!(velocity, value) # FunctionFields (from PrescribedVelocityFields): cannot be set -set_velocity!(::FunctionField, value) = +set_velocity!(::FunctionField, value) = throw(ArgumentError("Cannot set velocity component of PrescribedVelocityFields.")) # No momentum in kinematic models -AtmosphereModels.set_momentum!(::KinematicModel, name::Symbol, value) = +AtmosphereModels.set_momentum!(::KinematicModel, name::Symbol, value) = throw(ArgumentError("Cannot set momentum component '$name' of a KinematicModel.")) ##### diff --git a/src/Microphysics/dcmip2016_kessler.jl b/src/Microphysics/dcmip2016_kessler.jl index c8cf5f5d..a3bab8ce 100644 --- a/src/Microphysics/dcmip2016_kessler.jl +++ b/src/Microphysics/dcmip2016_kessler.jl @@ -418,7 +418,7 @@ end # Temperature offset for saturation adjustment (from TetensFormula) δT = constants.saturation_vapor_pressure.liquid_temperature_offset - + # Microphysics parameters cfl = microphysics.substep_cfl Cᵨ = microphysics.density_scale @@ -448,7 +448,7 @@ end qˡ_sum = qᶜˡ + qʳ qᵗ = max(qᵗ, qˡ_sum) qᵛ = qᵗ - qˡ_sum - + # Convert to mixing ratios for Kessler physics q = MoistureMassFractions(qᵛ, qˡ_sum) r = MoistureMixingRatio(q) diff --git a/src/PotentialTemperatureFormulations/potential_temperature_formulation.jl b/src/PotentialTemperatureFormulations/potential_temperature_formulation.jl index 0d5edf15..3c97f420 100644 --- a/src/PotentialTemperatureFormulations/potential_temperature_formulation.jl +++ b/src/PotentialTemperatureFormulations/potential_temperature_formulation.jl @@ -124,4 +124,3 @@ function Base.show(io::IO, formulation::LiquidIcePotentialTemperatureFormulation print(io, "└── potential_temperature: ", prettysummary(formulation.potential_temperature)) end end - diff --git a/src/StaticEnergyFormulations/static_energy_formulation.jl b/src/StaticEnergyFormulations/static_energy_formulation.jl index 13cc67c8..82118744 100644 --- a/src/StaticEnergyFormulations/static_energy_formulation.jl +++ b/src/StaticEnergyFormulations/static_energy_formulation.jl @@ -124,4 +124,3 @@ function Base.show(io::IO, formulation::StaticEnergyFormulation) print(io, "└── specific_energy: ", prettysummary(formulation.specific_energy)) end end - diff --git a/src/Thermodynamics/dynamic_states.jl b/src/Thermodynamics/dynamic_states.jl index 3f7f6e80..d5b70173 100644 --- a/src/Thermodynamics/dynamic_states.jl +++ b/src/Thermodynamics/dynamic_states.jl @@ -54,7 +54,7 @@ end qˡ = q.liquid qⁱ = q.ice - return Π * θ + (ℒˡᵣ * qˡ + ℒⁱᵣ * qⁱ) / cᵖᵐ + return Π * θ + (ℒˡᵣ * qˡ + ℒⁱᵣ * qⁱ) / cᵖᵐ end @inline function with_temperature(𝒰::LiquidIcePotentialTemperatureState, T, constants) @@ -125,4 +125,4 @@ end e = cᵖᵐ * T + g * z - ℒˡᵣ * qˡ - ℒⁱᵣ * qⁱ return StaticEnergyState(e, q, z, 𝒰.reference_pressure) -end \ No newline at end of file +end diff --git a/src/Thermodynamics/thermodynamics_constants.jl b/src/Thermodynamics/thermodynamics_constants.jl index fc2df882..26965392 100644 --- a/src/Thermodynamics/thermodynamics_constants.jl +++ b/src/Thermodynamics/thermodynamics_constants.jl @@ -423,7 +423,7 @@ end ##### ##### Moisture mixing ratios -##### +##### struct MoistureMixingRatio{FT} vapor :: FT @@ -517,4 +517,3 @@ Converts mixing ratios to mass fractions and calls `mixture_heat_capacity(q::MMF @inline function mixture_heat_capacity(r::MR, constants::TC) return mixture_heat_capacity(MoistureMassFractions(r), constants) end - diff --git a/src/Thermodynamics/vapor_saturation.jl b/src/Thermodynamics/vapor_saturation.jl index b00d59bc..4e800b5b 100644 --- a/src/Thermodynamics/vapor_saturation.jl +++ b/src/Thermodynamics/vapor_saturation.jl @@ -107,7 +107,7 @@ Compute the supersaturation ``𝒮 = pᵛ/pᵛ⁺ - 1`` over a given `surface`. # Arguments - `T`: Temperature -- `ρ`: Total air density +- `ρ`: Total air density - `q`: `MoistureMassFractions` containing vapor, liquid, and ice mass fractions - `constants`: `ThermodynamicConstants` - `surface`: Surface type (e.g., `PlanarLiquidSurface()`, `PlanarIceSurface()`) diff --git a/test/advection_schemes.jl b/test/advection_schemes.jl index e4cefba5..15c3910a 100644 --- a/test/advection_schemes.jl +++ b/test/advection_schemes.jl @@ -15,7 +15,7 @@ using Test @testset "Default advection schemes" begin static_energy_model = AtmosphereModel(grid; thermodynamic_constants=constants, dynamics, formulation=:StaticEnergy) - potential_temperature_model = AtmosphereModel(grid; thermodynamic_constants=constants, dynamics, + potential_temperature_model = AtmosphereModel(grid; thermodynamic_constants=constants, dynamics, formulation=:LiquidIcePotentialTemperature) @test static_energy_model.advection.ρe isa Centered @@ -119,4 +119,3 @@ using Test end end end - diff --git a/test/all_sky_radiative_transfer.jl b/test/all_sky_radiative_transfer.jl index 7fb66877..4fcc5168 100644 --- a/test/all_sky_radiative_transfer.jl +++ b/test/all_sky_radiative_transfer.jl @@ -156,4 +156,3 @@ using RRTMGP @test all(isfinite, interior(radiation.upwelling_longwave_flux)) end end - diff --git a/test/atmosphere_model_construction.jl b/test/atmosphere_model_construction.jl index 8f6e32b1..9fcd8f38 100644 --- a/test/atmosphere_model_construction.jl +++ b/test/atmosphere_model_construction.jl @@ -122,4 +122,3 @@ end @test model.clock.iteration == 1 end end - diff --git a/test/cloud_microphysics_1M.jl b/test/cloud_microphysics_1M.jl index 96766a72..51095ff5 100644 --- a/test/cloud_microphysics_1M.jl +++ b/test/cloud_microphysics_1M.jl @@ -284,7 +284,7 @@ end # rain sedimentation (terminal velocity) creates a flux divergence that # exactly cancels the autoconversion tendency. With multiple levels, # rain can accumulate in the domain before sedimenting out. - + Oceananigans.defaults.FloatType = FT Nz = 10 grid = RectilinearGrid(default_arch; size=(1, 1, Nz), x=(0, 1), y=(0, 1), z=(0, 1000), @@ -326,7 +326,7 @@ end # Rain should exist somewhere in the domain # (Even if some has sedimented out, there should be rain in upper cells) @test qʳ_max_final > FT(1e-8) # At least some rain exists - + # Check that autoconversion is happening by verifying rain increases initially # before sedimentation can remove it all. We'll check the top cell which # should accumulate rain without losing it to sedimentation as quickly. @@ -337,7 +337,7 @@ end @testset "ImpenetrableBoundaryCondition prevents rain from exiting domain [$(FT)]" for FT in test_float_types() # This test verifies that ImpenetrableBoundaryCondition allows rain to accumulate # in a single-cell domain where it would otherwise sediment out. - + Oceananigans.defaults.FloatType = FT grid = RectilinearGrid(default_arch; size=(1, 1, 1), x=(0, 1), y=(0, 1), z=(0, 1), topology=(Periodic, Periodic, Bounded)) @@ -361,7 +361,7 @@ end # With ImpenetrableBoundaryCondition, rain should accumulate in the domain # because it can't sediment out through the bottom qʳ_final = @allowscalar model.microphysical_fields.qʳ[1, 1, 1] - + # Check terminal velocity at bottom is zero (impenetrable) wʳ_bottom = @allowscalar model.microphysical_fields.wʳ[1, 1, 1] @test wʳ_bottom == 0 # Terminal velocity should be zero at impenetrable bottom diff --git a/test/diagnostics.jl b/test/diagnostics.jl index 3f2abcf9..b56c4aa3 100644 --- a/test/diagnostics.jl +++ b/test/diagnostics.jl @@ -184,4 +184,3 @@ end @test ph ≈ p_expected end - diff --git a/test/geostrophic_subsidence_forcings.jl b/test/geostrophic_subsidence_forcings.jl index c5863995..5e2ffd7a 100644 --- a/test/geostrophic_subsidence_forcings.jl +++ b/test/geostrophic_subsidence_forcings.jl @@ -61,7 +61,7 @@ end @testset "SubsidenceForcing with LiquidIcePotentialTemperature [$(FT)]" for FT in test_float_types() Oceananigans.defaults.FloatType = FT - + Nz = 10 Hz = 1000 # 1 km domain height grid = RectilinearGrid(default_arch; size=(4, 4, Nz), x=(0, 100), y=(0, 100), z=(0, Hz)) @@ -99,10 +99,10 @@ end end ρqᵗ_final = sum(model.moisture_density) - + # Check simulation didn't produce NaN @test !isnan(ρqᵗ_final) - + # With downward subsidence (wˢ < 0) and moisture decreasing with height (∂qᵗ/∂z < 0), # the subsidence forcing is: F_ρqᵗ = -ρᵣ * wˢ * ∂qᵗ/∂z = -ρᵣ * (-0.01) * (-Γq) < 0 # So moisture should DECREASE diff --git a/test/kinematic_driver.jl b/test/kinematic_driver.jl index 5e94495b..b4078953 100644 --- a/test/kinematic_driver.jl +++ b/test/kinematic_driver.jl @@ -47,25 +47,25 @@ using Test model = AtmosphereModel(grid; dynamics=PrescribedDynamics(reference_state)) @test model isa KinematicModel @test model.pressure_solver === nothing - + set!(model, θ=300, qᵗ=0.01, w=1) @test @allowscalar(model.velocities.w[1, 1, 4]) ≈ FT(1) - + time_step!(model, 1) @test model.clock.iteration == 1 end @testset "KinematicModel with PrescribedVelocityFields" begin w_evolving(x, y, z, t) = (1 - exp(-t / 100)) * sin(π * z / 2000) - + model = AtmosphereModel(grid; dynamics = PrescribedDynamics(reference_state), velocities = PrescribedVelocityFields(w=w_evolving)) - + @test model isa KinematicModel set!(model, θ=300, qᵗ=0.01) @test_throws ArgumentError set!(model, w=1) - + time_step!(model, 10) @test model.clock.time ≈ 10 end @@ -74,7 +74,7 @@ using Test w_inlet(x, y, t) = FT(0.5) w_bcs = FieldBoundaryConditions(bottom=OpenBoundaryCondition(w_inlet)) boundary_conditions = (; w = w_bcs) - + model = AtmosphereModel(grid; dynamics=PrescribedDynamics(reference_state), boundary_conditions) @test model isa KinematicModel @test model.velocities.w.boundary_conditions.bottom isa Oceananigans.BoundaryConditions.BoundaryCondition @@ -87,10 +87,10 @@ end @testset "Gaussian advection (analytical solution) [Float64]" begin FT = Float64 Oceananigans.defaults.FloatType = FT - + Lz, Nz, w₀ = 4000, 64, 10 # Reduced resolution for faster test grid = RectilinearGrid(default_arch; size=(4, 4, Nz), x=(0, 100), y=(0, 100), z=(0, Lz)) - + model = AtmosphereModel(grid; dynamics = PrescribedDynamics(ReferenceState(grid, ThermodynamicConstants())), tracers = :c, diff --git a/test/set_atmosphere_model.jl b/test/set_atmosphere_model.jl index ce128fff..61f8e541 100644 --- a/test/set_atmosphere_model.jl +++ b/test/set_atmosphere_model.jl @@ -141,4 +141,3 @@ end @test @allowscalar all(x -> x ≤ 1.01, interior(ℋ_field)) end end - diff --git a/test/unit_tests.jl b/test/unit_tests.jl index 2fa84594..f478ee84 100644 --- a/test/unit_tests.jl +++ b/test/unit_tests.jl @@ -44,7 +44,7 @@ using Breeze.AtmosphereModels: dynamics_density, dynamics_pressure reference_state = ReferenceState(grid, constants) dynamics_stub = AnelasticDynamics(reference_state) boundary_conditions = NamedTuple() - + dynamics = materialize_dynamics(dynamics_stub, grid, boundary_conditions, constants) @test dynamics isa AnelasticDynamics diff --git a/test/vertical_diffusion.jl b/test/vertical_diffusion.jl index c8022d9d..848ec7d4 100644 --- a/test/vertical_diffusion.jl +++ b/test/vertical_diffusion.jl @@ -135,4 +135,3 @@ using Test @test isapprox(numerical_decay_c, expected_decay_c, rtol=0.05) end end - diff --git a/validation/topography/mountain_wave.jl b/validation/topography/mountain_wave.jl index 6461f1df..23a9ed94 100644 --- a/validation/topography/mountain_wave.jl +++ b/validation/topography/mountain_wave.jl @@ -3,7 +3,7 @@ using Oceananigans.Units using CUDA # Schär mountain wave test case -# References: +# References: # Klemp et al. (2015) "Idealized global nonhydrostatic atmospheric test cases on a reduced-radius sphere" # Schär et al. (2002) "A New Terrain-Following Vertical Coordinate Formulation for Atmospheric Prediction Models" @@ -12,7 +12,7 @@ using CUDA # 2) Open lateral boundary conditions have not been implemented yet; periodic boundaries are used instead, which is not ideal for this test case. -# Problem parameters +# Problem parameters thermo = ThermodynamicConstants() g = thermo.gravitational_acceleration cᵖᵈ = thermo.dry_air.heat_capacity