@@ -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
222224Interfacer. step! (sim:: OceananigansSimulation , t) =
223225 OC. time_step! (sim. ocean, float (t) - sim. ocean. model. clock. time)
224226
225- # We always want the surface, so we always set zero(pt.lat) for z
226- """
227- to_node(pt::CA.ClimaCore.Geometry.LatLongPoint)
228-
229- Transform `LatLongPoint` into a tuple (long, lat, 0), where the 0 is needed because we only
230- care about the surface.
231- """
232- @inline to_node (pt:: CA.ClimaCore.Geometry.LatLongPoint ) = pt. long, pt. lat, zero (pt. lat)
233- # This next one is needed if we have "LevelGrid"
234- @inline to_node (pt:: CA.ClimaCore.Geometry.LatLongZPoint ) = pt. long, pt. lat, zero (pt. lat)
235-
236- """
237- map_interpolate(points, oc_field::OC.Field)
238-
239- Interpolate the given 3D field onto the target points.
240-
241- If the underlying grid does not contain a given point, return 0 instead.
242-
243- TODO: Use a non-allocating version of this function (simply replace `map` with `map!`)
244- """
245- function map_interpolate (points, oc_field:: OC.Field )
246- loc = map (L -> L (), OC. Fields. location (oc_field))
247- grid = oc_field. grid
248- data = oc_field. data
249-
250- # TODO : There has to be a better way
251- min_lat, max_lat = extrema (OC. φnodes (grid, OC. Center (), OC. Center (), OC. Center ()))
252-
253- map (points) do pt
254- FT = eltype (pt)
255-
256- # The oceananigans grid does not cover the entire globe, so we should not
257- # interpolate outside of its latitude bounds. Instead we return 0
258- min_lat < pt. lat < max_lat || return FT (0 )
259-
260- fᵢ = OC. Fields. interpolate (to_node (pt), data, loc, grid)
261- convert (FT, fᵢ):: FT
262- end
263- end
264-
265- """
266- surface_flux(f::OC.AbstractField)
267-
268- Extract the top boundary conditions for the given field.
269- """
270- function surface_flux (f:: OC.AbstractField )
271- top_bc = f. boundary_conditions. top
272- if top_bc isa OC. BoundaryCondition{<: OC.BoundaryConditions.Flux }
273- return top_bc. condition
274- else
275- return nothing
276- end
277- end
278-
279- function Interfacer. remap (field:: OC.Field , target_space)
280- return map_interpolate (CC. Fields. coordinate_field (target_space), field)
281- end
282-
283- function Interfacer. remap (operation:: OC.AbstractOperations.AbstractOperation , target_space)
284- evaluated_field = OC. Field (operation)
285- OC. compute! (evaluated_field)
286- return Interfacer. remap (evaluated_field, target_space)
287- end
288-
289227Interfacer. get_field (sim:: OceananigansSimulation , :: Val{:area_fraction} ) = sim. area_fraction
290228
291229# TODO : Better values for this
@@ -390,70 +328,6 @@ function FluxCalculator.update_turbulent_fluxes!(sim::OceananigansSimulation, fi
390328 return nothing
391329end
392330
393- """
394- set_from_extrinsic_vectors!(vectors, grid, u_cc, v_cc)
395-
396- Given the extrinsic vector components `u_cc` and `v_cc` as `Center, Center`
397- fields, rotate them onto the target grid and remap to `Face, Center` and
398- `Center, Face` fields, respectively.
399- """
400- function set_from_extrinsic_vectors! (vectors, grid, u_cc, v_cc)
401- arch = grid. architecture
402-
403- # Rotate vectors onto the grid
404- OC. Utils. launch! (arch, grid, :xy , _rotate_velocities!, u_cc, v_cc, grid)
405-
406- # Fill halo regions with the rotated vectors so we can use them to interpolate
407- OC. fill_halo_regions! (u_cc)
408- OC. fill_halo_regions! (v_cc)
409-
410- # Interpolate the vectors to face/center and center/face respectively
411- OC. Utils. launch! (
412- arch,
413- grid,
414- :xy ,
415- _interpolate_velocities!,
416- vectors. u,
417- vectors. v,
418- grid,
419- u_cc,
420- v_cc,
421- )
422- return nothing
423- end
424-
425- """
426- _rotate_velocities!(u, v, grid)
427-
428- Rotate the velocities from the extrinsic coordinate system to the intrinsic
429- coordinate system.
430- """
431- @kernel function _rotate_velocities! (u, v, grid)
432- # Use `k = 1` to index into the reduced Fields
433- i, j = @index (Global, NTuple)
434- # Rotate u, v from extrinsic to intrinsic coordinate system
435- ur, vr = OC. Operators. intrinsic_vector (i, j, 1 , grid, u, v)
436- @inbounds begin
437- u[i, j, 1 ] = ur
438- v[i, j, 1 ] = vr
439- end
440- end
441-
442- """
443- _interpolate_velocities!(u, v, grid, u_cc, v_cc)
444-
445- Interpolate the input velocities `u_cc` and `v_cc`, which are Center/Center
446- Fields to Face/Center and Center/Face coordinates, respectively.
447- """
448- @kernel function _interpolate_velocities! (u, v, grid, u_cc, v_cc)
449- # Use `k = 1` to index into the reduced Fields
450- i, j = @index (Global, NTuple)
451- @inbounds begin
452- u[i, j, 1 ] = OC. Operators. ℑxyᶠᶜᵃ (i, j, 1 , grid, u_cc)
453- v[i, j, 1 ] = OC. Operators. ℑxyᶜᶠᵃ (i, j, 1 , grid, v_cc)
454- end
455- end
456-
457331function Interfacer. update_field! (sim:: OceananigansSimulation , :: Val{:area_fraction} , field)
458332 sim. area_fraction .= field
459333 return nothing
0 commit comments