Skip to content

Commit

Permalink
Merge pull request #7 from CliMA/bm/interface_renaming
Browse files Browse the repository at this point in the history
Rename CplState Interface
  • Loading branch information
LenkaNovak authored May 27, 2021
2 parents d679658 + bfc7485 commit 1f019ab
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 48 deletions.
10 changes: 5 additions & 5 deletions docs/src/couplerstate.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Coupler Object

The CouplerMachine defines a type ```CplState``` for a _container_ variable that holds information about the field
values that are being used to couple between components. Components can use a ```put!``` operation to
export a set of field values to a ```CplState``` variable. A ```get``` operation is used to retrieve
values that are being used to couple between components. Components can use a ```coupler_put!``` operation to
export a set of field values to a ```CplState``` variable. A ```coupler_get``` operation is used to retrieve
a set field values from a ```CplState``` variable.

## Coupler Object API

```@docs
CouplerMachine.CplState
CouplerMachine.register_cpl_field!
CouplerMachine.put!
CouplerMachine.get
CouplerMachine.coupler_register!
CouplerMachine.coupler_put!
CouplerMachine.coupler_get
```
8 changes: 4 additions & 4 deletions experiments/AdvectionDiffusion/CplMainBL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ function preatmos(csolver)
mO = csolver.component_list.ocean.component_model
# Set boundary SST used in atmos to SST of ocean surface at start of coupling cycle.
mA.discretization.state_auxiliary.θ_secondary[mA.boundary] .=
CouplerMachine.get(csolver.coupler, :Ocean_SST, mA.grid, DateTime(0), u"°C")
coupler_get(csolver.coupler, :Ocean_SST, mA.grid, DateTime(0), u"°C")
# Set atmos boundary flux accumulator to 0.
mA.state.F_accum .= 0

Expand All @@ -638,7 +638,7 @@ function postatmos(csolver)
mO = csolver.component_list.ocean.component_model
# Pass atmos exports to "coupler" namespace
# 1. Save mean θ flux at the Atmos boundary during the coupling period
CouplerMachine.put!(csolver.coupler, :Atmos_MeanAirSeaθFlux, mA.state.F_accum[mA.boundary] ./ csolver.dt,
coupler_put!(csolver.coupler, :Atmos_MeanAirSeaθFlux, mA.state.F_accum[mA.boundary] ./ csolver.dt,
mA.grid, DateTime(0), u"°C")

@info(
Expand All @@ -663,7 +663,7 @@ function preocean(csolver)
mO = csolver.component_list.ocean.component_model
# Set mean air-sea theta flux
mO.discretization.state_auxiliary.F_prescribed[mO.boundary] .=
CouplerMachine.get(csolver.coupler, :Atmos_MeanAirSeaθFlux, mO.grid, DateTime(0), u"°C")
coupler_get(csolver.coupler, :Atmos_MeanAirSeaθFlux, mO.grid, DateTime(0), u"°C")
# Set ocean boundary flux accumulator to 0. (this isn't used)
mO.state.F_accum .= 0

Expand Down Expand Up @@ -691,7 +691,7 @@ function postocean(csolver)

# Pass ocean exports to "coupler" namespace
# 1. Ocean SST (value of θ at z=0)
CouplerMachine.put!(csolver.coupler, :Ocean_SST, mO.state.θ[mO.boundary], mO.grid, DateTime(0), u"°C")
coupler_put!(csolver.coupler, :Ocean_SST, mO.state.θ[mO.boundary], mO.grid, DateTime(0), u"°C")
end


Expand Down
4 changes: 2 additions & 2 deletions experiments/AdvectionDiffusion/run_script_v2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ function main(::Type{FT}) where {FT}
# Create a Coupler State object for holding import/export fields.
# Try using Dict here - not sure if that will be OK with GPU
coupler = CplState()
register_cpl_field!(coupler, :Ocean_SST, deepcopy(mO.state.θ[mO.boundary]), mO.grid, DateTime(0), u"°C")
register_cpl_field!(coupler, :Atmos_MeanAirSeaθFlux, deepcopy(mA.state.F_accum[mA.boundary]), mA.grid, DateTime(0), u"°C")
coupler_register!(coupler, :Ocean_SST, deepcopy(mO.state.θ[mO.boundary]), mO.grid, DateTime(0), u"°C")
coupler_register!(coupler, :Atmos_MeanAirSeaθFlux, deepcopy(mA.state.F_accum[mA.boundary]), mA.grid, DateTime(0), u"°C")


# Instantiate a coupled timestepper that steps forward the components and
Expand Down
12 changes: 6 additions & 6 deletions experiments/DesignTests/simple_2testcomp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ function main(::Type{FT}) where {FT}

## Create a Coupler State object for holding import/export fields.
coupler = CplState()
register_cpl_field!(coupler, :Ocean_SST, deepcopy(mO.state.θ[mO.boundary]), mO.grid, DateTime(0), u"°C")
register_cpl_field!(coupler, :Atmos_MeanAirSeaθFlux, deepcopy(mA.state.F_accum[mA.boundary]), mA.grid, DateTime(0), u"°C")
coupler_register!(coupler, :Ocean_SST, deepcopy(mO.state.θ[mO.boundary]), mO.grid, DateTime(0), u"°C")
coupler_register!(coupler, :Atmos_MeanAirSeaθFlux, deepcopy(mA.state.F_accum[mA.boundary]), mA.grid, DateTime(0), u"°C")

## Instantiate a coupled timestepper that steps forward the components and
## implements mapings between components export bondary states and
Expand Down Expand Up @@ -152,7 +152,7 @@ function preatmos(csolver)

## Set boundary SST used in atmos to SST of ocean surface at start of coupling cycle.
mA.discretization.state_auxiliary.θ_secondary[mA.boundary] .=
CouplerMachine.get(csolver.coupler, :Ocean_SST, mA.grid, DateTime(0), u"°C")
coupler_get(csolver.coupler, :Ocean_SST, mA.grid, DateTime(0), u"°C")
## Set atmos boundary flux accumulator to 0.
mA.state.F_accum .= 0

Expand All @@ -172,7 +172,7 @@ function postatmos(csolver)

## Pass atmos exports to "coupler" namespace
## 1. Save mean θ flux at the Atmos boundary during the coupling period
CouplerMachine.put!(csolver.coupler, :Atmos_MeanAirSeaθFlux, mA.state.F_accum[mA.boundary] ./ csolver.dt,
coupler_put!(csolver.coupler, :Atmos_MeanAirSeaθFlux, mA.state.F_accum[mA.boundary] ./ csolver.dt,
mA.grid, DateTime(0), u"°C")

@info(
Expand All @@ -197,7 +197,7 @@ function preocean(csolver)

## Set mean air-sea theta flux
mO.discretization.state_auxiliary.F_prescribed[mO.boundary] .=
CouplerMachine.get(csolver.coupler, :Atmos_MeanAirSeaθFlux, mO.grid, DateTime(0), u"°C")
coupler_get(csolver.coupler, :Atmos_MeanAirSeaθFlux, mO.grid, DateTime(0), u"°C")
## Set ocean boundary flux accumulator to 0. (this isn't used)
mO.state.F_accum .= 0

Expand All @@ -224,7 +224,7 @@ function postocean(csolver)

## Pass ocean exports to "coupler" namespace
## 1. Ocean SST (value of θ at z=0)
CouplerMachine.put!(csolver.coupler, :Ocean_SST, mO.state.θ[mO.boundary], mO.grid, DateTime(0), u"°C")
coupler_put!(csolver.coupler, :Ocean_SST, mO.state.θ[mO.boundary], mO.grid, DateTime(0), u"°C")
end

# # Specify balance law
Expand Down
14 changes: 7 additions & 7 deletions src/CplState.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Unitful, Dates
using PrettyTables

export CplState, put!, get, register_cpl_field!
export CplState, coupler_put!, coupler_get, coupler_register!

# TODO: Build constructor that uses a model component's grid.
struct CplGridInfo{GT, GP, GH, GE}
Expand Down Expand Up @@ -39,7 +39,7 @@ function CplState()
end

"""
Coupling.register_cpl_field!(
Coupling.coupler_register!(
coupler::CplState,
fieldname::Symbol,
fieldvalue,
Expand All @@ -58,7 +58,7 @@ Add a field to the coupler that is accessible with key `fieldname`.
- `datetime`: time associated with the field state.
- `units`: units associated with the field values. Dimensionless by default.
"""
function register_cpl_field!(
function coupler_register!(
coupler::CplState,
fieldname::Symbol,
fieldvalue,
Expand All @@ -71,14 +71,14 @@ function register_cpl_field!(
end

"""
get(coupler::CplState, fieldname::Symbol, gridinfo, datetime::DateTime, units::Unitful.Units)
coupler_get(coupler::CplState, fieldname::Symbol, gridinfo, datetime::DateTime, units::Unitful.Units)
Retrieve data array corresponding to `fieldname`.
Returns data on the grid specified by `gridinfo` and in the units of `units`. Checks that
the coupler data field is the state at time `datetime`.
"""
function get(coupler::CplState, fieldname::Symbol, gridinfo, datetime::DateTime, units::Unitful.Units)
function coupler_get(coupler::CplState, fieldname::Symbol, gridinfo, datetime::DateTime, units::Unitful.Units)
cplfield = coupler.CplStateBlob[fieldname]

# check that retrieving component and coupler are at same time
Expand All @@ -91,14 +91,14 @@ function get(coupler::CplState, fieldname::Symbol, gridinfo, datetime::DateTime,
end

"""
put!(coupler::CplState, fieldname::Symbol, fieldvalue, gridinfo, datetime::DateTime, units::Unitful.Units)
coupler_put!(coupler::CplState, fieldname::Symbol, fieldvalue, gridinfo, datetime::DateTime, units::Unitful.Units)
Updates coupler field `fieldname` with `fieldvalue`, the field's value at time `datetime`.
`gridinfo` and `units` inform the coupler of the format of the inputted data
allowing conversion to match the grid and units of the coupler field.
"""
function put!(coupler::CplState, fieldname::Symbol, fieldvalue, gridinfo, datetime::DateTime, units::Unitful.Units)
function coupler_put!(coupler::CplState, fieldname::Symbol, fieldvalue, gridinfo, datetime::DateTime, units::Unitful.Units)
cplfield = coupler.CplStateBlob[fieldname]

# map new data to grid of coupler field; new data -> coupler grid
Expand Down
48 changes: 24 additions & 24 deletions test/cplstate_interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,45 @@ using CouplerMachine, Dates, Unitful

data = rand(10,10)
date = DateTime(2021)
register_cpl_field!(coupler, :test1, data, nothing, date, u"kg")
register_cpl_field!(coupler, :test2, data, nothing, date, u"km/hr")
register_cpl_field!(coupler, :test3, data, nothing, date, u"°C")
coupler_register!(coupler, :test1, data, nothing, date, u"kg")
coupler_register!(coupler, :test2, data, nothing, date, u"km/hr")
coupler_register!(coupler, :test3, data, nothing, date, u"°C")

@testset "get" begin
@test data === CouplerMachine.get(coupler, :test1, nothing, date, u"kg")
@testset "coupler_get" begin
@test data === coupler_get(coupler, :test1, nothing, date, u"kg")
# unit conversion
@test data .* 1000 == CouplerMachine.get(coupler, :test1, nothing, date, u"g")
@test data .* (5 / 18) == CouplerMachine.get(coupler, :test2, nothing, date, u"m/s")
@test ustrip.(u"°F", data*u"°C") == CouplerMachine.get(coupler, :test3, nothing, date, u"°F")
@test data .* 1000 == coupler_get(coupler, :test1, nothing, date, u"g")
@test data .* (5 / 18) == coupler_get(coupler, :test2, nothing, date, u"m/s")
@test ustrip.(u"°F", data*u"°C") == coupler_get(coupler, :test3, nothing, date, u"°F")

# key not in coupler dict
@test_throws KeyError CouplerMachine.get(coupler, :idontexist, nothing, date, u"kg")
@test_throws KeyError coupler_get(coupler, :idontexist, nothing, date, u"kg")
# retreival at inconsistent datetime
@test_throws ErrorException CouplerMachine.get(coupler, :test1, nothing, DateTime(2022), u"kg")
@test_throws ErrorException coupler_get(coupler, :test1, nothing, DateTime(2022), u"kg")
# incompatible units
@test_throws Unitful.DimensionError CouplerMachine.get(coupler, :test1, nothing, date, u"°C")
@test_throws Unitful.DimensionError coupler_get(coupler, :test1, nothing, date, u"°C")
end

@testset "put!" begin
@testset "coupler_put!" begin
newdata = rand(10,10)
newdate = DateTime(2022)
CouplerMachine.put!(coupler, :test1, newdata, nothing, newdate, u"kg")
coupler_put!(coupler, :test1, newdata, nothing, newdate, u"kg")

@test newdata == CouplerMachine.get(coupler, :test1, nothing, newdate, u"kg")
# put! is in-place
@test newdata !== CouplerMachine.get(coupler, :test1, nothing, newdate, u"g")
@test newdata == coupler_get(coupler, :test1, nothing, newdate, u"kg")
# coupler_put! is in-place
@test newdata !== coupler_get(coupler, :test1, nothing, newdate, u"g")
# unit conversion
CouplerMachine.put!(coupler, :test1, newdata, nothing, newdate, u"g")
@test newdata CouplerMachine.get(coupler, :test1, nothing, newdate, u"g")
coupler_put!(coupler, :test1, newdata, nothing, newdate, u"g")
@test newdata coupler_get(coupler, :test1, nothing, newdate, u"g")

# put! must be to a previously registered field
@test_throws KeyError CouplerMachine.put!(coupler, :idontexist, newdata, nothing, newdate, u"kg")
# coupler_put! must be to a previously registered field
@test_throws KeyError coupler_put!(coupler, :idontexist, newdata, nothing, newdate, u"kg")
# incoming data must match dimensions of registered field
@test_throws DimensionMismatch CouplerMachine.put!(coupler, :test1, rand(10,5), nothing, newdate, u"kg")
@test_throws DimensionMismatch coupler_put!(coupler, :test1, rand(10,5), nothing, newdate, u"kg")
# incompatible units
@test_throws Unitful.DimensionError CouplerMachine.put!(coupler, :test1, newdata, nothing, newdate, u"J/m")
# put! updates coupler timestamp
@test_throws ErrorException CouplerMachine.get(coupler, :test1, nothing, date, u"kg")
@test_throws Unitful.DimensionError coupler_put!(coupler, :test1, newdata, nothing, newdate, u"J/m")
# coupler_put! updates coupler timestamp
@test_throws ErrorException coupler_get(coupler, :test1, nothing, date, u"kg")
end

@testset "grid interpolation" begin
Expand Down

0 comments on commit 1f019ab

Please sign in to comment.