Skip to content

Expose interpolation method to users #173

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ ClimaUtilities.jl Release Notes
main
------

#### Interpolation method for InterpolationsRegridder

`InterpolationsRegridder` now accepts the new keyword argument
`interpolation_method` for choosing the mode of the gridded interpolation. The
default is `Interpolations.Linear()`.

```julia
import ClimaUtilities.Regridders
import ClimaCore, Interpolations

linear_reg = Regridders.InterpolationsRegridder(
target_space,
interpolation_method = Intp.Linear(),
)
constant_reg = Regridders.InterpolationsRegridder(
target_space,
interpolation_method = Intp.Constant(),
)
```

v0.1.23
------

Expand Down
7 changes: 7 additions & 0 deletions docs/src/regridders.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ regridded_u = Regridders.regrid(reg, target_date)
along each direction) and returns a `ClimaCore` `Field` defined on the
`target_space`.

!!! note "Did you know?"
With versions of ClimaUtilities after v0.1.24, you can choose the mode of
the gridded interpolation with the keyword argument `interpolation_method`.
For example, to do constant interpolation, you can pass
`interpolation_method = Interpolations.Constant()` as a keyword argument
when constructing the regridder.

Currently, `InterpolationsRegridder` only supports spherical shells and extruded
spherical shells (but it could be easily extended to other domains).

Expand Down
18 changes: 15 additions & 3 deletions ext/InterpolationsRegridderExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import ClimaUtilities.Regridders
struct InterpolationsRegridder{
SPACE <: ClimaCore.Spaces.AbstractSpace,
FIELD <: ClimaCore.Fields.Field,
IM,
BC,
DT <: Tuple,
} <: Regridders.AbstractRegridder
Expand All @@ -21,6 +22,9 @@ struct InterpolationsRegridder{
"""ClimaCore.Field of physical coordinates over which the data will be interpolated"""
coordinates::FIELD

"""Method of gridded interpolation as accepted by Interpolations.jl"""
interpolation_method::IM

"""Tuple of extrapolation conditions as accepted by Interpolations.jl"""
extrapolation_bc::BC

Expand All @@ -37,7 +41,9 @@ totuple(pt::ClimaCore.Geometry.XYZPoint) = pt.x, pt.y, pt.z

"""
InterpolationsRegridder(target_space::ClimaCore.Spaces.AbstractSpace
[; extrapolation_bc::Tuple])
[; extrapolation_bc::Tuple,
dim_increasing::Union{Nothing, Tuple},
interpolation_method = Interpolations.Linear()])

An online regridder that uses Interpolations.jl

Expand Down Expand Up @@ -67,6 +73,7 @@ function Regridders.InterpolationsRegridder(
target_space::ClimaCore.Spaces.AbstractSpace;
extrapolation_bc::Union{Nothing, Tuple} = nothing,
dim_increasing::Union{Nothing, Tuple} = nothing,
interpolation_method = Intp.Linear(),
)
coordinates = ClimaCore.Fields.coordinate_field(target_space)
# set default values for the extrapolation_bc and dim_increasing if they are not provided
Expand All @@ -89,6 +96,7 @@ function Regridders.InterpolationsRegridder(
return InterpolationsRegridder(
target_space,
coordinates,
interpolation_method,
extrapolation_bc,
dim_increasing,
)
Expand Down Expand Up @@ -119,7 +127,7 @@ function Regridders.regrid(regridder::InterpolationsRegridder, data, dimensions)
Intp.interpolate(
dimensions_FT,
FT.(data_transformed),
Intp.Gridded(Intp.Linear()),
Intp.Gridded(regridder.interpolation_method),
),
regridder.extrapolation_bc,
)
Expand Down Expand Up @@ -148,7 +156,11 @@ function Regridders.regrid!(
"Dimensions must be monotonically increasing to use regrid!. Sort the dimensions first, or use regrid.",
)
itp = Intp.extrapolate(
Intp.interpolate(dimensions, data, Intp.Gridded(Intp.Linear())),
Intp.interpolate(
dimensions,
data,
Intp.Gridded(regridder.interpolation_method),
),
regridder.extrapolation_bc,
)
gpuitp = Adapt.adapt(ClimaComms.array_type(regridder.target_space), itp)
Expand Down
34 changes: 34 additions & 0 deletions test/regridders.jl
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,40 @@ end
end
end

@testset "Interpolation method" begin
# Test constant interpolation method
lon, lat, z =
collect(0.0:1:360), collect(-90.0:1:90), collect(0.0:1.0:100.0)
dimensions2D = (lon, lat)
dimensions3D = (lon, lat, z)
size2D = (361, 181)
size3D = (361, 181, 101)
ones_2Ddata = ones(size2D)
ones_3Ddata = ones(size3D)

for FT in (Float32, Float64)
spaces = make_spherical_space(FT; context)
horzspace = spaces.horizontal
hv_center_space = spaces.hybrid

reg_horz = Regridders.InterpolationsRegridder(
horzspace,
interpolation_method = Interpolations.Constant(),
)
reg_hv = Regridders.InterpolationsRegridder(
hv_center_space,
interpolation_method = Interpolations.Constant(),
)

regridded_2Ddata =
Regridders.regrid(reg_horz, ones_2Ddata, dimensions2D)
regridded_3Ddata = Regridders.regrid(reg_hv, ones_3Ddata, dimensions3D)

@test all(x -> x == one(x), parent(regridded_2Ddata))
@test all(x -> x == one(x), parent(regridded_3Ddata))
end
end

@testset "InterpolationsRegridderXYZPoint" begin
helem = (10, 10)
Nq = 4
Expand Down
Loading