Skip to content

Commit

Permalink
move CoupledSim to Interfacer
Browse files Browse the repository at this point in the history
  • Loading branch information
juliasloan25 committed Oct 5, 2023
1 parent 0e4e570 commit fc284b5
Showing 18 changed files with 189 additions and 165 deletions.
2 changes: 1 addition & 1 deletion docs/src/interfacer.md
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
This module contains functions for defining the interface for coupling component models, as well as stub objects that contain prescribed fields.

## Coupled Simulation
- `CoupledSimulation` (`cs`, currently in Utilities - TODO) stores info for ESM run. We require that each `cs` contains four (`atmos_sim`, `land_sim`, `ocean_sim` and `ice_sim`) components. While this requirement will not be eventually needed, for the time being, if a simulation surface type is not needed for a given run, it should be initialized with `SurfaceStub` with a zero `area_fracion`. The `atmos_sim` should always be specified.
- `CoupledSimulation` (`cs`) stores info for ESM run. We require that each `cs` contains four (`atmos_sim`, `land_sim`, `ocean_sim` and `ice_sim`) components. While this requirement will not be eventually needed, for the time being, if a simulation surface type is not needed for a given run, it should be initialized with `SurfaceStub` with a zero `area_fracion`. The `atmos_sim` should always be specified.

## Component model simulations
- all Simulations that are not the `CoupledSimulation` fall under `ComponentModelSimulation`
4 changes: 3 additions & 1 deletion experiments/AMIP/modular/coupler_driver_modular.jl
Original file line number Diff line number Diff line change
@@ -73,14 +73,16 @@ import ClimaCoupler.Regridder:
update_surface_fractions!, combine_surfaces!, combine_surfaces_from_sol!, dummmy_remap!, binary_mask
import ClimaCoupler.ConservationChecker:
EnergyConservationCheck, WaterConservationCheck, check_conservation!, plot_global_conservation
import ClimaCoupler.Utilities: CoupledSimulation, float_type, swap_space!
import ClimaCoupler.Utilities: swap_space!
import ClimaCoupler.BCReader:
bcfile_info_init, float_type_bcf, update_midmonth_data!, next_date_in_file, interpolate_midmonth_to_daily
import ClimaCoupler.TimeManager: current_date, datetime_to_strdate, trigger_callback, Monthly, EveryTimestep
import ClimaCoupler.Diagnostics: get_var, init_diagnostics, accumulate_diagnostics!, save_diagnostics, TimeMean
import ClimaCoupler.PostProcessor: postprocess

import ClimaCoupler.Interfacer:
CoupledSimulation,
float_type,
AtmosModelSimulation,
SurfaceModelSimulation,
SurfaceStub,
1 change: 1 addition & 0 deletions experiments/AMIP/modular/user_io/user_diagnostics.jl
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
# Atmos diagnostics
import ClimaAtmos.Parameters as CAP
import Thermodynamics as TD
using ClimaCoupler.Interfacer: CoupledSimulation, float_type

"""
get_var(cs::CoupledSimulation, ::Val{:T})
31 changes: 19 additions & 12 deletions src/ConservationChecker.jl
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@ This module contains functions that check global conservation of energy and wate
module ConservationChecker

using ClimaCore: ClimaCore, Geometry, Meshes, Domains, Topologies, Spaces, Fields, InputOutput
using ClimaCore.Utilities: half
using ClimaComms
using NCDatasets
using ClimaCoreTempestRemap
@@ -16,7 +15,7 @@ using UnPack
using Plots
using ClimaAtmos: RRTMGPI
using ClimaLSM
using ClimaCoupler.Utilities: CoupledSimulation, swap_space!
using ClimaCoupler.Utilities: swap_space!
import ClimaCoupler: Interfacer

export AbstractConservationCheck,
@@ -61,25 +60,29 @@ end
Interfacer.name(::WaterConservationCheck) = "water [kg]"

"""
check_conservation!(coupler_sim::CoupledSimulation; runtime_check = false)
check_conservation!(coupler_sim::Interfacer.CoupledSimulation; runtime_check = false)
itertes over all specified conservation checks.
"""
check_conservation!(coupler_sim::CoupledSimulation; runtime_check = false) =
check_conservation!(coupler_sim::Interfacer.CoupledSimulation; runtime_check = false) =
map(x -> check_conservation!(x, coupler_sim, runtime_check), coupler_sim.conservation_checks)

"""
check_conservation!(
cc::EnergyConservationCheck,
coupler_sim,
coupler_sim::Interfacer.CoupledSimulation,
runtime_check = false,
)
computes the total energy, ∫ ρe dV, of the model components
of the coupled simulations and the TOA radiation, and updates
`cc` with these values.
"""
function check_conservation!(cc::EnergyConservationCheck, coupler_sim::CoupledSimulation, runtime_check = false)
function check_conservation!(
cc::EnergyConservationCheck,
coupler_sim::Interfacer.CoupledSimulation,
runtime_check = false,
)

ccs = cc.sums
@unpack model_sims = coupler_sim
@@ -139,7 +142,7 @@ end
"""
check_conservation!(
cc::WaterConservationCheck,
coupler_sim,
coupler_sim::Interfacer.CoupledSimulation,
runtime_check = false,
)
@@ -148,7 +151,11 @@ of the coupled simulations, and updates `cc` with the values.
Note: in the future this should not use `push!`.
"""
function check_conservation!(cc::WaterConservationCheck, coupler_sim::CoupledSimulation, runtime_check = false)
function check_conservation!(
cc::WaterConservationCheck,
coupler_sim::Interfacer.CoupledSimulation,
runtime_check = false,
)

ccs = cc.sums
@unpack model_sims = coupler_sim
@@ -197,11 +204,11 @@ function check_conservation!(cc::WaterConservationCheck, coupler_sim::CoupledSim
end

"""
surface_water_gain_from_rates(cs)
surface_water_gain_from_rates(cs::Interfacer.CoupledSimulation)
Determines the total water content gain/loss of a surface from the begining of the simulation based on evaporation and precipitation rates.
"""
function surface_water_gain_from_rates(cs::CoupledSimulation)
function surface_water_gain_from_rates(cs::Interfacer.CoupledSimulation)
evaporation = cs.fields.F_turb_moisture # kg / m^2 / s / layer depth
precipitation_l = cs.fields.P_liq
precipitation_s = cs.fields.P_snow
@@ -214,7 +221,7 @@ ENV["GKSwstype"] = "nul"
"""
plot_global_conservation(
cc::EnergyConservationCheck,
coupler_sim::CoupledSimulation;
coupler_sim::Interfacer.CoupledSimulation;
figname1 = "total_energy.png",
figname2 = "total_energy_log.png",
)
@@ -226,7 +233,7 @@ relative to the initial value;
"""
function plot_global_conservation(
cc::AbstractConservationCheck,
coupler_sim::CoupledSimulation;
coupler_sim::Interfacer.CoupledSimulation;
figname1 = "total.png",
figname2 = "total_log.png",
)
2 changes: 1 addition & 1 deletion src/Diagnostics.jl
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ This module contains functions for defining, gathering and outputting online mod
module Diagnostics

using ClimaCore: Spaces, Fields, InputOutput
using ClimaCoupler.Utilities: CoupledSimulation
using ClimaCoupler.Interfacer: CoupledSimulation
using Dates
using ClimaCoupler.TimeManager: AbstractFrequency, Monthly, EveryTimestep, trigger_callback
using ClimaComms
55 changes: 54 additions & 1 deletion src/Interfacer.jl
Original file line number Diff line number Diff line change
@@ -7,7 +7,9 @@ module Interfacer
import Thermodynamics as TD

using ClimaCore: Fields
export ComponentModelSimulation,
export CoupledSimulation,
float_type,
ComponentModelSimulation,
AtmosModelSimulation,
SurfaceModelSimulation,
SurfaceStub,
@@ -18,6 +20,57 @@ export ComponentModelSimulation,
get_field,
update_field!


"""
AbstractSimulation
An abstract super-type representing a simulation.
"""
abstract type AbstractSimulation{FT} end

"""
CoupledSimulation
Stores information needed to run a simulation with the coupler.
"""
struct CoupledSimulation{
FT <: Real,
X,
D,
B,
FV,
P,
E,
TS,
TI <: Real,
DTI <: Real,
NTSM <: NamedTuple,
NTMS <: NamedTuple,
NTM <: NamedTuple,
}
comms_ctx::X
dates::D
boundary_space::B
fields::FV
parsed_args::P
conservation_checks::E
tspan::TS
t::TI
Δt_cpl::DTI
surface_fractions::NTSM
model_sims::NTMS
mode::NTM
diagnostics::Tuple
end

CoupledSimulation{FT}(args...) where {FT} = CoupledSimulation{FT, typeof.(args[1:12])...}(args...)

"""
float_type(::CoupledSimulation)
Return the floating point type backing `T`: `T` can either be an object or a type.
"""
float_type(::CoupledSimulation{FT}) where {FT} = FT

"""
ComponentModelSimulation
15 changes: 7 additions & 8 deletions src/Regridder.jl
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ module Regridder

using ..Utilities
using ..TimeManager
using ..Interfacer
using ..Interfacer: CoupledSimulation, float_type, SurfaceModelSimulation, get_field, update_field!
using ClimaCore: Meshes, Domains, Topologies, Spaces, Fields, InputOutput
using ClimaComms
using NCDatasets
@@ -405,9 +405,9 @@ Maintains the invariant that the sum of area fractions is 1 at all points.
"""
function update_surface_fractions!(cs::CoupledSimulation)

FT = Utilities.float_type(cs)
FT = float_type(cs)

ice_d = Interfacer.get_field(cs.model_sims.ice_sim, Val(:area_fraction))
ice_d = get_field(cs.model_sims.ice_sim, Val(:area_fraction))

# static fraction
land_s = cs.surface_fractions.land
@@ -421,8 +421,8 @@ function update_surface_fractions!(cs::CoupledSimulation)
@assert maximum(cs.surface_fractions.ice .+ cs.surface_fractions.land .+ cs.surface_fractions.ocean) FT(1)

# update component models
Interfacer.update_field!(cs.model_sims.ocean_sim, Val(:area_fraction), cs.surface_fractions.ocean)
Interfacer.update_field!(cs.model_sims.ice_sim, Val(:area_fraction), cs.surface_fractions.ice)
update_field!(cs.model_sims.ocean_sim, Val(:area_fraction), cs.surface_fractions.ocean)
update_field!(cs.model_sims.ice_sim, Val(:area_fraction), cs.surface_fractions.ice)


end
@@ -455,9 +455,8 @@ surface simulations. THe result is saved in `combined_field`.
function combine_surfaces!(combined_field::Fields.Field, sims::NamedTuple, field_name::Val)
combined_field .= eltype(combined_field)(0)
for sim in sims
if sim isa Interfacer.SurfaceModelSimulation
combined_field .+=
Interfacer.get_field(sim, Val(:area_fraction)) .* nans_to_zero.(Interfacer.get_field(sim, field_name)) # this ensures that unitialized (masked) areas do not affect (TODO: move to mask / remove)
if sim isa SurfaceModelSimulation
combined_field .+= get_field(sim, Val(:area_fraction)) .* nans_to_zero.(get_field(sim, field_name)) # this ensures that unitialized (masked) areas do not affect (TODO: move to mask / remove)
end
end
end
2 changes: 1 addition & 1 deletion src/TimeManager.jl
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ of data.
"""
module TimeManager

using ..Utilities
using ..Interfacer: CoupledSimulation
using Dates

export current_date,
52 changes: 1 addition & 51 deletions src/Utilities.jl
Original file line number Diff line number Diff line change
@@ -8,57 +8,7 @@ module Utilities

using ClimaCore: Fields, Spaces

export CoupledSimulation, float_type, swap_space!

"""
AbstractSimulation
An abstract super-type representing a simulation.
"""
abstract type AbstractSimulation{FT} end

"""
CoupledSimulation
Stores information needed to run a simulation with the coupler.
"""
struct CoupledSimulation{
FT <: Real,
X,
D,
B,
FV,
P,
E,
TS,
TI <: Real,
DTI <: Real,
NTSM <: NamedTuple,
NTMS <: NamedTuple,
NTM <: NamedTuple,
}
comms_ctx::X
dates::D
boundary_space::B
fields::FV
parsed_args::P
conservation_checks::E
tspan::TS
t::TI
Δt_cpl::DTI
surface_fractions::NTSM
model_sims::NTMS
mode::NTM
diagnostics::Tuple
end

CoupledSimulation{FT}(args...) where {FT} = CoupledSimulation{FT, typeof.(args[1:12])...}(args...)

"""
float_type(::CoupledSimulation)
Return the floating point type backing `T`: `T` can either be an object or a type.
"""
float_type(::CoupledSimulation{FT}) where {FT} = FT
export swap_space!

"""
swap_space!(field_out::Fields.Field, field_in::Fields.Field)
4 changes: 2 additions & 2 deletions test/bcreader_tests.jl
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
Unit tests for ClimaCoupler BCReader module
=#

using ClimaCoupler: Regridder, BCReader, TimeManager, Utilities
using ClimaCoupler: Regridder, BCReader, TimeManager, Interfacer
using ClimaCore: Fields, Meshes, Domains, Topologies, Spaces
using ClimaComms
using Test
@@ -180,7 +180,7 @@ for FT in (Float32, Float64)
SST_all = []
updating_dates = []

cs_t = Utilities.CoupledSimulation{FT}(
cs_t = Interfacer.CoupledSimulation{FT}(
comms_ctx, # comms_ctx
dates, # dates
nothing, # boundary_space
6 changes: 3 additions & 3 deletions test/conservation_checker_tests.jl
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
Unit tests for ClimaCoupler ConservationChecker, with parsed objects mimicking those in the full coupled system
=#

using ClimaCoupler: Utilities, Regridder, TestHelper, Interfacer
using ClimaCoupler: Regridder, TestHelper, Interfacer
using ClimaCoupler.ConservationChecker:
EnergyConservationCheck, WaterConservationCheck, check_conservation!, plot_global_conservation
using ClimaCore: ClimaCore, Geometry, Meshes, Domains, Topologies, Spaces, Fields, InputOutput
@@ -72,7 +72,7 @@ get_field(s::TestLand, ::Val{:area_fraction}) = ones(s.i.space) .* 0.25
@. cf.P_liq = -100

# init
cs = Utilities.CoupledSimulation{FT}(
cs = Interfacer.CoupledSimulation{FT}(
nothing, # comms_ctx
nothing, # dates
space, # boundary_space
@@ -149,7 +149,7 @@ end
@. cf.P_liq = -100

# init
cs = Utilities.CoupledSimulation{FT}(
cs = Interfacer.CoupledSimulation{FT}(
nothing, # comms_ctx
nothing, # dates
space, # boundary_space
10 changes: 8 additions & 2 deletions test/debug/debug_amip_plots.jl
Original file line number Diff line number Diff line change
@@ -4,8 +4,14 @@ using Test
using ClimaCore
using ClimaCoupler: TestHelper
import ClimaCoupler.Interfacer:
update_field!, AtmosModelSimulation, SurfaceModelSimulation, SurfaceStub, get_field, update_field!, name
using ClimaCoupler.Utilities: CoupledSimulation, CoupledSimulation
CoupledSimulation,
update_field!,
AtmosModelSimulation,
SurfaceModelSimulation,
SurfaceStub,
get_field,
update_field!,
name

FT = Float64

Loading

0 comments on commit fc284b5

Please sign in to comment.