-
Notifications
You must be signed in to change notification settings - Fork 186
/
discrete_forcing.jl
66 lines (49 loc) · 2.26 KB
/
discrete_forcing.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import Adapt
using Oceananigans.Utils: prettysummary
"""
struct DiscreteForcing{P, F}
Wrapper for "discrete form" forcing functions with optional `parameters`.
"""
struct DiscreteForcing{P, F}
func :: F
parameters :: P
end
"""
DiscreteForcing(func; parameters=nothing)
Construct a "discrete form" forcing function with optional parameters.
The forcing function is applied at grid point `i, j, k`.
When `parameters` are not specified, `func` must be callable with the signature
```
func(i, j, k, grid, clock, model_fields)
```
where `grid` is `model.grid`, `clock.time` is the current simulation time and
`clock.iteration` is the current model iteration, and `model_fields` is a
`NamedTuple` with `u, v, w` and the fields in `model.tracers`.
*Note* that the index `end` does *not* access the final physical grid point of
a model field in any direction. The final grid point must be explicitly specified, as
in `model_fields.u[i, j, grid.Nz]`.
When `parameters` _is_ specified, `func` must be callable with the signature.
```
func(i, j, k, grid, clock, model_fields, parameters)
```
Above, `parameters` is, in principle, arbitrary. Note, however, that GPU compilation
can place constraints on `typeof(parameters)`.
"""
DiscreteForcing(func; parameters=nothing) = DiscreteForcing(func, parameters)
@inline function (forcing::DiscreteForcing{P, F})(i, j, k, grid, clock, model_fields) where {P, F<:Function}
parameters = forcing.parameters
return forcing.func(i, j, k, grid, clock, model_fields, parameters)
end
@inline (forcing::DiscreteForcing{<:Nothing, F})(i, j, k, grid, clock, model_fields) where F<:Function =
forcing.func(i, j, k, grid, clock, model_fields)
"""Show the innards of a `DiscreteForcing` in the REPL."""
Base.show(io::IO, forcing::DiscreteForcing{P}) where P =
print(io, "DiscreteForcing{$P}", "\n",
"├── func: $(prettysummary(forcing.func))", "\n",
"└── parameters: $(forcing.parameters)")
Adapt.adapt_structure(to, forcing::DiscreteForcing) =
DiscreteForcing(Adapt.adapt(to, forcing.func),
Adapt.adapt(to, forcing.parameters))
on_architecture(to, forcing::DiscreteForcing) =
DiscreteForcing(on_architecture(to, forcing.func),
on_architecture(to, forcing.parameters))