Fold the north seam of h_layer, u/v layer faces, and every
registered tracer. Call AFTER ocean_periodic_wrap_state.
No-op when bc%north_fold is .false.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(ocean_bc_state_t), | intent(in) | :: | bc | |||
| type(multilayer_state_t), | intent(inout) | :: | ms | |||
| logical, | intent(in), | optional | :: | device_resident |
px > 1 only: |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | it | ||||
| integer, | private | :: | nghost | ||||
| integer, | private | :: | nx | ||||
| integer, | private | :: | nx_phys | ||||
| integer, | private | :: | ny | ||||
| integer, | private | :: | ny_phys | ||||
| integer, | private | :: | nz |
subroutine ocean_fold_wrap_state(grid, bc, ms, device_resident) !! Fold the north seam of h_layer, u/v layer faces, and every !! registered tracer. Call AFTER `ocean_periodic_wrap_state`. !! No-op when `bc%north_fold` is .false. type(hgrid_t), intent(in) :: grid type(ocean_bc_state_t), intent(in) :: bc type(multilayer_state_t), intent(inout) :: ms logical, intent(in), optional :: device_resident !! px > 1 only: `.false.` for host-side (pre-`enter_data`) calls. integer :: it integer :: nx, ny, nz, nx_phys, ny_phys, nghost if (.not. bc%north_fold) return nx = grid%nx_total ny = grid%ny_total nz = ms%nz_ml nx_phys = grid%nx_phys ny_phys = grid%ny_phys nghost = grid%nghost if (ocean_fold_is_distributed()) then ! One group: h (T), u (u, −), v (v, −, + fold row), every hTr (T). call ocean_fold_begin((nghost + 1)*nz*(3 + n_tracers(ms))) call ocean_fold_pack(ms%h_layer, nx, ny, nz, FOLD_STAG_T, device_resident) call ocean_fold_pack(ms%u_face_x_layer, nx + 1, ny, nz, FOLD_STAG_U, device_resident) call ocean_fold_pack(ms%v_face_y_layer, nx, ny + 1, nz, FOLD_STAG_V, device_resident) if (allocated(ms%tracers)) then do it = 1, size(ms%tracers) if (.not. allocated(ms%tracers(it)%hTr)) cycle call ocean_fold_pack(ms%tracers(it)%hTr, nx, ny, nz, FOLD_STAG_T, device_resident) end do end if call ocean_fold_exchange(device_resident) call ocean_fold_unpack(ms%h_layer, nx, ny, nz, FOLD_STAG_T, .false., device_resident) call ocean_fold_unpack(ms%u_face_x_layer, nx + 1, ny, nz, FOLD_STAG_U, .true., & device_resident) call ocean_fold_unpack(ms%v_face_y_layer, nx, ny + 1, nz, FOLD_STAG_V, .true., & device_resident) if (allocated(ms%tracers)) then do it = 1, size(ms%tracers) if (.not. allocated(ms%tracers(it)%hTr)) cycle call ocean_fold_unpack(ms%tracers(it)%hTr, nx, ny, nz, FOLD_STAG_T, .false., & device_resident) end do end if call ocean_fold_end() return end if ! Centre (T): h_layer. call fold_north_centre(ms%h_layer, nx, ny, nz, & nx_phys, ny_phys, nghost) ! u-face (Cu): negate. call fold_north_u_face(ms%u_face_x_layer, nx + 1, ny, nz, & nx_phys, ny_phys, nghost) ! v-face (Cv): negate + on-row antisymmetric projection. call fold_north_v_face(ms%v_face_y_layer, nx, ny + 1, nz, & nx_phys, ny_phys, nghost) ! Per-tracer loop OUTSIDE the DC kernels (outer-shim for array-of-DTs). if (allocated(ms%tracers)) then do it = 1, size(ms%tracers) if (.not. allocated(ms%tracers(it)%hTr)) cycle call fold_north_centre(ms%tracers(it)%hTr, nx, ny, nz, & nx_phys, ny_phys, nghost) end do end if end subroutine ocean_fold_wrap_state