register_derived Subroutine

public subroutine register_derived(state, name, time_op, dt_out, coord)

Register ONE derived diagnostic by catalog name (used by apply_diag_selection): look it up and forward to state%diag%register(...) with the catalog metadata + correct buffer shape. Error-stops on an unknown name. coord (a DIAG_VGRID_*) sets the output vgrid for a LAYERED diag + attaches the conservative remap (2D entries ignore it); default LAYER. Remaps INTENSIVE.

Arguments

Type IntentOptional Attributes Name
type(ocean_state_t), intent(inout), target :: state
character(len=*), intent(in) :: name
integer, intent(in), optional :: time_op
real(kind=wp), intent(in), optional :: dt_out
integer, intent(in), optional :: coord

Calls

proc~~register_derived~~CallsGraph proc~register_derived register_derived error error proc~register_derived->error proc~catalog_name_list catalog_name_list proc~register_derived->proc~catalog_name_list proc~coord_remap_proc coord_remap_proc proc~register_derived->proc~coord_remap_proc proc~derived_requires_fail derived_requires_fail proc~register_derived->proc~derived_requires_fail proc~diag_mask_vanished_is_on diag_mask_vanished_is_on proc~register_derived->proc~diag_mask_vanished_is_on proc~ensure_catalog_initialised ensure_catalog_initialised proc~register_derived->proc~ensure_catalog_initialised proc~error_ring_push error_ring_push proc~register_derived->proc~error_ring_push proc~ocean_diag_register ocean_diag_t%ocean_diag_register proc~register_derived->proc~ocean_diag_register proc~catalog_name_list->proc~ensure_catalog_initialised proc~derived_requires_fail->error proc~derived_requires_fail->proc~error_ring_push proc~reset_accumulator reset_accumulator proc~ocean_diag_register->proc~reset_accumulator proc~fill_buffer_impl fill_buffer_impl proc~reset_accumulator->proc~fill_buffer_impl

Called by

proc~~register_derived~~CalledByGraph proc~register_derived register_derived proc~apply_diag_selection apply_diag_selection proc~apply_diag_selection->proc~register_derived proc~engine_configure_diag engine_configure_diag proc~engine_configure_diag->proc~apply_diag_selection proc~engine_setup engine_setup proc~engine_setup->proc~engine_configure_diag proc~complete_ocean_create complete_ocean_create proc~complete_ocean_create->proc~engine_setup proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_setup proc~driver_validate driver_validate proc~driver_validate->proc~engine_setup proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean proc~rdb_ocean_create_finalize rdb_ocean_create_finalize proc~rdb_ocean_create_finalize->proc~complete_ocean_create proc~rdb_ocean_create_from_string rdb_ocean_create_from_string proc~rdb_ocean_create_from_string->proc~complete_ocean_create

Variables

Type Visibility Attributes Name Initial
type(derived_entry_t), private :: entry
integer, private :: i
integer, private :: idx
integer, private :: n3
integer, private :: nx
integer, private :: ny
integer, private :: nz
integer, private :: ocoord
procedure(diag_remap_proc), private, pointer :: remap

Source Code

   subroutine register_derived(state, name, time_op, dt_out, coord)
      !! Register ONE derived diagnostic by catalog `name` (used by
      !! `apply_diag_selection`): look it up and forward to
      !! `state%diag%register(...)` with the catalog metadata + correct buffer
      !! shape.  Error-stops on an unknown name.  `coord` (a `DIAG_VGRID_*`)
      !! sets the output vgrid for a LAYERED diag + attaches the conservative
      !! remap (2D entries ignore it); default LAYER.  Remaps INTENSIVE.
      type(ocean_state_t), intent(inout), target :: state
      character(len=*), intent(in) :: name
      integer, intent(in), optional :: time_op
      real(wp), intent(in), optional :: dt_out
      integer, intent(in), optional :: coord
      integer :: i, idx, nx, ny, nz, n3, ocoord
      type(derived_entry_t) :: entry
      procedure(diag_remap_proc), pointer :: remap

      call ensure_catalog_initialised()

      idx = 0
      do i = 1, N_CATALOG
         if (trim(CATALOG(i)%name) == trim(name)) then
            idx = i
            exit
         end if
      end do
      if (idx == 0) then
         call error_ring_push("unknown derived diagnostic '"//trim(name)// &
                              "'; valid names: "//catalog_name_list())
         call global_logger%error("unknown derived diagnostic '"//trim(name)// &
                                  "'; valid names: "//catalog_name_list())
         error stop "register_derived: unknown derived diagnostic name"
      end if
      entry = CATALOG(idx)

      ! Prerequisite gate.  FAIL LOUD, never a silent plane of zeros or
      ! of missing values: a user who asked for `melt` on a run with no
      ! melt slot has made a configuration error, and handing them a
      ! NetCDF variable full of `_FillValue` would let it reach a figure.
      select case (entry%requires)
      case (DERIVED_REQ_CAVITY_DYN)
         if (.not. state%metrics%use_cavity) then
            call derived_requires_fail(trim(entry%name), "&ocean_cavity_dyn_nml enable", &
                                       "the ice-shelf draft geometry")
         end if
      case (DERIVED_REQ_CAVITY_MELT)
         if (.not. state%cavity_flux%enable) then
            call derived_requires_fail(trim(entry%name), "&ocean_cavity_melt_nml enable", &
                                       "the basal-melt interface slot")
         end if
      case default
         continue
      end select

      nx = size(state%barotropic%h, 1)
      ny = size(state%barotropic%h, 2)
      nz = state%multilayer%nz_ml
      n3 = nz
      if (.not. entry%is_layered) n3 = 1

      ocoord = DIAG_VGRID_LAYER
      if (present(coord) .and. entry%is_layered) ocoord = coord
      call coord_remap_proc(ocoord, remap)

      if (associated(remap)) then
         call state%diag%register(name=trim(entry%name), units=trim(entry%units), &
                                  fill=entry%fill, n1=nx, n2=ny, n3=n3, &
                                  long_name=trim(entry%long_name), &
                                  standard_name=trim(entry%standard_name), &
                                  time_op=time_op, dt_out=dt_out, &
                                  output_vgrid=ocoord, remap=remap, is_extensive=.false., &
                                  ! A `masks_land` entry (`vorticity_z`) writes
                                  ! `DIAG_MISSING_VALUE` at every land T-cell on this
                                  ! (remapped, layered) path too, so it must advertise
                                  ! `_FillValue` here as well as below.
                                  has_missing=((diag_mask_vanished_is_on() .and. &
                                                ocoord /= DIAG_VGRID_DENSITY) .or. &
                                               entry%masks_land))
      else
         ! Every cavity entry writes the NaN sentinel outside the cover
         ! (`cavity_mask_impl`), so the NetCDF variable must advertise a
         ! `_FillValue` — unconditionally, not via
         ! `diag_mask_vanished_is_on()`, which gates the REMAP path's
         ! below-target fill and has nothing to do with a calving front.
         ! A `masks_land` entry (`vorticity_z`, `fill_vorticity_z_impl`)
         ! writes `DIAG_MISSING_VALUE` at every land T-cell regardless of
         ! `mask_vanished_layers`, so it advertises unconditionally too.
         call state%diag%register(name=trim(entry%name), units=trim(entry%units), &
                                  fill=entry%fill, n1=nx, n2=ny, n3=n3, &
                                  long_name=trim(entry%long_name), &
                                  standard_name=trim(entry%standard_name), &
                                  time_op=time_op, dt_out=dt_out, &
                                  has_missing=(entry%requires /= DERIVED_REQ_NONE .or. &
                                               entry%masks_land))
      end if
   end subroutine register_derived