@@ -458,15 +458,14 @@ abstract type SlabplanetTerraMode <: AbstractSlabplanetSimulationMode end
458458Remap the given `field` onto the `target_space`. If the field is already
459459on the target space or a compatible one, it is returned unchanged.
460460
461- Note that this method has a lot of allocations and is not efficient .
461+ This is a convenience wrapper around `remap!` that allocates the output field .
462462
463463Non-ClimaCore fields should provide a method to this function.
464464"""
465465function remap end
466466
467- function remap (field:: CC.Fields.Field , target_space:: CC.Spaces.AbstractSpace )
468- source_space = axes (field)
469- comms_ctx = ClimaComms. context (source_space)
467+ function remap (source_field:: CC.Fields.Field , target_space:: CC.Spaces.AbstractSpace )
468+ source_space = axes (source_field)
470469
471470 # Check if the source and target spaces are compatible
472471 spaces_are_compatible =
@@ -481,7 +480,53 @@ function remap(field::CC.Fields.Field, target_space::CC.Spaces.AbstractSpace)
481480 end
482481
483482 # If the spaces are the same or one is a subspace of the other, we can just return the input field
484- spaces_are_compatible && return field
483+ spaces_are_compatible && return source_field
484+
485+ # Allocate target field and call remap!
486+ target_field = CC. Fields. zeros (target_space)
487+ remap! (target_field, source_field)
488+ return target_field
489+ end
490+
491+ function remap (source_field:: Number , target_space:: CC.Spaces.AbstractSpace )
492+ # Allocate target field and call remap!
493+ target_field = CC. Fields. zeros (target_space)
494+ remap! (target_field, source_field)
495+ return target_field
496+ end
497+
498+ """
499+ remap!(target_field, source_field)
500+
501+ Remap the given `source_field` onto the `target_field`. This is the core non-allocating
502+ implementation.
503+
504+ Non-ClimaCore fields should provide a method to this function.
505+ """
506+ function remap! end
507+
508+ function remap! (target_field:: CC.Fields.Field , source_field:: CC.Fields.Field )
509+ source_space = axes (source_field)
510+ target_space = axes (target_field)
511+ comms_ctx = ClimaComms. context (source_space)
512+
513+ # Check if the source and target spaces are compatible
514+ spaces_are_compatible =
515+ source_space == target_space ||
516+ CC. Spaces. issubspace (source_space, target_space) ||
517+ CC. Spaces. issubspace (target_space, source_space)
518+
519+ # TODO : Handle remapping of Vectors correctly
520+ if hasproperty (source_field, :components )
521+ @assert length (source_field. components) == 1 " Can only work with simple vectors"
522+ source_field = source_field. components. data.:1
523+ end
524+
525+ # If the spaces are the same or one is a subspace of the other, we can just copy
526+ if spaces_are_compatible
527+ target_field .= source_field
528+ return nothing
529+ end
485530
486531 # Get vector of LatLongPoints for the target space to get the hcoords
487532 # Copy target coordinates to CPU if they are on GPU
@@ -493,10 +538,10 @@ function remap(field::CC.Fields.Field, target_space::CC.Spaces.AbstractSpace)
493538 # Remap the field, using MPI if applicable
494539 if comms_ctx isa ClimaComms. SingletonCommsContext
495540 # Remap source field to target space as an array
496- remapped_array = CC. Remapping. interpolate (field , hcoords, [])
541+ remapped_array = CC. Remapping. interpolate (source_field , hcoords, [])
497542
498- # Convert remapped array to a field in the target space
499- return CC. Fields. array2field (remapped_array, target_space)
543+ # Copy remapped array into target field
544+ target_field . = CC. Fields. array2field (remapped_array, target_space)
500545 else
501546 # Gather then broadcast the global hcoords and offsets
502547 offset = [length (hcoords)]
@@ -506,33 +551,22 @@ function remap(field::CC.Fields.Field, target_space::CC.Spaces.AbstractSpace)
506551 # Interpolate on root and broadcast to all processes
507552 remapper = CC. Remapping. Remapper (source_space; target_hcoords = all_hcoords)
508553 remapped_array =
509- ClimaComms. bcast (comms_ctx, CC. Remapping. interpolate (remapper, field ))
554+ ClimaComms. bcast (comms_ctx, CC. Remapping. interpolate (remapper, source_field ))
510555
511556 my_ending_offset = sum (all_offsets[1 : ClimaComms. mypid (comms_ctx)])
512557 my_starting_offset = my_ending_offset - offset[]
513558
514- # Convert remapped array to a field in the target space on each process
515- return CC. Fields. array2field (
559+ # Copy remapped array into target field on each process
560+ target_field . = CC. Fields. array2field (
516561 remapped_array[(1 + my_starting_offset): my_ending_offset],
517562 target_space,
518563 )
519564 end
565+ return nothing
520566end
521567
522- function remap (num:: Number , target_space:: CC.Spaces.AbstractSpace )
523- return num
524- end
525-
526- """
527- remap!(target_field, source)
528-
529- Remap the given `source` onto the `target_field`.
530-
531- Non-ClimaCore fields should provide a method to [`Interfacer.remap`](@ref), or directly to this
532- function.
533- """
534- function remap! (target_field, source)
535- target_field .= remap (source, axes (target_field))
568+ function remap! (target_field:: CC.Fields.Field , source:: Number )
569+ fill! (target_field, source)
536570 return nothing
537571end
538572
0 commit comments