fold_sample Subroutine

private subroutine fold_sample(v, dt)

Combine the current output_buffer sample into accumulator per time_op.

MEAN and INTEGRAL fold dt-weighted: accumulator += sample · dt. With fixed dt this matches a count-weighted sum exactly, so callers running uniform timesteps see no change. With variable dt it produces the true (1/T) ∫ f dt (MEAN) or ∫ f dt (INTEGRAL), which a count-weighted scheme would not.

MAX / MIN are dt-independent — the running extremum doesn’t care about sample weight.

When v%mask is allocated, the sample is multiplied by the mask weight (broadcast across z) before folding. Cells with weight = 0 contribute nothing to MEAN / INTEGRAL. For MAX / MIN, masked cells are taken as -huge / +huge respectively so they never win — masked output stays at the seed value.

Arguments

Type IntentOptional Attributes Name
type(diag_var_t), intent(inout) :: v
real(kind=wp), intent(in) :: dt

Calls

proc~~fold_sample~~CallsGraph proc~fold_sample fold_sample proc~fold_sample_masked_impl fold_sample_masked_impl proc~fold_sample->proc~fold_sample_masked_impl proc~fold_sample_unmasked_impl fold_sample_unmasked_impl proc~fold_sample->proc~fold_sample_unmasked_impl local local proc~fold_sample_masked_impl->local

Called by

proc~~fold_sample~~CalledByGraph proc~fold_sample fold_sample proc~ocean_diag_step ocean_diag_t%ocean_diag_step proc~ocean_diag_step->proc~fold_sample proc~engine_step_finalize engine_step_finalize proc~engine_step_finalize->proc~ocean_diag_step proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_step_finalize proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step_finalize proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean

Source Code

   subroutine fold_sample(v, dt)
      !! Combine the current `output_buffer` sample into `accumulator`
      !! per `time_op`.
      !!
      !! MEAN and INTEGRAL fold dt-weighted: `accumulator += sample · dt`.
      !! With fixed `dt` this matches a count-weighted sum exactly, so
      !! callers running uniform timesteps see no change.  With variable
      !! `dt` it produces the true `(1/T) ∫ f dt` (MEAN) or `∫ f dt`
      !! (INTEGRAL), which a count-weighted scheme would not.
      !!
      !! MAX / MIN are dt-independent — the running extremum doesn't
      !! care about sample weight.
      !!
      !! When `v%mask` is allocated, the sample is multiplied by the
      !! mask weight (broadcast across z) before folding.  Cells with
      !! weight = 0 contribute nothing to MEAN / INTEGRAL.  For MAX /
      !! MIN, masked cells are taken as `-huge` / `+huge` respectively
      !! so they never win — masked output stays at the seed value.
      type(diag_var_t), intent(inout) :: v
      real(wp), intent(in) :: dt
      if (.not. allocated(v%accumulator)) return
      if (allocated(v%mask)) then
         call fold_sample_masked_impl(v%accumulator, v%output_buffer, &
                                      v%mask%weight, v%mask%nx, v%mask%ny, &
                                      dt, v%time_op)
      else
         call fold_sample_unmasked_impl(v%accumulator, v%output_buffer, &
                                        dt, v%time_op)
      end if
      v%n_accum = v%n_accum + 1
   end subroutine fold_sample