-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Monthly updating of BCs from file #90
Conversation
6a8c10f
to
25104e6
Compare
724ac50
to
26483eb
Compare
93: Interface changes pulled from #90 r=LenkaNovak a=LenkaNovak # PULL REQUEST ## Purpose and Content This PR introduces interface changes which are used in PR #90 . They are split from the main PR to make reviewing of the functionality easier. The changes here include: - reducing arguments in `push!` and `pull` functions by introducing a `CouplerSimulation` struct - unifying names of, and information contained within, model sims. This reduces the number of `if.. else..` statements when running with prescribed or modeled SSTs. - include `SST` and `SIC` in their respective sims While these interface changes are not part of the final coupler interface design, they facilitate the development and running of the models from the coupler in the intermediate term, and will be used in the first AMIP showcase. ## Benefits and Risks - b: less code, more structured - r: interface changes are not the priority (only minimal changes introduced here) ## Linked Issues see #90 ## PR Checklist - [x] This PR has a corresponding issue OR is linked to an SDI. - [x] I have followed CliMA's codebase [contribution](https://clima.github.io/ClimateMachine.jl/latest/Contributing/) and [style](https://clima.github.io/ClimateMachine.jl/latest/DevDocs/CodeStyle/) guidelines OR N/A. - [x] I have followed CliMA's [documentation policy](https://github.com/CliMA/policies/wiki/Documentation-Policy). - [x] I have checked all issues and PRs and I certify that this PR does not duplicate an open PR. - [x] I linted my code on my local machine prior to submission OR N/A. - [x] Unit tests are included OR N/A. - [x] Code used in an integration test OR N/A. - [x] All tests ran successfully on my local machine OR N/A. - [x] All classes, modules, and function contain docstrings OR N/A. - [x] Documentation has been added/updated OR N/A. Co-authored-by: LenkaNovak <lenka@caltech.edu>
a1eec8b
to
6d5c86c
Compare
@@ -120,19 +129,20 @@ end | |||
|
|||
# init coupler | |||
coupler_field_names = (:T_S, :z0m_S, :z0b_S, :ρ_sfc, :q_sfc, :albedo, :F_A, :F_E, :F_R, :P_liq) | |||
coupler_fields = | |||
coupler_fileds = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo?
dates, | ||
boundary_space, | ||
FT, | ||
mask, | ||
coupler_fields, | ||
coupler_fileds, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, I missed this guy during the update! Thanks for catching it! 🐛
|
||
end | ||
|
||
no_scalling(x) = swap_space!(x, axes(mask)) # TODO: mask should not be global |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no_scaling?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe pass in mask as an argument, then it's no longer a global?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually moved this to the bcfile_reader.jl
, where it's easy to obtain the mask. :)
Convert from String ("YYYYMMDD") to Date format | ||
""" | ||
strdate_to_datetime(strdate::String) = | ||
Dates.Date(parse(Int, strdate[1:4]), parse(Int, strdate[5:6]), parse(Int, strdate[7:8])) # required by the official AMIP input files | ||
Dates.DateTime(parse(Int, strdate[1:4]), parse(Int, strdate[5:6]), parse(Int, strdate[7:8])) # required by the official AMIP input files |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this hardcoded to a specific format? should we concerned that that could change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use Dates
, then Date()
and DateTime()
are the default formats, so I would have thought that this is quite safe.
@@ -60,3 +60,6 @@ function ice_init(::Type{FT}; tspan, saveat, dt, space, ice_mask, stepper = Eule | |||
end | |||
|
|||
get_ice_mask(h_ice, FT) = h_ice > FT(0) ? FT(1) : FT(0) | |||
|
|||
# file-specific |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we add a doc string explaining what this is doing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass in mask so that it is not global?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass in FT also
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure :)
@@ -55,3 +55,6 @@ function ocean_init(::Type{FT}; tspan, dt, saveat, space, mask, stepper = Euler( | |||
|
|||
SlabSimulation(params, Y, space, integrator) | |||
end | |||
|
|||
# file specific |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we add a doc string explaining what this is doing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass in mask so that it is not global?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass in FT also
joinpath(coupler_output_dir, "total_energy_bucket.png"), | ||
joinpath(coupler_output_dir, "total_energy_log_bucket.png"), | ||
) | ||
end | ||
|
||
@show coupler_sim.fields.P_liq | ||
@show cs.fields.P_liq |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can remove :) I had added this in debugging a while back
sst_data, | ||
"SST", | ||
boundary_space, | ||
segment_idx0 = [Int(1309)], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hardcoded 1309, is this ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a function that finds the closest index of the file date to the user-elected start date.
cs.mode.SIC_info, | ||
) | ||
SIC = cs.mode.SIC_info.monthly_fields[1] | ||
ice_mask = ice_sim.integrator.p.Ya.ice_mask .= get_ice_mask.(SIC .- FT(50), FT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since 50 is hardcoded, and it appears twice (also on line 113 - maybe make a param we pass in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! I've included it as a keyword argument in get_ice_mask()
.
|
||
else | ||
# ocean | ||
elseif mode_name == "aquaplanet" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is "aquaplanet" a misleading name at all? Not sure the convention. but this "aquaplanet" has land and ice as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually removed the ice. Since one of the goals was to have a full aquaplanet, shall we remove the land too? It means land won't be included in the conservation check though. Maybe going forward, we can have another case like simple_earth
, which demonstrates the conservation of all slab+Bucket components, also with topography?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes! I think both are great ideas. We can have a full aquaplanet and a full land planet, and then AMIP?
Maybe we can get rid of this:
|
I think we should add a buildkite job for the amip mode. Whatever plot you are looking at now to make sure it is doing the right thing should be automatically made as part of CI (otherwise it becomes harder for others to make changes to main, since they wouldnt know what plot to make/check...).. |
) | ||
elseif Dates.days(date - all_dates[Int(midmonth_idx)]) > 2 # throw error when there are closer initial indices for the bc file data that matches this date0 | ||
nearest_idx = | ||
argmin(abs.(parse(FT, datetime_to_strdate(date)) .- parse.(FT, datetime_to_strdate.(all_dates[:])))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
global lookup of FT
Δt::I | ||
t::F | ||
tspan::S |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depending on the type of tspan
, it may not be necessary to also store Δt
. For example, if tspan = tstart:Δt:tstop
then Δt = tspan.step
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be a neat solution! :) I was following the notation of ClimaAtmos
(where they use tspan
to set the ODEProblem
), and I believe Kat did the same for the Bucket. Maybe to be consistent for now, we can suggest this as part of the holistic interface revamp when we explore Dennis's design?
NamedTuple{coupler_field_names}(ntuple(i -> ClimaCore.Fields.zeros(boundary_space), length(coupler_field_names))) | ||
model_sims = (atm = atmos_sim, ice = ice_sim, lnd = land_sim, ocn = ocean_sim) | ||
dates = (; date = [date], date0 = [date0], date1 = [date1]) | ||
|
||
coupler_sim = CouplerSimulation( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using coupler_sim
is clearer!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. The timing macro would break though with cs = coupler_sim
within the timing loop (i.e. cs
needs to be in the global scope). Because of this behavior, we will need to revisit using this macro vs just functions, but removing it now seems like a major rework, so I put this on the TODO list after the AMIP showcase.
atmos_sim = cs.model_sims.atm | ||
land_sim = cs.model_sims.lnd | ||
ocean_sim = cs.model_sims.ocn | ||
ice_sim = cs.model_sims.ice | ||
Δt_cpl = cs.Δt | ||
tspan = cs.tspan |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe something like this? Would need to do some renaming
atmos_sim = cs.model_sims.atm | |
land_sim = cs.model_sims.lnd | |
ocean_sim = cs.model_sims.ocn | |
ice_sim = cs.model_sims.ice | |
Δt_cpl = cs.Δt | |
tspan = cs.tspan | |
@unpack model_sims, Δt, tspan = cs | |
@unpack atm, lnd, ocn = model_sims |
struct BCFileInfo{S, V, R, D, C, O, I} | ||
datafile_cgll::S | ||
varname::V | ||
weightfile::S | ||
regrid_space::R | ||
all_dates::D | ||
segment_idx::Vector{Int} | ||
segment_idx0::Vector{Int} | ||
monthly_fields::C | ||
segment_length::Vector{Int} | ||
scaling_function::O # TODO: turn this into a func for scaling + offsets etc | ||
interpolate_monthly::I | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add some docs for the fields of this!
|
||
end | ||
|
||
no_scalling(x) = swap_space!(x, axes(mask)) # TODO: mask should not be global |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be no_scaling
?
Is this ok to merge? All issues above should be addressed, and we can iterate on the interface in the upcoming PR(s), after the ClimaAtmos update. |
sure! After the ClimaAtmos update, we can also add in buildkite runs for the AMIP mode. |
format init monthly interp running final tests done format refact push/pull+unit tst for update_midmonth_data format fix cons test fix cons check fix interf update updated and tested format rev updated format scope fix fix format
22fa8a2
to
b221bf0
Compare
bors r+ |
105: Daily interpolation from monthly data (v2) r=LenkaNovak a=LenkaNovak # PULL REQUEST - Update from #91 ## Purpose and Content Adds capability to interpolate linearly between two monthly `Fields`. The demo uses prerequisite PRs outlined in #88 to obtain monthly data. ## Benefits and Risks - benefit: last piece for enabling specifying temporarily varying boundary conditions from a file. - risk: performance slow-down - check are in place (see below) ## Linked Issues - SDI: #74 - Design: #88 ## Dependent PRs - no not merge before #87 , #89 and #90 ## Performance of the final solution - time loop only over added infrastructure of #88 : adding 0.24s per simulation day at `dt = 200s` ## PR Checklist - [x] This PR has a corresponding issue OR is linked to an SDI. - [x] I have followed CliMA's codebase [contribution](https://clima.github.io/ClimateMachine.jl/latest/Contributing/) and [style](https://clima.github.io/ClimateMachine.jl/latest/DevDocs/CodeStyle/) guidelines OR N/A. - [x] I have followed CliMA's [documentation policy](https://github.com/CliMA/policies/wiki/Documentation-Policy). - [x] I have checked all issues and PRs and I certify that this PR does not duplicate an open PR. - [x] I linted my code on my local machine prior to submission OR N/A. - [x] Unit tests are included OR N/A. - [x] Code used in an integration test OR N/A. - [x] All tests ran successfully on my local machine OR N/A. - [x] All classes, modules, and function contain docstrings OR N/A. - [x] Documentation has been added/updated OR N/A. Co-authored-by: LenkaNovak <lenka@caltech.edu>
PULL REQUEST
Purpose and Content
This PR adds functionality to collect BC field information in a struct
..._info
, which is then updated each month with a new file read of the regridded data. In the next PR..._info
will contain two Fields read from a file, which will be used for the daily interpolation.Benefits and Risks
Linked Issues
Dependent PRs
Coupling loop performance
PR Checklist