configure_ocean_wave_drag Subroutine

public subroutine configure_ocean_wave_drag(cfg, ocean_state, grid, compute_rank, ierr)

Configure the barotropic linear (Rayleigh) wave-drag piston-velocity maps (Egbert & Ray 2001; Jayne & St Laurent 2001) — the bulk energy sink for the barotropic tide, MOM6 BT_LINEAR_WAVE_DRAG. Builds a host-only h-point r_h(nx,ny) map (uniform scalar or a resolved-bathymetry roughness proxy), scales it, averages h->face into bt_work%lwd_drag_u/v, and leaves the arrays unallocated when the knob is off (bit-identical). MUST run AFTER bathymetry is set (ocean_state%barotropic%b) and land masking (configure_ocean_land_mask) and BEFORE ocean_state_enter_data — the !$acc enter data copyin in barotropic_workstate_enter_data carries these host-filled values to the device (CLAUDE.md gotcha (2): arrays mapped create do not carry pre-map host values, so this ordering is load-bearing).

Arguments

Type IntentOptional Attributes Name
type(config_t), intent(in) :: cfg
type(ocean_state_t), intent(inout) :: ocean_state
type(hgrid_t), intent(in) :: grid
integer, intent(in) :: compute_rank
integer, intent(out), optional :: ierr

Non-zero on an unreachable/unimplemented wave_drag_form when present; absent behaves as today (error stop).


Calls

proc~~configure_ocean_wave_drag~~CallsGraph proc~configure_ocean_wave_drag configure_ocean_wave_drag info info proc~configure_ocean_wave_drag->info proc~fail fail proc~configure_ocean_wave_drag->proc~fail proc~wave_drag_roughness_proxy wave_drag_roughness_proxy proc~configure_ocean_wave_drag->proc~wave_drag_roughness_proxy to_string to_string proc~configure_ocean_wave_drag->to_string error error proc~fail->error proc~error_ring_push error_ring_push proc~fail->proc~error_ring_push

Called by

proc~~configure_ocean_wave_drag~~CalledByGraph proc~configure_ocean_wave_drag configure_ocean_wave_drag proc~engine_setup engine_setup proc~engine_setup->proc~configure_ocean_wave_drag 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
integer, private :: i
integer, private :: j
integer, private :: nx
integer, private :: ny
real(kind=wp), private, allocatable :: r_h(:,:)

Source Code

   subroutine configure_ocean_wave_drag(cfg, ocean_state, grid, compute_rank, ierr)
      !! Configure the barotropic linear (Rayleigh) wave-drag piston-velocity
      !! maps (Egbert & Ray 2001; Jayne & St Laurent 2001) — the bulk energy
      !! sink for the barotropic tide, MOM6 `BT_LINEAR_WAVE_DRAG`. Builds a
      !! host-only h-point `r_h(nx,ny)` map (uniform scalar or a
      !! resolved-bathymetry roughness proxy), scales it, averages h->face
      !! into `bt_work%lwd_drag_u/v`, and leaves the arrays unallocated when
      !! the knob is off (bit-identical). MUST run AFTER bathymetry is set
      !! (`ocean_state%barotropic%b`) and land masking
      !! (`configure_ocean_land_mask`) and BEFORE `ocean_state_enter_data` —
      !! the `!$acc enter data copyin` in `barotropic_workstate_enter_data`
      !! carries these host-filled values to the device (CLAUDE.md gotcha
      !! (2): arrays mapped `create` do not carry pre-map host values, so
      !! this ordering is load-bearing).
      type(config_t), intent(in) :: cfg
      type(ocean_state_t), intent(inout) :: ocean_state
      type(hgrid_t), intent(in) :: grid
      integer, intent(in) :: compute_rank
      integer, intent(out), optional :: ierr
         !! Non-zero on an unreachable/unimplemented `wave_drag_form` when
         !! present; absent behaves as today (`error stop`).
      real(wp), allocatable :: r_h(:, :)
      integer :: i, j, nx, ny

      associate (bw => ocean_state%dyn%bt_work, bcfg => cfg%ocean%bt)
         bw%lwd_enable = bcfg%wave_drag
         if (.not. bcfg%wave_drag) then
            if (present(ierr)) ierr = OCEAN_STATUS_OK
            return
         end if

         nx = grid%nx_total
         ny = grid%ny_total
         allocate (bw%lwd_drag_u(nx + 1, ny), source=0.0_wp)
         allocate (bw%lwd_drag_v(nx, ny + 1), source=0.0_wp)
         allocate (r_h(nx, ny), source=0.0_wp)

         select case (trim(bcfg%wave_drag_form))
         case ("uniform")
            r_h = bcfg%wave_drag_r_uniform
         case ("roughness_proxy")
            call wave_drag_roughness_proxy(ocean_state%barotropic%b, &
                                           ocean_state%metrics%wet_T, &
                                           nx, ny, grid%nghost, bcfg%wave_drag_kappa, &
                                           bcfg%wave_drag_n_bot, bcfg%wave_drag_h2_max, r_h)
         case default
            ! Unreachable: validate_config fails loud on any other tag
            ! (including "file", registered but not yet implemented).
            call fail("configure_ocean_wave_drag: unreachable wave_drag_form='"// &
                      trim(bcfg%wave_drag_form)//"'", ierr, OCEAN_STATUS_ERR_SETUP)
            return
         end select

         r_h = bcfg%wave_drag_scale*r_h

         ! h -> face average (as MOM6 forms its wave-drag face map), built ONCE
         ! here; the array-edge faces (i=1/nx+1, j=1/ny+1) stay at their
         ! source=0.0 init value.
         do i = 2, nx
            do j = 1, ny
               bw%lwd_drag_u(i, j) = 0.5_wp*(r_h(i - 1, j) + r_h(i, j))
            end do
         end do
         do j = 2, ny
            do i = 1, nx
               bw%lwd_drag_v(i, j) = 0.5_wp*(r_h(i, j - 1) + r_h(i, j))
            end do
         end do

         if (compute_rank == 0) then
            call logger%info("Barotropic wave drag: ON  form="//trim(bcfg%wave_drag_form)// &
                             "  scale="//to_string(bcfg%wave_drag_scale)// &
                             "  max(r_H)="//to_string(maxval(bw%lwd_drag_u))// &
                             " m/s  mean(r_H)="// &
                             to_string(sum(bw%lwd_drag_u)/real(size(bw%lwd_drag_u), wp))//" m/s")
         end if
      end associate
      if (present(ierr)) ierr = OCEAN_STATUS_OK
   end subroutine configure_ocean_wave_drag