Skip to content
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

Forcing API refactor #444

Merged
merged 26 commits into from
Oct 9, 2019
Merged

Forcing API refactor #444

merged 26 commits into from
Oct 9, 2019

Conversation

glwagner
Copy link
Member

@glwagner glwagner commented Oct 7, 2019

This PR changes the name of the Forcing constructor to ModelForcing to clarify the difference between constructors for forcing objects on single fields, and constructors for the NamedTuple of forcing objects for all model fields. It also conventionalizes the name of the fields in ModelForcing, so that

forcing = ModelForcing(u=u_forcing)

is used to apply the forcing function u_forcing to u.

In addition it adds a new type "SimpleForcing", which permits users to pass functions of x, y, z, and t. A few validating lines in the ModelForcing constructor ensure that forcing functions for u, v, and w are applied at the correct locations.

For example, we can now write

T_forcing = SimpleForcing((x, y, z, t) -> exp(z) * cos(t))

model = Model(forcing=ModelForcing(T=T_forcing))

To create a forcing on temperature that decays exponentially in z and oscillates in time.

To test this functionality, this PR introduces an example "ocean_convection_with_plankton" that uses SimpleForcing to model the growth and decay of a plankton-like tracer.

@glwagner
Copy link
Member Author

glwagner commented Oct 8, 2019

@suyashbire1 we can use this pattern to implement a SimpleBoundaryCondition type as well (which addresses a concern raised in #421 about a simple way to use a function to implement boundary conditions).

Happy to work on that once this is merged.

@codecov
Copy link

codecov bot commented Oct 8, 2019

Codecov Report

Merging #444 into master will decrease coverage by 0.29%.
The diff coverage is 55%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master     #444     +/-   ##
=========================================
- Coverage   71.85%   71.55%   -0.3%     
=========================================
  Files          25       26      +1     
  Lines        1400     1417     +17     
=========================================
+ Hits         1006     1014      +8     
- Misses        394      403      +9
Impacted Files Coverage Δ
src/Oceananigans.jl 62.5% <ø> (ø) ⬆️
src/models.jl 81.57% <ø> (-0.48%) ⬇️
src/fields.jl 47.67% <45.45%> (-1.68%) ⬇️
src/forcing.jl 66.66% <66.66%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4b7e5bc...5a6c772. Read the comment docs.

@glwagner glwagner mentioned this pull request Oct 9, 2019
1 task
Copy link
Member

@ali-ramadhan ali-ramadhan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I might just add a couple of examples to the docstrings.

Should probably also add a SimpleForcing benchmark to benchmark_forcing_functions.jl but that doesn't have to be in this PR.

There are now two ways to specify a forcing function. If you want to use parameters then you must use the more low-level version and pass a function straight to ModelForcing.

This choice is hard to document through docstrings, which just means we have to document it clearly in the documentation page on "model setup". I've been meaning to write that page for a while, hopefully next week...

src/forcing.jl Outdated Show resolved Hide resolved
src/forcing.jl Outdated Show resolved Hide resolved
examples/ocean_convection_with_plankton.jl Show resolved Hide resolved
@glwagner
Copy link
Member Author

glwagner commented Oct 9, 2019

We can extend SimpleForcing with a field .parameters to optionally admit parameters via dispatch, eg

u_forcing = SimpleForcing((x, y, z, t, parameters) -> something, parameters=user_defined_parameters)

What do you think?

Interestingly, putting parameters in the forcing object obviates the need for model.parameters. Ultimately this design may be preferred; I suppose we will see.

@ali-ramadhan
Copy link
Member

Hmmm, yeah I guess model.parameters may be useful in boundary conditions (possibly elsewhere too) but if we only end up using them for forcing functions then that makes sense.

@glwagner
Copy link
Member Author

glwagner commented Oct 9, 2019

Hmmm, yeah I guess model.parameters may be useful in boundary conditions (possibly elsewhere too)

To make model.parameters fully obsolete, we would need wrappers / interfaces for boundary conditions; eg

bc = SimpleBoundaryCondition(Flux, (x, y, t, parameters) -> something, parameters=parameters)

Not suggesting we do it now, but something to think about for the future.

@glwagner glwagner merged commit 8876640 into master Oct 9, 2019
@glwagner glwagner deleted the forcing-api-improvements branch October 9, 2019 17:55
arcavaliere pushed a commit to arcavaliere/Oceananigans.jl that referenced this pull request Nov 6, 2019
…ments

Forcing API refactor

Former-commit-id: 8876640
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants