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 | Intent | Optional | 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 |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | i | ||||
| integer, | private | :: | j | ||||
| integer, | private | :: | nx | ||||
| integer, | private | :: | ny | ||||
| real(kind=wp), | private, | allocatable | :: | r_h(:,:) |
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