-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[skip ci][ci skip]
- Loading branch information
Showing
7 changed files
with
289 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,22 @@ | ||
struct AnalyticTimeVaryingInput{F <: Function} <: AbstractTimeVaryingInput | ||
# func here as to be GPU-compatible (e.g., splines are not) | ||
# func here has to be GPU-compatible (e.g., splines are not) | ||
func::F | ||
end | ||
|
||
function TimeVaryingInput(input::Function; method = nothing, device = nothing) | ||
# _kwargs... is needed to seamlessly support the other TimeVaryingInputs. | ||
function TimeVaryingInput(input::Function; _kwargs...) | ||
isnothing(method) || | ||
@warn "Interpolation method is ignored for analytical functions" | ||
return AnalyticTimeVaryingInput(input) | ||
end | ||
|
||
function evaluate!(dest, input::AnalyticTimeVaryingInput, time) | ||
dest .= input.func(time) | ||
function evaluate!( | ||
dest, | ||
input::AnalyticTimeVaryingInput, | ||
time, | ||
args...; | ||
kwargs..., | ||
) | ||
dest .= input.func(time, args...; kwargs...) | ||
return nothing | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
src/shared_utilities/interpolating_time_varying_input2d.jl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
""" | ||
InterpolatingTimeVaryingInput2D | ||
The constructor for InterpolatingTimeVaryingInput2D is not supposed to be used directly, unless you | ||
know what you are doing. The constructor does not perform any check and does not take care of | ||
GPU compatibility. It is responsibility of the user-facing constructor TimeVaryingInput() to do so. | ||
""" | ||
struct InterpolatingTimeVaryingInput2D{ | ||
DH <: TemporalDataHandler, | ||
AA <: AbstractArray, | ||
M <: AbstractInterpolationMethod, | ||
CC <: ClimaComms.AbstractCommsContext, | ||
R <: Tuple, | ||
} <: AbstractTimeVaryingInput | ||
"""Object that has all the information on how to deal with files, data, and so on. | ||
Having to deal with files, it lives on the CPU.""" | ||
data_handler::DH | ||
|
||
"""Interpolation method""" | ||
method::M | ||
|
||
"""ClimaComms context""" | ||
context::CC | ||
|
||
"""Range of times over which the interpolator is defined. range is always defined on the | ||
CPU. Used by the in() function.""" | ||
range::R | ||
end | ||
|
||
function TimeVaryingInput( | ||
data_handler::TemporalDataHandler, | ||
method = LinearInterpolation(), | ||
context = ClimaComms.context(), | ||
) | ||
range = (first_time(data_handler), last_time(data_handler)) | ||
return InterpolatingTimeVaryingInput2D(data_handler, method, context, range) | ||
end | ||
|
||
function evaluate!( | ||
dest, | ||
itp::InterpolatingTimeVaryingInput2D, | ||
time, | ||
args...; | ||
kwargs..., | ||
) | ||
time in itp || error("TimeVaryingInput does not cover time $time") | ||
evaluate!(parent(dest), itp, time, itp.method) | ||
return nothing | ||
end | ||
|
||
function evaluate!( | ||
dest, | ||
itp::InterpolatingTimeVaryingInput2D, | ||
time, | ||
::NearestNeighbor, | ||
args...; | ||
kwargs..., | ||
) | ||
t0, t1 = | ||
previous_time(itp.data_handler, time), next_time(itp.data_handler, time) | ||
|
||
# The closest snapshot could be either the previous or the next one | ||
if (time - t0) < (t1 - time) | ||
dest .= previous_snapshot!(itp.data_handler, time) | ||
else | ||
dest .= next_snapshot!(itp.data_handler, time) | ||
end | ||
end | ||
|
||
function evaluate!( | ||
dest, | ||
itp::InterpolatingTimeVaryingInput2D, | ||
time, | ||
::LinearInterpolation, | ||
args...; | ||
kwargs..., | ||
) | ||
# Linear interpolation is: | ||
# y = y0 + (y1 - y0) * (time - t0) / (t1 - t0) | ||
# | ||
# Define coeff = (time - t0) / (t1 - t0) | ||
# | ||
# y = (1 - coeff) * y0 + coeff * y1 | ||
|
||
t0, t1 = | ||
previous_time(itp.data_handler, time), next_time(itp.data_handler, time) | ||
coeff = (time - t0) / (t1 - t0) | ||
dest .= | ||
(1 - coeff) * previous_snapshot!(itp.data_handler, time) .+ | ||
coeff * next_snapshot!(itp.data_handler, time) | ||
end |
Oops, something went wrong.