Skip to content

Commit

Permalink
Use t_end to determine output frequency
Browse files Browse the repository at this point in the history
The logic is as follows:

If `t_end < 1 day` take hourly means,
if `t_end < 1 year` take daily means,
If `t_end >= 1 year` take monthly means.
  • Loading branch information
Sbozzolo committed Jan 29, 2024
1 parent 8760f6e commit b1cd9d9
Showing 1 changed file with 143 additions and 36 deletions.
179 changes: 143 additions & 36 deletions src/diagnostics/default_diagnostics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,21 @@
# level interfaces, add them here. Feel free to include extra files.

"""
default_diagnostics(model, output_writer)
default_diagnostics(model, t_end; output_writer)
Return a list of `ScheduledDiagnostic`s associated with the given `model` that use
`output_write` to write to disk.
`output_write` to write to disk. `t_end` is the expected simulation end time and it is used
to choose the most reasonable output frequency.
The logic is as follows:
If `t_end < 1 day` take hourly means,
if `t_end < 1 year` take daily means,
If `t_end >= 1 year` take monthly means.
One month is defined as 30 days.
"""
function default_diagnostics(model::AtmosModel; output_writer)
function default_diagnostics(model::AtmosModel, t_end::Real; output_writer)
# Unfortunately, [] is not treated nicely in a map (we would like it to be "excluded"),
# so we need to manually filter out the submodels that don't have defaults associated
# to
Expand All @@ -24,9 +31,13 @@ function default_diagnostics(model::AtmosModel; output_writer)
# We use a map because we want to ensure that diagnostics is a well defined type, not
# Any. This reduces latency.
return vcat(
core_default_diagnostics(output_writer),
core_default_diagnostics(output_writer, t_end),
map(non_empty_fields) do field
default_diagnostics(getfield(model, field); output_writer)
default_diagnostics(
getfield(model, field),
t_end;
output_writer,
)
end...,
)
end
Expand All @@ -38,11 +49,9 @@ end
# submodels that have no given defaults.
default_diagnostics(submodel; output_writer) = []


"""
produce_common_diagnostic_function(period, reduction)
Helper function to define functions like `daily_max`.
"""
function common_diagnostics(
Expand Down Expand Up @@ -70,8 +79,69 @@ function average_pre_output_hook!(accum, counter)
end

"""
daily_maxs(short_names...; output_writer)
monthly_maxs(short_names...; output_writer)
Return a list of `ScheduledDiagnostics` that compute the monthly max for the given variables.
A month is defined as 30 days.
"""
monthly_maxs(short_names...; output_writer) =
common_diagnostics(30 * 24 * 60 * 60, max, output_writer, short_names...)
"""
monthly_max(short_names; output_writer)
Return a `ScheduledDiagnostics` that computes the monthly max for the given variable.
A month is defined as 30 days.
"""
monthly_max(short_names; output_writer) =
monthly_maxs(short_names; output_writer)[1]

"""
monthly_mins(short_names...; output_writer)
Return a list of `ScheduledDiagnostics` that compute the monthly min for the given variables.
"""
monthly_mins(short_names...; output_writer) =
common_diagnostics(30 * 24 * 60 * 60, min, output_writer, short_names...)
"""
monthly_min(short_names; output_writer)
Return a `ScheduledDiagnostics` that computes the monthly min for the given variable.
A month is defined as 30 days.
"""
monthly_min(short_names; output_writer) =
monthly_mins(short_names; output_writer)[1]

"""
monthly_averages(short_names...; output_writer)
Return a list of `ScheduledDiagnostics` that compute the monthly average for the given variables.
A month is defined as 30 days.
"""
# An average is just a sum with a normalization before output
monthly_averages(short_names...; output_writer) = common_diagnostics(
30 * 24 * 60 * 60,
(+),
output_writer,
short_names...;
pre_output_hook! = average_pre_output_hook!,
)
"""
monthly_average(short_names; output_writer)
Return a `ScheduledDiagnostics` that compute the monthly average for the given variable.
A month is defined as 30 days.
"""
# An average is just a sum with a normalization before output
monthly_average(short_names; output_writer) =
daily_averages(short_names; output_writer)[1]

"""
daily_maxs(short_names...; output_writer)
Return a list of `ScheduledDiagnostics` that compute the daily max for the given variables.
"""
Expand All @@ -89,15 +159,13 @@ daily_max(short_names; output_writer) =
"""
daily_mins(short_names...; output_writer)
Return a list of `ScheduledDiagnostics` that compute the daily min for the given variables.
"""
daily_mins(short_names...; output_writer) =
common_diagnostics(24 * 60 * 60, min, output_writer, short_names...)
"""
daily_min(short_names; output_writer)
Return a `ScheduledDiagnostics` that computes the daily min for the given variable.
"""
daily_min(short_names; output_writer) =
Expand All @@ -106,7 +174,6 @@ daily_min(short_names; output_writer) =
"""
daily_averages(short_names...; output_writer)
Return a list of `ScheduledDiagnostics` that compute the daily average for the given variables.
"""
# An average is just a sum with a normalization before output
Expand All @@ -120,16 +187,15 @@ daily_averages(short_names...; output_writer) = common_diagnostics(
"""
daily_average(short_names; output_writer)
Return a `ScheduledDiagnostics` that compute the daily average for the given variable.
"""
# An average is just a sum with a normalization before output
daily_average(short_names; output_writer) =
daily_averages(short_names; output_writer)[1]

"""
hourly_maxs(short_names...; output_writer)
Return a list of `ScheduledDiagnostics` that compute the hourly max for the given variables.
"""
hourly_maxs(short_names...; output_writer) =
Expand All @@ -138,7 +204,6 @@ hourly_maxs(short_names...; output_writer) =
"""
hourly_max(short_names; output_writer)
Return a `ScheduledDiagnostics` that computes the hourly max for the given variable.
"""
hourly_max(short_names...; output_writer) =
Expand All @@ -147,7 +212,6 @@ hourly_max(short_names...; output_writer) =
"""
hourly_mins(short_names...; output_writer)
Return a list of `ScheduledDiagnostics` that compute the hourly min for the given variables.
"""
hourly_mins(short_names...; output_writer) =
Expand All @@ -165,7 +229,6 @@ hourly_min(short_names; output_writer) =
"""
hourly_averages(short_names...; output_writer)
Return a list of `ScheduledDiagnostics` that compute the hourly average for the given variables.
"""
hourly_averages(short_names...; output_writer) = common_diagnostics(
Expand All @@ -179,20 +242,52 @@ hourly_averages(short_names...; output_writer) = common_diagnostics(
"""
hourly_average(short_names...; output_writer)
Return a `ScheduledDiagnostics` that computes the hourly average for the given variable.
"""
hourly_average(short_names; output_writer) =
hourly_averages(short_names; output_writer)[1]


"""
frequency_averages(t_end::Real)
Return the correct averaging function depending on the total simulation time.
If `t_end < 1 day` take hourly means,
if `t_end < 1 year` take daily means,
If `t_end >= 1 year` take monthly means.
One month is defined as 30 days.
"""
function frequency_averages(t_end::Real)
if t_end > 365 * 86400
return monthly_averages
elseif t_end < 86400
return hourly_averages
else
return daily_averages
end
end

# Include all the subdefaults

########
# Core #
########
function core_default_diagnostics(output_writer)
function core_default_diagnostics(output_writer, t_end)
core_diagnostics =
["ts", "ta", "thetaa", "ha", "pfull", "rhoa", "ua", "va", "wa", "hfes"]

average_func = frequency_averages(t_end)

if t_end > 365 * 86400
min_func = monthly_min
max_func = monthly_max
else
min_func = daily_min
max_func = daily_max
end

return [
# We need to compute the topography at the beginning of the simulation (and only at
# the beginning), so we set output_every = 0 (it still called at the first timestep)
Expand All @@ -201,9 +296,9 @@ function core_default_diagnostics(output_writer)
output_every = 0,
output_writer,
),
daily_averages(core_diagnostics...; output_writer)...,
daily_max("ts"; output_writer),
daily_min("ts"; output_writer),
average_func(core_diagnostics...; output_writer)...,
min_func("ts"; output_writer),
max_func("ts"; output_writer),
]
end

Expand All @@ -216,42 +311,51 @@ function default_diagnostics(
) where {T <: Union{EquilMoistModel, NonEquilMoistModel}}
moist_diagnostics = ["hur", "hus", "cl", "clw", "cli", "hussfc", "evspsbl"]

return [daily_averages(moist_diagnostics...; output_writer)...]
average_func = frequency_averages(t_end)

return [average_func(moist_diagnostics...; output_writer)...]
end

#######################
# Precipitation model #
#######################
function default_diagnostics(::Microphysics0Moment; output_writer)
function default_diagnostics(::Microphysics0Moment, t_end; output_writer)
precip_diagnostics = ["pr"]

return [daily_averages(precip_diagnostics...; output_writer)...]
average_func = frequency_averages(t_end)

return [average_func(precip_diagnostics...; output_writer)...]
end

##################
# Radiation mode #
##################
function default_diagnostics(::RRTMGPI.AbstractRRTMGPMode; output_writer)
function default_diagnostics(::RRTMGPI.AbstractRRTMGPMode, t_end; output_writer)
rad_diagnostics = ["rsd", "rsu", "rld", "rlu"]

return [daily_averages(rad_diagnostics...; output_writer)...]
average_func = frequency_averages(t_end)

return [average_func(rad_diagnostics...; output_writer)...]
end


function default_diagnostics(
::RRTMGPI.AllSkyRadiationWithClearSkyDiagnostics;
::RRTMGPI.AllSkyRadiationWithClearSkyDiagnostics,
t_end;
output_writer,
)
rad_diagnostics =
["rsd", "rsu", "rld", "rlu", "rsdcs", "rsucs", "rldcs", "rlucs"]

return [daily_averages(rad_diagnostics...; output_writer)...]
average_func = frequency_averages(t_end)

return [average_func(rad_diagnostics...; output_writer)...]
end

##################
# Turbconv model #
##################
function default_diagnostics(::PrognosticEDMFX; output_writer)
function default_diagnostics(::PrognosticEDMFX, t_end; output_writer)
edmfx_tenmin_diagnostics = [
"ts",
"ta",
Expand Down Expand Up @@ -321,15 +425,17 @@ function default_diagnostics(::PrognosticEDMFX; output_writer)
"lmix",
]

average_func = frequency_averages(t_end)

return [
thirtymin_insts(edmfx_tenmin_diagnostics...; output_writer)...,
daily_averages(edmfx_draft_diagnostics...; output_writer)...,
daily_averages(edmfx_env_diagnostics...; output_writer)...,
average_func(edmfx_draft_diagnostics...; output_writer)...,
average_func(edmfx_env_diagnostics...; output_writer)...,
]
end


function default_diagnostics(::DiagnosticEDMFX; output_writer)
function default_diagnostics(::DiagnosticEDMFX, t_end; output_writer)
diagnostic_edmfx_tenmin_diagnostics = [
"ts",
"ta",
Expand Down Expand Up @@ -364,7 +470,6 @@ function default_diagnostics(::DiagnosticEDMFX; output_writer)
thirtymin_insts(short_names...; output_writer) =
common_diagnostics(30 * 60, nothing, output_writer, short_names...;)


diagnostic_edmfx_draft_diagnostics = [
"arup",
"rhoaup",
Expand All @@ -379,12 +484,14 @@ function default_diagnostics(::DiagnosticEDMFX; output_writer)
]
diagnostic_edmfx_env_diagnostics = ["waen", "tke", "lmix"]

average_func = frequency_averages(t_end)

return [
thirtymin_insts(
diagnostic_edmfx_tenmin_diagnostics...;
output_writer,
)...,
daily_averages(diagnostic_edmfx_draft_diagnostics...; output_writer)...,
daily_averages(diagnostic_edmfx_env_diagnostics...; output_writer)...,
average_func(diagnostic_edmfx_draft_diagnostics...; output_writer)...,
average_func(diagnostic_edmfx_env_diagnostics...; output_writer)...,
]
end

0 comments on commit b1cd9d9

Please sign in to comment.