-
Notifications
You must be signed in to change notification settings - Fork 195
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
Adds an interface for inserting biogeochemistry models into Oceananigans models #2802
Conversation
I've had a play implementing an NPD model in this framework now and think that the other way to define the source functions is preferential: Oceananigans.jl/test/test_biogeochemistry.jl Lines 33 to 37 in 45971e4
We could even go one step further and define a model like this: struct NPD
Kₙ :: Float64
m :: Float64
nitrif :: Float64
end
validate_biogeochemistry(::NPD, tracernames) = all([T ∈ tracernames for T in [:N, :P, :D]])
@inline function (model::NPD)(i, j, k, grid, ::Val{:N}, clock, fields)
P = @inbounds fields.P[i, j, k]
N = @inbounds fields.N[i, j, k]
D = @inbounds fields.D[i, j, k]
return model.nitrif*D - P*N/(N+model.Kₙ)
end
@inline function (model::NPD)(i, j, k, grid, ::Val{:P}, clock, fields)
P = @inbounds fields.P[i, j, k]
N = @inbounds fields.N[i, j, k]
return P*N/(N+model.Kₙ) - model.m*P
end
@inline function (model::NPD)(i, j, k, grid, ::Val{:D}, clock, fields)
P = @inbounds fields.P[i, j, k]
D = @inbounds fields.D[i, j, k]
return model.m*P - model.nitrif*D
end
@inline (model::NPD)(args...) = 0.0 This negates the need to define a |
related to #2512 |
@johnryantaylor do you have any preferences for this API? |
We can use an abstract type to obviate the need for "zero functions": abstract type AbstractBiogeochemistry end
struct NutrientsPlanktonDetritus{FT} <: AbstractBiogeochemistry
background_nutrients :: FT
mortality_rate :: FT
nitrification :: FT
end then with @inline (::AbstractBiogeochemistry)(i, j, k, grid, val_tracer_name, clock, fields) = zero(grid) users don't need to define the "netural biogeochemical forcing" themselves. Very Important: always use verbose names! I don't know how to enforce that within the API 😂 I like this interface. Let's figure out if |
Instead of required_biogeochemical_tracers(::NutrientsPlanktonDetritus) = (:N, :P, :D) is a better syntax. Then users don't have to write their own error messages (we'll handle that in Oceananigans). It also gives us flexibility regarding the choice between 1) automagically adding the biogeochemical tracers or 2) requiring the user to add tracers themselves. We starting to use tracers for a few important things (TKE, biogeochemistry, buoyancy models). We may also need to come up with a system for handling "name clashes" gracefully. For example, someone might introduce a biogeochemistry model with tracer |
Ah I thought we could do something with abstract types for that but couldn't get it to work before. I'll try this on a GPU now if I can get one. And that makes sense for the validation. |
A lot of tests are failing too, we need to fix those |
|
This API looks good to me. I agree with all of @glwagner's suggestions. If we don't use explicit function names, then I think that it will be important to help the users by adding a comment at the start of the function to explain what that definition is doing and how to call the function. |
I've had a go at implementing a proper NPZD model (rather than one I just made up on the fly) and have some thoughts on how we should modify the API:
You can see my implementation here and a script using it here since I thought it was probably too complicated for the test (and will change that back to a 1 variable model later). Not finished making it work but yet but will be done soon. |
Should the user specify this, or should the biogeochemical model add it its struct (taking in |
Can't we add advective terms via the biogeochemical forcing term? edit: I see you mentioned that, so I might be missing something... I'll take a look at your examples. PS we should add those scripts to |
I think we can impose a little more structure that eases biogeochemical model development. One route is to build out a layer on top of struct TracerBasedBiogeochemistry
biogeochemical_tracers
drift_advection_schemes
drift_velocities
transitions
auxiliary_fields
end and perhaps more properties. This is similar to how Another possibility is to build out a new abstract type below I was also thinking it would be nice to supply a "continuous form" interface, so that model developers can implement functions that look something like biogeochemical_transition(x, y, z, t, N, P, Z, D, parameters) rather than having to use the "discrete form". This sort of structure could also be provided by an external package. The advantage of including it here is that we get tighter coupling with Oceananigans development. |
This is a good point, I think doing it as part of the model in update state is a much better solution |
This seems like a good idea, I will have a think and try and come up with something |
Sorry meant to put [skip ci] |
We can't setup Continuous forcing with the normal functions because it makes interpolation operators dependent on the index of tracers so the full model needs to be setup before you can create the forcing which doesn't work here. I guess the normal continuous forcing is as complicated as it is for a reason so we might have todo something else at some point, maybe for GPU compatability?
Anything else needed now? |
Co-authored-by: Gregory L. Wagner <wagner.greg@gmail.com>
src/Biogeochemistry.jl
Outdated
- `(bgc::BiogeochemicalModel)(i, j, k, grid, ::Val{:tracer_name}, clock, fields)` which | ||
returns the biogeochemical reaction for for each tracer. | ||
|
||
- `required_biogeochemical_tracers(::BiogeochemicalModel)` which returns a tuple of |
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.
2 spaces for markdown
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.
This looks good to me! The docstring for AbstractBiochemistry
should evolve into a documentation page in the Docs soon! That can be a new PR. :)
@seamanticscience docs for |
Is this ready to merge now? |
I think so. @glwagner? |
yay! |
Plus a simple test with a plankton growth/death model similar to
examples/convecting_plankton.jl
.TODO:
HydrostaticFreeSurfaceModel
With @jagoosw