@@ -9,35 +9,36 @@ care about the surface.
99@inline to_node (pt:: CC.Geometry.LatLongZPoint ) = pt. long, pt. lat, zero (pt. lat)
1010
1111"""
12- map_interpolate(points, oc_field ::OC.Field)
12+ map_interpolate!(target_field::CC.Fields.Field, source_field ::OC.Field)
1313
14- Interpolate the given 3D field onto the target points .
14+ Interpolate the given 3D field onto the target field, modifying the target field in place .
1515
16- If the underlying grid does not contain a given point, return 0 instead.
16+ If the underlying grid does not contain a given point, writes 0 instead.
1717
18- Note: `map_interpolate` does not support interpolation from `Field`s defined on
18+ Note: `map_interpolate! ` does not support interpolation from `Field`s defined on
1919`OrthogononalSphericalShellGrids` such as the `TripolarGrid`.
20-
21- TODO: Use a non-allocating version of this function (simply replace `map` with `map!`)
2220"""
23- function map_interpolate (points, oc_field:: OC.Field )
24- loc = map (L -> L (), OC. Fields. location (oc_field))
25- grid = oc_field. grid
26- data = oc_field. data
21+ function map_interpolate! (target_field:: CC.Fields.Field , source_field:: OC.Field )
22+ points = CC. Fields. coordinate_field (axes (target_field))
23+ loc = map (L -> L (), OC. Fields. location (source_field))
24+ grid = source_field. grid
25+ data = source_field. data
2726
2827 # TODO : There has to be a better way
2928 min_lat, max_lat = extrema (OC. φnodes (grid, OC. Center (), OC. Center (), OC. Center ()))
3029
31- map (points) do pt
30+ # Use map! on the field directly, which handles complex data layouts correctly
31+ map! (target_field, points) do pt
3232 FT = eltype (pt)
3333
3434 # The oceananigans grid does not cover the entire globe, so we should not
3535 # interpolate outside of its latitude bounds. Instead we return 0
3636 min_lat < pt. lat < max_lat || return FT (0 )
3737
3838 fᵢ = OC. Fields. interpolate (to_node (pt), data, loc, grid)
39- convert (FT, fᵢ):: FT
39+ return convert (FT, fᵢ):: FT
4040 end
41+ return nothing
4142end
4243
4344"""
@@ -54,14 +55,33 @@ function surface_flux(f::OC.AbstractField)
5455 end
5556end
5657
57- function Interfacer. remap (field:: OC.Field , target_space)
58- return map_interpolate (CC. Fields. coordinate_field (target_space), field)
58+ function Interfacer. remap! (target_field:: CC.Fields.Field , source_field:: OC.Field )
59+ map_interpolate! (target_field, source_field)
60+ return nothing
5961end
6062
61- function Interfacer. remap (operation:: OC.AbstractOperations.AbstractOperation , target_space)
63+ function Interfacer. remap! (
64+ target_field:: CC.Fields.Field ,
65+ operation:: OC.AbstractOperations.AbstractOperation ,
66+ )
6267 evaluated_field = OC. Field (operation)
6368 OC. compute! (evaluated_field)
64- return Interfacer. remap (evaluated_field, target_space)
69+ Interfacer. remap! (target_field, evaluated_field)
70+ return nothing
71+ end
72+
73+ function Interfacer. remap (target_space, field:: OC.Field )
74+ # Allocate target field and call remap!
75+ target_field = CC. Fields. zeros (target_space)
76+ Interfacer. remap! (target_field, field)
77+ return target_field
78+ end
79+
80+ function Interfacer. remap (target_space, operation:: OC.AbstractOperations.AbstractOperation )
81+ # Allocate target field and call remap!
82+ target_field = CC. Fields. zeros (target_space)
83+ Interfacer. remap! (target_field, operation)
84+ return target_field
6585end
6686
6787"""
0 commit comments