From 01b4f27a4657adbf41be6f39ddd373fbbcee4576 Mon Sep 17 00:00:00 2001 From: Gabriele Bozzola Date: Tue, 3 Dec 2024 08:42:06 -0800 Subject: [PATCH 1/2] Move SG_quad out of cache There is no reason for SG_quad to be in AtmosCache: it is constant and is firmly attached to a specific function. --- src/cache/cache.jl | 8 +--- src/cache/cloud_fraction.jl | 15 ++++--- src/solver/model_getters.jl | 5 ++- src/solver/types.jl | 79 +++++++++++++++++++---------------- test/coupler_compatibility.jl | 1 - 5 files changed, 56 insertions(+), 52 deletions(-) diff --git a/src/cache/cache.jl b/src/cache/cache.jl index 2dc4215a18..cb86d7c032 100644 --- a/src/cache/cache.jl +++ b/src/cache/cache.jl @@ -6,7 +6,6 @@ struct AtmosCache{ COR, SFC, GHOST, - SGQ, PREC, SCRA, HYPE, @@ -44,9 +43,6 @@ struct AtmosCache{ """Center and face ghost buffers used by DSS""" ghost_buffer::GHOST - """Struct with sub-grid sampling quadrature""" - SG_quad::SGQ - """Quantities that are updated with set_precomputed_quantities!""" precomputed::PREC @@ -144,11 +140,10 @@ function build_cache(Y, atmos, params, surface_setup, sim_info, aerosol_names) sfc_setup = surface_setup(params) scratch = temporary_quantities(Y, atmos) - SG_quad = SGSQuadrature(FT) precomputed = precomputed_quantities(Y, atmos) precomputing_arguments = - (; atmos, core, params, sfc_setup, precomputed, scratch, dt, SG_quad) + (; atmos, core, params, sfc_setup, precomputed, scratch, dt) # Coupler compatibility isnothing(precomputing_arguments.sfc_setup) && @@ -178,7 +173,6 @@ function build_cache(Y, atmos, params, surface_setup, sim_info, aerosol_names) core, sfc_setup, ghost_buffer, - SG_quad, precomputed, scratch, hyperdiff, diff --git a/src/cache/cloud_fraction.jl b/src/cache/cloud_fraction.jl index c1ce240560..6fc5875e22 100644 --- a/src/cache/cloud_fraction.jl +++ b/src/cache/cloud_fraction.jl @@ -60,9 +60,10 @@ NVTX.@annotate function set_cloud_fraction!( Y, p, ::Union{EquilMoistModel, NonEquilMoistModel}, - ::QuadratureCloud, + qc::QuadratureCloud, ) - (; SG_quad, params) = p + SG_quad = qc.SG_quad + (; params) = p FT = eltype(params) thermo_params = CAP.thermodynamics_params(params) @@ -112,10 +113,11 @@ NVTX.@annotate function set_cloud_fraction!( Y, p, ::Union{EquilMoistModel, NonEquilMoistModel}, - ::SGSQuadratureCloud, + qc::SGSQuadratureCloud, ::DiagnosticEDMFX, ) - (; SG_quad, params) = p + SG_quad = qc.SG_quad + (; params) = p FT = eltype(params) thermo_params = CAP.thermodynamics_params(params) @@ -162,10 +164,11 @@ NVTX.@annotate function set_cloud_fraction!( Y, p, ::Union{EquilMoistModel, NonEquilMoistModel}, - ::SGSQuadratureCloud, + qc::SGSQuadratureCloud, ::PrognosticEDMFX, ) - (; SG_quad, params) = p + SG_quad = qc.SG_quad + (; params) = p FT = eltype(params) thermo_params = CAP.thermodynamics_params(params) diff --git a/src/solver/model_getters.jl b/src/solver/model_getters.jl index 29ef6a1160..5cb9154191 100644 --- a/src/solver/model_getters.jl +++ b/src/solver/model_getters.jl @@ -313,12 +313,13 @@ end function get_cloud_model(parsed_args) cloud_model = parsed_args["cloud_model"] + FT = parsed_args["FLOAT_TYPE"] == "Float64" ? Float64 : Float32 return if cloud_model == "grid_scale" GridScaleCloud() elseif cloud_model == "quadrature" - QuadratureCloud() + QuadratureCloud(SGSQuadrature(FT)) elseif cloud_model == "quadrature_sgs" - SGSQuadratureCloud() + SGSQuadratureCloud(SGSQuadrature(FT)) else error("Invalid cloud_model $(cloud_model)") end diff --git a/src/solver/types.jl b/src/solver/types.jl index 6394389223..16b131ce5c 100644 --- a/src/solver/types.jl +++ b/src/solver/types.jl @@ -16,10 +16,51 @@ struct NoPrecipitation <: AbstractPrecipitationModel end struct Microphysics0Moment <: AbstractPrecipitationModel end struct Microphysics1Moment <: AbstractPrecipitationModel end +# TODO: Add docstrings explaining this +abstract type AbstractQuadratureType end +struct LogNormalQuad <: AbstractQuadratureType end +struct GaussianQuad <: AbstractQuadratureType end + +# TODO: Add docstrings explaining this +abstract type AbstractSGSamplingType end +struct SGSMean <: AbstractSGSamplingType end +struct SGSQuadrature{N, QT, A, W} <: AbstractSGSamplingType + quadrature_type::QT + a::A + w::W + function SGSQuadrature( + ::Type{FT}; + quadrature_name = "gaussian", + quadrature_order = 3, + ) where {FT} + quadrature_type = if quadrature_name == "log-normal" + LogNormalQuad() + elseif quadrature_name == "gaussian" + GaussianQuad() + else + error("Invalid thermodynamics quadrature $(quadrature_name)") + end + N = quadrature_order + # TODO: double check this python-> julia translation + # a, w = np.polynomial.hermite.hermgauss(N) + a, w = FastGaussQuadrature.gausshermite(N) + a, w = SA.SVector{N, FT}(a), SA.SVector{N, FT}(w) + QT = typeof(quadrature_type) + return new{N, QT, typeof(a), typeof(w)}(quadrature_type, a, w) + end +end +quadrature_order(::SGSQuadrature{N}) where {N} = N +quad_type(::SGSQuadrature{N}) where {N} = N #TODO - this seems wrong? + +# TODO: Add docstrings explaining this abstract type AbstractCloudModel end struct GridScaleCloud <: AbstractCloudModel end -struct QuadratureCloud <: AbstractCloudModel end -struct SGSQuadratureCloud <: AbstractCloudModel end +struct QuadratureCloud{SGQ <: AbstractSGSamplingType} <: AbstractCloudModel + SG_quad::SGQ +end +struct SGSQuadratureCloud{SGQ <: AbstractSGSamplingType} <: AbstractCloudModel + SG_quad::SGQ +end abstract type AbstractModelConfig end struct SingleColumnModel <: AbstractModelConfig end @@ -274,40 +315,6 @@ struct GeneralizedDetrainment <: AbstractDetrainmentModel end struct GeneralizedHarmonicsDetrainment <: AbstractDetrainmentModel end struct SmoothAreaDetrainment <: AbstractDetrainmentModel end -abstract type AbstractQuadratureType end -struct LogNormalQuad <: AbstractQuadratureType end -struct GaussianQuad <: AbstractQuadratureType end - -abstract type AbstractSGSamplingType end -struct SGSMean <: AbstractSGSamplingType end -struct SGSQuadrature{N, QT, A, W} <: AbstractSGSamplingType - quadrature_type::QT - a::A - w::W - function SGSQuadrature( - ::Type{FT}; - quadrature_name = "gaussian", - quadrature_order = 3, - ) where {FT} - quadrature_type = if quadrature_name == "log-normal" - LogNormalQuad() - elseif quadrature_name == "gaussian" - GaussianQuad() - else - error("Invalid thermodynamics quadrature $(quadrature_name)") - end - N = quadrature_order - # TODO: double check this python-> julia translation - # a, w = np.polynomial.hermite.hermgauss(N) - a, w = FastGaussQuadrature.gausshermite(N) - a, w = SA.SVector{N, FT}(a), SA.SVector{N, FT}(w) - QT = typeof(quadrature_type) - return new{N, QT, typeof(a), typeof(w)}(quadrature_type, a, w) - end -end -quadrature_order(::SGSQuadrature{N}) where {N} = N -quad_type(::SGSQuadrature{N}) where {N} = N #TODO - this seems wrong? - abstract type AbstractSurfaceThermoState end struct GCMSurfaceThermoState <: AbstractSurfaceThermoState end diff --git a/test/coupler_compatibility.jl b/test/coupler_compatibility.jl index 70fb3a9fa0..84ce515047 100644 --- a/test/coupler_compatibility.jl +++ b/test/coupler_compatibility.jl @@ -72,7 +72,6 @@ const T2 = 290 p.core, sfc_setup, p.ghost_buffer, - p.SG_quad, p.precomputed, p.scratch, p.hyperdiff, From 3fed07101524d5e1154eb2630cd4a6da71c859a7 Mon Sep 17 00:00:00 2001 From: Anna Jaruga Date: Tue, 10 Dec 2024 16:43:36 -0800 Subject: [PATCH 2/2] Remove unused Lognormal quadrature type, add docstrings --- src/cache/cloud_fraction.jl | 4 +- src/solver/types.jl | 73 ++++++++++++++++++++++++------------- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/cache/cloud_fraction.jl b/src/cache/cloud_fraction.jl index 6fc5875e22..f05f78d39f 100644 --- a/src/cache/cloud_fraction.jl +++ b/src/cache/cloud_fraction.jl @@ -223,7 +223,8 @@ end coeff, ᶜlength_scale, thermo_params) where: - - SG_quad is a struct containing information about quadrature type and order + - SG_quad is a struct containing information about Gaussian quadrature order, + sampling point values and weights - ts is the thermodynamic state - ᶜ∇q, ᶜ∇θ are the gradients of q_tot and liquid ice potential temperature - coeff - a free parameter (to be moved into params) @@ -251,7 +252,6 @@ function quad_loop( # and limited covarainces function get_x_hat(χ1, χ2) - @assert SG_quad.quadrature_type isa GaussianQuad FT = eltype(χ1) q′q′ = covariance_from_grad(coeff, ᶜlength_scale, ᶜ∇q, ᶜ∇q) diff --git a/src/solver/types.jl b/src/solver/types.jl index 16b131ce5c..e3cbaa0ff0 100644 --- a/src/solver/types.jl +++ b/src/solver/types.jl @@ -16,48 +16,71 @@ struct NoPrecipitation <: AbstractPrecipitationModel end struct Microphysics0Moment <: AbstractPrecipitationModel end struct Microphysics1Moment <: AbstractPrecipitationModel end -# TODO: Add docstrings explaining this -abstract type AbstractQuadratureType end -struct LogNormalQuad <: AbstractQuadratureType end -struct GaussianQuad <: AbstractQuadratureType end +""" + + AbstractSGSamplingType -# TODO: Add docstrings explaining this +How sub-grid scale diagnostic should be sampled in computing cloud fraction. +""" abstract type AbstractSGSamplingType end + +""" + SGSMean + +Use the mean value. +""" struct SGSMean <: AbstractSGSamplingType end -struct SGSQuadrature{N, QT, A, W} <: AbstractSGSamplingType - quadrature_type::QT - a::A - w::W - function SGSQuadrature( - ::Type{FT}; - quadrature_name = "gaussian", - quadrature_order = 3, - ) where {FT} - quadrature_type = if quadrature_name == "log-normal" - LogNormalQuad() - elseif quadrature_name == "gaussian" - GaussianQuad() - else - error("Invalid thermodynamics quadrature $(quadrature_name)") - end + +""" + SGSQuadrature + +Compute the mean as a weighted sum of the Gauss-Hermite quadrature points. +""" +struct SGSQuadrature{N, A, W} <: AbstractSGSamplingType + a::A # values + w::W # weights + function SGSQuadrature(::Type{FT}; quadrature_order = 3) where {FT} N = quadrature_order # TODO: double check this python-> julia translation # a, w = np.polynomial.hermite.hermgauss(N) a, w = FastGaussQuadrature.gausshermite(N) a, w = SA.SVector{N, FT}(a), SA.SVector{N, FT}(w) - QT = typeof(quadrature_type) - return new{N, QT, typeof(a), typeof(w)}(quadrature_type, a, w) + return new{N, typeof(a), typeof(w)}(a, w) end end quadrature_order(::SGSQuadrature{N}) where {N} = N -quad_type(::SGSQuadrature{N}) where {N} = N #TODO - this seems wrong? -# TODO: Add docstrings explaining this +""" + AbstractCloudModel + +How to compute the cloud fraction. +""" abstract type AbstractCloudModel end + +""" + GridScaleCloud + +Compute the cloud fraction based on grid mean conditions. +""" struct GridScaleCloud <: AbstractCloudModel end + +""" + QuadratureCloud + +Compute the cloud fraction by sampling over the quadrature points, but without +the EDMF sub-grid scale model. +""" struct QuadratureCloud{SGQ <: AbstractSGSamplingType} <: AbstractCloudModel SG_quad::SGQ end + +""" + SGSQuadratureCloud + +Compute the cloud fraction as a sum of the EDMF environment and updraft +contributions. The EDMF environment cloud fraction is computed by sampling over +the quadrature points. +""" struct SGSQuadratureCloud{SGQ <: AbstractSGSamplingType} <: AbstractCloudModel SG_quad::SGQ end