Skip to content

Commit d627b0d

Browse files
committed
Expose interpolation method to users
1 parent d243666 commit d627b0d

File tree

4 files changed

+76
-3
lines changed

4 files changed

+76
-3
lines changed

NEWS.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,26 @@ ClimaUtilities.jl Release Notes
44
main
55
------
66

7+
#### Interpolation method for InterpolationsRegridder
8+
9+
`InterpolationsRegridder` now accepts the new keyword argument
10+
`interpolation_method` for choosing which kind of interpolation to do. The
11+
default is `Interpolations.Linear()`.
12+
13+
```julia
14+
import ClimaUtilities.Regridders
15+
import ClimaCore, Interpolations
16+
17+
linear_reg = Regridders.InterpolationsRegridder(
18+
target_space,
19+
interpolation_method = Intp.Linear(),
20+
)
21+
constant_reg = Regridders.InterpolationsRegridder(
22+
target_space,
23+
interpolation_method = Intp.Constant(),
24+
)
25+
```
26+
727
v0.1.23
828
------
929

docs/src/regridders.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ regridded_u = Regridders.regrid(reg, target_date)
6565
along each direction) and returns a `ClimaCore` `Field` defined on the
6666
`target_space`.
6767

68+
!!! note "Did you know?"
69+
With versions of ClimaUtilities after v0.1.24, you can change the
70+
interpolation method to perform any gridded interpolation supported by
71+
Interpolations.jl. For example, to do constant interpolation, you can pass
72+
`interpolation_method = Interpolations.Constant()` as a keyword argument
73+
when constructing the regridder.
74+
6875
Currently, `InterpolationsRegridder` only supports spherical shells and extruded
6976
spherical shells (but it could be easily extended to other domains).
7077

ext/InterpolationsRegridderExt.jl

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import ClimaUtilities.Regridders
1111
struct InterpolationsRegridder{
1212
SPACE <: ClimaCore.Spaces.AbstractSpace,
1313
FIELD <: ClimaCore.Fields.Field,
14+
IM,
1415
BC,
1516
DT <: Tuple,
1617
} <: Regridders.AbstractRegridder
@@ -21,6 +22,9 @@ struct InterpolationsRegridder{
2122
"""ClimaCore.Field of physical coordinates over which the data will be interpolated"""
2223
coordinates::FIELD
2324

25+
"""Method of interpolation as accepted by Interpolations.jl"""
26+
interpolation_method::IM
27+
2428
"""Tuple of extrapolation conditions as accepted by Interpolations.jl"""
2529
extrapolation_bc::BC
2630

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

3842
"""
3943
InterpolationsRegridder(target_space::ClimaCore.Spaces.AbstractSpace
40-
[; extrapolation_bc::Tuple])
44+
[; extrapolation_bc::Tuple,
45+
dim_increasing::Union{Nothing, Tuple},
46+
interpolation_method = Interpolations.Linear()])
4147
4248
An online regridder that uses Interpolations.jl
4349
@@ -67,6 +73,7 @@ function Regridders.InterpolationsRegridder(
6773
target_space::ClimaCore.Spaces.AbstractSpace;
6874
extrapolation_bc::Union{Nothing, Tuple} = nothing,
6975
dim_increasing::Union{Nothing, Tuple} = nothing,
76+
interpolation_method = Intp.Linear(),
7077
)
7178
coordinates = ClimaCore.Fields.coordinate_field(target_space)
7279
# set default values for the extrapolation_bc and dim_increasing if they are not provided
@@ -89,6 +96,7 @@ function Regridders.InterpolationsRegridder(
8996
return InterpolationsRegridder(
9097
target_space,
9198
coordinates,
99+
interpolation_method,
92100
extrapolation_bc,
93101
dim_increasing,
94102
)
@@ -119,7 +127,7 @@ function Regridders.regrid(regridder::InterpolationsRegridder, data, dimensions)
119127
Intp.interpolate(
120128
dimensions_FT,
121129
FT.(data_transformed),
122-
Intp.Gridded(Intp.Linear()),
130+
Intp.Gridded(regridder.interpolation_method),
123131
),
124132
regridder.extrapolation_bc,
125133
)
@@ -148,7 +156,11 @@ function Regridders.regrid!(
148156
"Dimensions must be monotonically increasing to use regrid!. Sort the dimensions first, or use regrid.",
149157
)
150158
itp = Intp.extrapolate(
151-
Intp.interpolate(dimensions, data, Intp.Gridded(Intp.Linear())),
159+
Intp.interpolate(
160+
dimensions,
161+
data,
162+
Intp.Gridded(regridder.interpolation_method),
163+
),
152164
regridder.extrapolation_bc,
153165
)
154166
gpuitp = Adapt.adapt(ClimaComms.array_type(regridder.target_space), itp)

test/regridders.jl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,40 @@ end
267267
end
268268
end
269269

270+
@testset "Interpolation method" begin
271+
# Test constant interpolation method
272+
lon, lat, z =
273+
collect(0.0:1:360), collect(-90.0:1:90), collect(0.0:1.0:100.0)
274+
dimensions2D = (lon, lat)
275+
dimensions3D = (lon, lat, z)
276+
size2D = (361, 181)
277+
size3D = (361, 181, 101)
278+
ones_2Ddata = ones(size2D)
279+
ones_3Ddata = ones(size3D)
280+
281+
for FT in (Float32, Float64)
282+
spaces = make_spherical_space(FT; context)
283+
horzspace = spaces.horizontal
284+
hv_center_space = spaces.hybrid
285+
286+
reg_horz = Regridders.InterpolationsRegridder(
287+
horzspace,
288+
interpolation_method = Interpolations.Constant(),
289+
)
290+
reg_hv = Regridders.InterpolationsRegridder(
291+
hv_center_space,
292+
interpolation_method = Interpolations.Constant(),
293+
)
294+
295+
regridded_2Ddata =
296+
Regridders.regrid(reg_horz, ones_2Ddata, dimensions2D)
297+
regridded_3Ddata = Regridders.regrid(reg_hv, ones_3Ddata, dimensions3D)
298+
299+
@test all(x -> x == one(x), parent(regridded_2Ddata))
300+
@test all(x -> x == one(x), parent(regridded_3Ddata))
301+
end
302+
end
303+
270304
@testset "InterpolationsRegridderXYZPoint" begin
271305
helem = (10, 10)
272306
Nq = 4

0 commit comments

Comments
 (0)