@@ -7,6 +7,8 @@ import Thermodynamics as TD
77import ClimaOcean. EN4: download_dataset
88using KernelAbstractions: @kernel , @index , @inbounds
99
10+ include (" climaocean_helpers.jl" )
11+
1012"""
1113 OceananigansSimulation{SIM, A, OPROP, REMAP}
1214
207209Interfacer. step! (sim:: OceananigansSimulation , t) =
208210 OC. time_step! (sim. ocean, float (t) - sim. ocean. model. clock. time)
209211
210- # We always want the surface, so we always set zero(pt.lat) for z
211- """
212- to_node(pt::CA.ClimaCore.Geometry.LatLongPoint)
213-
214- Transform `LatLongPoint` into a tuple (long, lat, 0), where the 0 is needed because we only
215- care about the surface.
216- """
217- @inline to_node (pt:: CA.ClimaCore.Geometry.LatLongPoint ) = pt. long, pt. lat, zero (pt. lat)
218- # This next one is needed if we have "LevelGrid"
219- @inline to_node (pt:: CA.ClimaCore.Geometry.LatLongZPoint ) = pt. long, pt. lat, zero (pt. lat)
220-
221- """
222- map_interpolate(points, oc_field::OC.Field)
223-
224- Interpolate the given 3D field onto the target points.
225-
226- If the underlying grid does not contain a given point, return 0 instead.
227-
228- TODO: Use a non-allocating version of this function (simply replace `map` with `map!`)
229- """
230- function map_interpolate (points, oc_field:: OC.Field )
231- loc = map (L -> L (), OC. Fields. location (oc_field))
232- grid = oc_field. grid
233- data = oc_field. data
234-
235- # TODO : There has to be a better way
236- min_lat, max_lat = extrema (OC. φnodes (grid, OC. Center (), OC. Center (), OC. Center ()))
237-
238- map (points) do pt
239- FT = eltype (pt)
240-
241- # The oceananigans grid does not cover the entire globe, so we should not
242- # interpolate outside of its latitude bounds. Instead we return 0
243- min_lat < pt. lat < max_lat || return FT (0 )
244-
245- fᵢ = OC. Fields. interpolate (to_node (pt), data, loc, grid)
246- convert (FT, fᵢ):: FT
247- end
248- end
249-
250- """
251- surface_flux(f::OC.AbstractField)
252-
253- Extract the top boundary conditions for the given field.
254- """
255- function surface_flux (f:: OC.AbstractField )
256- top_bc = f. boundary_conditions. top
257- if top_bc isa OC. BoundaryCondition{<: OC.BoundaryConditions.Flux }
258- return top_bc. condition
259- else
260- return nothing
261- end
262- end
263-
264- function Interfacer. remap (field:: OC.Field , target_space)
265- return map_interpolate (CC. Fields. coordinate_field (target_space), field)
266- end
267-
268- function Interfacer. remap (operation:: OC.AbstractOperations.AbstractOperation , target_space)
269- evaluated_field = OC. Field (operation)
270- OC. compute! (evaluated_field)
271- return Interfacer. remap (evaluated_field, target_space)
272- end
273-
274212Interfacer. get_field (sim:: OceananigansSimulation , :: Val{:area_fraction} ) = sim. area_fraction
275213
276214# TODO : Better values for this
@@ -375,70 +313,6 @@ function FluxCalculator.update_turbulent_fluxes!(sim::OceananigansSimulation, fi
375313 return nothing
376314end
377315
378- """
379- set_from_extrinsic_vectors!(vectors, grid, u_cc, v_cc)
380-
381- Given the extrinsic vector components `u_cc` and `v_cc` as `Center, Center`
382- fields, rotate them onto the target grid and remap to `Face, Center` and
383- `Center, Face` fields, respectively.
384- """
385- function set_from_extrinsic_vectors! (vectors, grid, u_cc, v_cc)
386- arch = grid. architecture
387-
388- # Rotate vectors onto the grid
389- OC. Utils. launch! (arch, grid, :xy , _rotate_velocities!, u_cc, v_cc, grid)
390-
391- # Fill halo regions with the rotated vectors so we can use them to interpolate
392- OC. fill_halo_regions! (u_cc)
393- OC. fill_halo_regions! (v_cc)
394-
395- # Interpolate the vectors to face/center and center/face respectively
396- OC. Utils. launch! (
397- arch,
398- grid,
399- :xy ,
400- _interpolate_velocities!,
401- vectors. u,
402- vectors. v,
403- grid,
404- u_cc,
405- v_cc,
406- )
407- return nothing
408- end
409-
410- """
411- _rotate_velocities!(u, v, grid)
412-
413- Rotate the velocities from the extrinsic coordinate system to the intrinsic
414- coordinate system.
415- """
416- @kernel function _rotate_velocities! (u, v, grid)
417- # Use `k = 1` to index into the reduced Fields
418- i, j = @index (Global, NTuple)
419- # Rotate u, v from extrinsic to intrinsic coordinate system
420- ur, vr = OC. Operators. intrinsic_vector (i, j, 1 , grid, u, v)
421- @inbounds begin
422- u[i, j, 1 ] = ur
423- v[i, j, 1 ] = vr
424- end
425- end
426-
427- """
428- _interpolate_velocities!(u, v, grid, u_cc, v_cc)
429-
430- Interpolate the input velocities `u_cc` and `v_cc`, which are Center/Center
431- Fields to Face/Center and Center/Face coordinates, respectively.
432- """
433- @kernel function _interpolate_velocities! (u, v, grid, u_cc, v_cc)
434- # Use `k = 1` to index into the reduced Fields
435- i, j = @index (Global, NTuple)
436- @inbounds begin
437- u[i, j, 1 ] = OC. Operators. ℑxyᶠᶜᵃ (i, j, 1 , grid, u_cc)
438- v[i, j, 1 ] = OC. Operators. ℑxyᶜᶠᵃ (i, j, 1 , grid, v_cc)
439- end
440- end
441-
442316function Interfacer. update_field! (sim:: OceananigansSimulation , :: Val{:area_fraction} , field)
443317 sim. area_fraction .= field
444318 return nothing
0 commit comments