nc_emit_post_fire Subroutine

private subroutine nc_emit_post_fire(diag, ivar, t)

Post-fire emit hook. Appends one slice + time value for the var that just fired. Bound to diag%emit_post_fire by open_stream.

Arguments

Type IntentOptional Attributes Name
class(*), intent(inout) :: diag
integer, intent(in) :: ivar
real(kind=wp), intent(in) :: t

Calls

proc~~nc_emit_post_fire~~CallsGraph proc~nc_emit_post_fire nc_emit_post_fire nf90_put_var nf90_put_var proc~nc_emit_post_fire->nf90_put_var nf90_sync nf90_sync proc~nc_emit_post_fire->nf90_sync output_buffer output_buffer proc~nc_emit_post_fire->output_buffer proc~nc_check nc_check proc~nc_emit_post_fire->proc~nc_check proc~nc_put_var_3d_slice nc_put_var_3d_slice proc~nc_emit_post_fire->proc~nc_put_var_3d_slice proc~nc_put_var_3d_slice_r4 nc_put_var_3d_slice_r4 proc~nc_emit_post_fire->proc~nc_put_var_3d_slice_r4 proc~nc_put_var_4d_slice nc_put_var_4d_slice proc~nc_emit_post_fire->proc~nc_put_var_4d_slice proc~nc_put_var_4d_slice_r4 nc_put_var_4d_slice_r4 proc~nc_emit_post_fire->proc~nc_put_var_4d_slice_r4 stage stage proc~nc_emit_post_fire->stage vars vars proc~nc_emit_post_fire->vars nf90_strerror nf90_strerror proc~nc_check->nf90_strerror proc~fail fail proc~nc_check->proc~fail proc~nc_put_var_3d_slice->nf90_put_var proc~nc_put_var_3d_slice->proc~nc_check proc~nc_put_var_3d_slice_r4->nf90_put_var proc~nc_put_var_3d_slice_r4->proc~nc_check proc~nc_put_var_4d_slice->nf90_put_var proc~nc_put_var_4d_slice->proc~nc_check proc~nc_put_var_4d_slice_r4->nf90_put_var proc~nc_put_var_4d_slice_r4->proc~nc_check error error proc~fail->error proc~error_ring_push error_ring_push proc~fail->proc~error_ring_push

Variables

Type Visibility Attributes Name Initial
integer, private :: n1
integer, private :: n2
integer, private :: n3
integer, private :: ti

Source Code

   subroutine nc_emit_post_fire(diag, ivar, t)
      !! Post-fire emit hook.  Appends one slice + time value for the
      !! var that just fired.  Bound to `diag%emit_post_fire` by
      !! `open_stream`.
      class(*), intent(inout) :: diag
      integer, intent(in) :: ivar
      real(wp), intent(in) :: t
      integer :: n1, n2, n3, ti

      select type (d => diag)
      class is (ocean_diag_t)
         if (.not. d%nc_stream%is_open) return
         if (ivar < 1 .or. ivar > d%nvars) return
         associate (v => d%vars(ivar))
            if (v%nc_varid < 0) return
            v%nc_time_index = v%nc_time_index + 1
            ti = v%nc_time_index

            call nc_check(nf90_put_var(d%nc_stream%ncid, v%nc_time_varid, &
                                       [t], start=[ti], count=[1]), &
                          "writing diag time coord for "//trim(v%name))

            n3 = size(v%output_buffer, 3)
            if (d%nc_stream%xtype == NC_R4 .and. allocated(d%nc_stream%stage)) then
               ! Convert fp64 -> fp32 in the shared host staging buffer,
               ! then hand real32 data to a real32 variable.  Handing the
               ! fp64 buffer straight to an NF90_FLOAT variable would also
               ! "work" (netcdf converts internally) but doubles the bytes
               ! crossing into the library — the whole point of the knob is
               ! the byte count, so the conversion is ours to do.
               n1 = size(v%output_buffer, 1)
               n2 = size(v%output_buffer, 2)
               d%nc_stream%stage(1:n1, 1:n2, 1:n3) = &
                  real(v%output_buffer(1:n1, 1:n2, 1:n3), real32)
               if (n3 == 1) then
                  call nc_put_var_3d_slice_r4(d%nc_stream%ncid, v%nc_varid, &
                                              d%nc_stream%stage(1:n1, 1:n2, 1), ti)
               else
                  call nc_put_var_4d_slice_r4(d%nc_stream%ncid, v%nc_varid, &
                                              d%nc_stream%stage(1:n1, 1:n2, 1:n3), ti)
               end if
            else if (n3 == 1) then
               call nc_put_var_3d_slice(d%nc_stream%ncid, v%nc_varid, &
                                        v%output_buffer(:, :, 1), ti)
            else
               call nc_put_var_4d_slice(d%nc_stream%ncid, v%nc_varid, &
                                        v%output_buffer, ti)
            end if

            ! Flush the HDF5 metadata cache so frames survive an abort
            ! (e.g. the h-guard ERROR STOP): without this, a killed run
            ! leaves every record dim at 0 and the written data orphaned.
            call nc_check(nf90_sync(d%nc_stream%ncid), &
                          "syncing diag stream after "//trim(v%name))
         end associate
      end select
   end subroutine nc_emit_post_fire