rdb_ocean_halo Module

Ocean staggered halo exchange — the ONLY backend.

At px==1 / py==1 the X / Y pass never enters a collective: it either applies ocean_periodic_wrap_* locally or does nothing. That is what lets this module compile and run against pic-mpi’s serial backend, which error stops on point-to-point calls by design.


Uses

  • module~~rdb_ocean_halo~~UsesGraph module~rdb_ocean_halo rdb_ocean_halo module~rdb_comm_env rdb_comm_env module~rdb_ocean_halo->module~rdb_comm_env module~rdb_constants rdb_constants module~rdb_ocean_halo->module~rdb_constants module~rdb_decomp rdb_decomp module~rdb_ocean_halo->module~rdb_decomp module~rdb_error_ring rdb_error_ring module~rdb_ocean_halo->module~rdb_error_ring module~rdb_ocean_halo_counters rdb_ocean_halo_counters module~rdb_ocean_halo->module~rdb_ocean_halo_counters module~rdb_ocean_periodic rdb_ocean_periodic module~rdb_ocean_halo->module~rdb_ocean_periodic module~rdb_ocean_status rdb_ocean_status module~rdb_ocean_halo->module~rdb_ocean_status pic_logger pic_logger module~rdb_ocean_halo->pic_logger pic_mpi_lib pic_mpi_lib module~rdb_ocean_halo->pic_mpi_lib pic_strings pic_strings module~rdb_ocean_halo->pic_strings module~rdb_comm_env->module~rdb_constants module~rdb_comm_env->pic_mpi_lib iso_fortran_env iso_fortran_env module~rdb_comm_env->iso_fortran_env pic_types pic_types module~rdb_constants->pic_types module~rdb_config rdb_config module~rdb_decomp->module~rdb_config module~rdb_error_ring->pic_logger module~rdb_ocean_halo_counters->pic_strings module~rdb_ocean_halo_counters->iso_fortran_env module~rdb_ocean_periodic->module~rdb_constants module~rdb_grid rdb_grid module~rdb_ocean_periodic->module~rdb_grid module~rdb_multilayer_state rdb_multilayer_state module~rdb_ocean_periodic->module~rdb_multilayer_state module~rdb_ocean_boundary_types rdb_ocean_boundary_types module~rdb_ocean_periodic->module~rdb_ocean_boundary_types module~rdb_config->module~rdb_constants module~rdb_config->module~rdb_error_ring module~rdb_config->module~rdb_ocean_status module~rdb_config->pic_logger module~rdb_config->pic_strings module~rdb_ice_enthalpy rdb_ice_enthalpy module~rdb_config->module~rdb_ice_enthalpy module~rdb_ice_init rdb_ice_init module~rdb_config->module~rdb_ice_init module~rdb_nml_schema rdb_nml_schema module~rdb_config->module~rdb_nml_schema pic_ascii pic_ascii module~rdb_config->pic_ascii module~rdb_grid->module~rdb_constants module~rdb_multilayer_state->module~rdb_constants module~rdb_multilayer_state->module~rdb_error_ring module~rdb_multilayer_state->pic_logger module~rdb_multilayer_state->iso_fortran_env module~rdb_multilayer_state->module~rdb_grid module~rdb_efp rdb_efp module~rdb_multilayer_state->module~rdb_efp module~rdb_mem_report rdb_mem_report module~rdb_multilayer_state->module~rdb_mem_report module~rdb_tracer rdb_tracer module~rdb_multilayer_state->module~rdb_tracer module~rdb_ocean_boundary_types->module~rdb_constants module~rdb_ocean_boundary_types->module~rdb_ocean_status module~rdb_ocean_boundary_types->pic_logger module~rdb_ocean_boundary_types->iso_fortran_env module~rdb_ocean_boundary_types->module~rdb_grid module~rdb_ocean_boundary_types->module~rdb_mem_report module~rdb_ocean_tide_astro rdb_ocean_tide_astro module~rdb_ocean_boundary_types->module~rdb_ocean_tide_astro module~rdb_ocean_boundary_types->pic_ascii module~rdb_efp->iso_fortran_env ieee_arithmetic ieee_arithmetic module~rdb_efp->ieee_arithmetic module~rdb_ice_enthalpy->module~rdb_constants module~rdb_ice_init->module~rdb_constants module~rdb_ice_init->module~rdb_grid module~rdb_ice_init->module~rdb_multilayer_state module~rdb_ice_init->module~rdb_ice_enthalpy module~rdb_ice_column rdb_ice_column module~rdb_ice_init->module~rdb_ice_column module~rdb_ice_state rdb_ice_state module~rdb_ice_init->module~rdb_ice_state module~rdb_ocean_metrics rdb_ocean_metrics module~rdb_ice_init->module~rdb_ocean_metrics module~rdb_mem_report->module~rdb_constants module~rdb_mem_report->pic_logger module~rdb_mem_report->pic_strings module~rdb_mem_report->iso_fortran_env module~rdb_nml_schema->module~rdb_constants module~rdb_nml_schema->module~rdb_error_ring module~rdb_nml_schema->pic_logger module~rdb_ocean_tide_astro->module~rdb_constants module~rdb_ocean_tide_astro->iso_fortran_env module~rdb_tracer->module~rdb_constants module~rdb_tracer->iso_fortran_env module~rdb_tracer->module~rdb_grid module~rdb_tracer->module~rdb_mem_report module~rdb_ice_column->module~rdb_constants module~rdb_ice_column->module~rdb_ice_enthalpy module~rdb_ice_mass rdb_ice_mass module~rdb_ice_column->module~rdb_ice_mass module~rdb_ice_optics rdb_ice_optics module~rdb_ice_column->module~rdb_ice_optics module~rdb_ice_state->module~rdb_constants module~rdb_ice_state->iso_fortran_env module~rdb_ice_state->module~rdb_grid module~rdb_ice_state->module~rdb_ice_enthalpy module~rdb_ice_state->module~rdb_mem_report module~rdb_ice_state->module~rdb_ice_column module~rdb_ocean_metrics->module~rdb_constants module~rdb_ocean_metrics->module~rdb_error_ring module~rdb_ocean_metrics->module~rdb_ocean_status module~rdb_ocean_metrics->pic_logger module~rdb_ocean_metrics->pic_strings module~rdb_ocean_metrics->iso_fortran_env module~rdb_ocean_metrics->module~rdb_grid module~rdb_ocean_metrics->module~rdb_mem_report module~rdb_io_netcdf rdb_io_netcdf module~rdb_ocean_metrics->module~rdb_io_netcdf module~rdb_ocean_bipolar rdb_ocean_bipolar module~rdb_ocean_metrics->module~rdb_ocean_bipolar module~rdb_ocean_fold rdb_ocean_fold module~rdb_ocean_metrics->module~rdb_ocean_fold netcdf netcdf module~rdb_ocean_metrics->netcdf

Used by

  • module~~rdb_ocean_halo~~UsedByGraph module~rdb_ocean_halo rdb_ocean_halo module~rdb_barotropic_substep rdb_barotropic_substep module~rdb_barotropic_substep->module~rdb_ocean_halo module~rdb_continuity rdb_continuity module~rdb_continuity->module~rdb_ocean_halo module~rdb_ice_evp rdb_ice_evp module~rdb_ice_evp->module~rdb_ocean_halo module~rdb_ice_transport rdb_ice_transport module~rdb_ice_transport->module~rdb_ocean_halo module~rdb_ice_transport->module~rdb_continuity module~rdb_ocean_halo_state rdb_ocean_halo_state module~rdb_ice_transport->module~rdb_ocean_halo_state module~rdb_ocean_bt_wide rdb_ocean_bt_wide module~rdb_ocean_bt_wide->module~rdb_ocean_halo module~rdb_ocean_bt_wide->module~rdb_barotropic_substep module~rdb_ocean_dyn rdb_ocean_dyn module~rdb_ocean_dyn->module~rdb_ocean_halo module~rdb_ocean_dyn->module~rdb_barotropic_substep module~rdb_ocean_dyn->module~rdb_continuity module~rdb_ocean_dyn->module~rdb_ocean_bt_wide module~rdb_ocean_dyn->module~rdb_ocean_halo_state module~rdb_ocean_engine rdb_ocean_engine module~rdb_ocean_engine->module~rdb_ocean_halo module~rdb_ocean_engine->module~rdb_ice_evp module~rdb_ocean_engine->module~rdb_ice_transport module~rdb_ocean_engine->module~rdb_ocean_dyn module~rdb_ocean_engine->module~rdb_ocean_halo_state module~rdb_ocean_setup rdb_ocean_setup module~rdb_ocean_engine->module~rdb_ocean_setup module~rdb_ice_ocean_coupler rdb_ice_ocean_coupler module~rdb_ocean_engine->module~rdb_ice_ocean_coupler module~rdb_ocean_data_forcing rdb_ocean_data_forcing module~rdb_ocean_engine->module~rdb_ocean_data_forcing module~rdb_ocean_state rdb_ocean_state module~rdb_ocean_engine->module~rdb_ocean_state module~rdb_ocean_diag_derived rdb_ocean_diag_derived module~rdb_ocean_engine->module~rdb_ocean_diag_derived module~rdb_ocean_diag_fills rdb_ocean_diag_fills module~rdb_ocean_engine->module~rdb_ocean_diag_fills module~rdb_ocean_halo_state->module~rdb_ocean_halo module~rdb_ocean_setup->module~rdb_ocean_halo module~rdb_ocean_setup->module~rdb_ocean_dyn module~rdb_ocean_setup->module~rdb_ocean_halo_state module~rdb_ocean_setup->module~rdb_ocean_state module~rdb_driver rdb_driver module~rdb_driver->module~rdb_ocean_dyn module~rdb_driver->module~rdb_ocean_engine module~rdb_driver->module~rdb_ocean_state module~rdb_handle rdb_handle module~rdb_handle->module~rdb_ocean_engine module~rdb_handle->module~rdb_ocean_state module~rdb_ice_ocean_coupler->module~rdb_ocean_halo_state module~rdb_ocean_api rdb_ocean_api module~rdb_ocean_api->module~rdb_ocean_dyn module~rdb_ocean_api->module~rdb_ocean_engine module~rdb_ocean_api->module~rdb_handle module~rdb_ocean_api->module~rdb_ocean_diag_derived module~rdb_ocean_api->module~rdb_ocean_diag_fills module~rdb_ocean_data_forcing->module~rdb_ocean_halo_state module~rdb_ocean_state->module~rdb_continuity module~rdb_ocean_state->module~rdb_ocean_dyn module~rdb_ocean_state->module~rdb_ocean_data_forcing module~rdb_ocean_diag_derived->module~rdb_ocean_state module~rdb_ocean_diag_derived->module~rdb_ocean_diag_fills module~rdb_ocean_diag_fills->module~rdb_ocean_state

Variables

Type Visibility Attributes Name Initial
integer, private, parameter :: MAX_REQS = 8

Upper bound on requests per exchange (2 per active direction x 2 axes)

integer, private, parameter :: TAG_OC_E_TO_W = 12

Westward send (filled into east-recv on peer)

integer, private, parameter :: TAG_OC_N_TO_S = 14

Southward send

integer, private, parameter :: TAG_OC_S_TO_N = 13

Northward send

integer, private, parameter :: TAG_OC_W_TO_E = 11

Eastward send (filled into west-recv on peer)

real(kind=wp), private, allocatable :: oh_buf_recv_east(:)

Data sent/received to/from the east neighbour (capacity = (ng+1)*ny_total)

real(kind=wp), private, allocatable :: oh_buf_recv_north(:)

Data sent/received to/from the north neighbour (capacity = (ng+1)*nx_total)

real(kind=wp), private, allocatable :: oh_buf_recv_south(:)

Data sent/received to/from the south neighbour (capacity = (ng+1)*nx_total)

real(kind=wp), private, allocatable :: oh_buf_recv_west(:)

Data sent/received to/from the west neighbour (capacity = (ng+1)*ny_total)

real(kind=wp), private, allocatable :: oh_buf_send_east(:)

Data sent/received to/from the east neighbour (capacity = (ng+1)*ny_total)

real(kind=wp), private, allocatable :: oh_buf_send_north(:)

Data sent/received to/from the north neighbour (capacity = (ng+1)*nx_total)

real(kind=wp), private, allocatable :: oh_buf_send_south(:)

Data sent/received to/from the south neighbour (capacity = (ng+1)*nx_total)

real(kind=wp), private, allocatable :: oh_buf_send_west(:)

Data sent/received to/from the west neighbour (capacity = (ng+1)*ny_total)

integer, private :: oh_cap_ew = 0

Allocated capacity for E/W buffers

integer, private :: oh_cap_ns = 0

Allocated capacity for N/S buffers

type(decomp_t), private :: oh_decomp

Copy of domain decomposition

logical, private :: oh_initialised = .false.

True after ocean_halo_init

integer, private :: oh_nghost = 0

Ghost cell width

integer, private :: oh_nx_local = 0

Physical cells in x on this subdomain

integer, private :: oh_nx_total = 0

nx_local + 2*nghost

integer, private :: oh_ny_local = 0

Physical cells in y on this subdomain

integer, private :: oh_ny_total = 0

ny_local + 2*nghost

logical, private :: oh_periodic_x = .false.

x axis is reentrant periodic

logical, private :: oh_periodic_y = .false.

y axis is reentrant periodic


Interfaces

public interface ocean_halo_centre

  • private subroutine ocean_halo_centre_2d(fld, device_resident)

    Two-pass X-then-Y halo exchange for a cell-centred 2D field.

    Arguments

    Type IntentOptional Attributes Name
    real(kind=wp), intent(inout) :: fld(oh_nx_total,oh_ny_total)

    Cell-centred 2D field (nx_total, ny_total)

    logical, intent(in), optional :: device_resident

    If .false., operate on host memory (no OpenACC directives). Default (.true.) is the normal device-resident path.

  • private subroutine ocean_halo_centre_3d(fld, nz, device_resident)

    Two-pass X-then-Y halo exchange for a cell-centred 3D field. Batched: packs ALL nz layers into one buffer per direction and posts ONE isend+irecv pair per needed direction (not per layer). Buffer index formula: ((L-1)rows + (row-1))width + k_within_strip where L=layer, rows=nyt, width=ng (centre X-pass).

    Arguments

    Type IntentOptional Attributes Name
    real(kind=wp), intent(inout) :: fld(oh_nx_total,oh_ny_total,nz)

    Cell-centred 3D field (nx_total, ny_total, nz)

    integer, intent(in) :: nz

    Number of vertical layers

    logical, intent(in), optional :: device_resident

    If .false., operate on host memory (no OpenACC directives). Default (.true.) is the normal device-resident path.

public interface ocean_halo_face_x

  • private subroutine ocean_halo_face_x_2d(fld, device_resident)

    Two-pass X-then-Y halo exchange for a 2D x-face field.

    Index map (ng=nghost, nxl=nx_local): Send EAST (ng+1 per j-row): source i = nxl+1..ng+nxl+1 (last i = ng+nxl+1 is owned seam face; first ng are pre-seam interior) → fills east-nbr’s i = 1..ng+1 (west ghosts + seam-copy overwrite)

    Recv FROM EAST (ng per j-row): east-nbr sends its i = ng+2..2*ng+1 → fills OUR east ghosts i = ng+nxl+2..ng+nxl+ng+1

    Send WEST (ng per j-row): source i = ng+2..2*ng+1 → fills west-nbr’s east ghosts

    Recv FROM WEST (ng+1 per j-row): west-nbr sends its owned seam + ng interior → fills OUR i = 1..ng+1

    Arguments

    Type IntentOptional Attributes Name
    real(kind=wp), intent(inout) :: fld(oh_nx_total+1,oh_ny_total)

    x-face field (nx_total+1, ny_total)

    logical, intent(in), optional :: device_resident

    If .false., operate on host memory (no OpenACC directives). Default (.true.) is the normal device-resident path.

  • private subroutine ocean_halo_face_x_3d(fld, nz, device_resident)

    Two-pass X-then-Y halo exchange for a 3D x-face field. Batched: packs ALL nz layers into one buffer per direction. Face-x ownership: west rank sends (ng+1)nytnz eastward, east rank sends ngnytnz westward (D1 asymmetry preserved). Y-pass strip is nxt1ngnz (full face-x i extent × ng rows × nz).

    Arguments

    Type IntentOptional Attributes Name
    real(kind=wp), intent(inout) :: fld(oh_nx_total+1,oh_ny_total,nz)

    x-face field (nx_total+1, ny_total, nz)

    integer, intent(in) :: nz

    Number of vertical layers

    logical, intent(in), optional :: device_resident

    If .false., operate on host memory (no OpenACC directives). Default (.true.) is the normal device-resident path.

public interface ocean_halo_face_y

  • private subroutine ocean_halo_face_y_2d(fld, device_resident)

    Two-pass X-then-Y halo exchange for a 2D y-face field. Symmetric to face_x_2d with i↔j, x↔y.

    Index map (ng=nghost, nyl=ny_local): Send NORTH (ng+1 per i-col): source j = nyl+1..ng+nyl+1 (last j = ng+nyl+1 is owned seam face; my j == north-nbr’s j_N + nyl) → fills north-nbr’s j = 1..ng+1 (south ghosts + seam-copy)

    Recv FROM NORTH (ng per i-col): north-nbr sends j = ng+2..2*ng+1 → fills OUR north ghosts j = ng+nyl+2..ng+nyl+ng+1

    Send SOUTH (ng per i-col): source j = ng+2..2*ng+1 Recv FROM SOUTH (ng+1 per i-col): fills OUR j = 1..ng+1

    Arguments

    Type IntentOptional Attributes Name
    real(kind=wp), intent(inout) :: fld(oh_nx_total,oh_ny_total+1)

    y-face field (nx_total, ny_total+1)

    logical, intent(in), optional :: device_resident

    If .false., operate on host memory (no OpenACC directives). Default (.true.) is the normal device-resident path.

  • private subroutine ocean_halo_face_y_3d(fld, nz, device_resident)

    Two-pass X-then-Y halo exchange for a 3D y-face field. Batched: packs ALL nz layers into one buffer per direction. Face-y ownership (D1): south rank sends (ng+1)nxtnz northward, north rank sends ngnxtnz southward. X-pass uses standard centre-style (ng per column per layer over nyt1 rows).

    Arguments

    Type IntentOptional Attributes Name
    real(kind=wp), intent(inout) :: fld(oh_nx_total,oh_ny_total+1,nz)

    y-face field (nx_total, ny_total+1, nz)

    integer, intent(in) :: nz

    Number of vertical layers

    logical, intent(in), optional :: device_resident

    If .false., operate on host memory (no OpenACC directives). Default (.true.) is the normal device-resident path.


Functions

public pure function ocean_halo_is_decomposed() result(flag)

True iff a genuine multi-rank seam exists (initialised, px>1 or py>1).

Arguments

None

Return Value logical

public pure function ocean_halo_is_decomposed_x() result(flag)

True iff the X axis is split across ranks (px>1); skip the local x wrap.

Arguments

None

Return Value logical

public pure function ocean_halo_is_decomposed_y() result(flag)

Y analogue of ocean_halo_is_decomposed_x (py>1).

Arguments

None

Return Value logical

public pure function ocean_halo_is_init() result(flag)

True if ocean_halo_init has been called and not yet destroyed.

Arguments

None

Return Value logical

private pure function ew_rank_east() result(r)

East neighbour rank with periodic wrap-around.

Arguments

None

Return Value integer

private pure function ew_rank_west() result(r)

West neighbour rank with periodic wrap-around.

Arguments

None

Return Value integer

private pure function ns_rank_north() result(r)

North neighbour rank with periodic wrap-around.

Arguments

None

Return Value integer

private pure function ns_rank_south() result(r)

South neighbour rank with periodic wrap-around.

Arguments

None

Return Value integer


Subroutines

public subroutine ocean_halo_bt_group_2d(eta, ubt, vbt, device_resident)

Single-call two-pass exchange of three barotropic fields. Calls the three individual 2D exchanges in order, which each run their own full two-pass X-then-Y exchange.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: eta(oh_nx_total,oh_ny_total)

Barotropic sea-surface height (nx_total x ny_total)

real(kind=wp), intent(inout) :: ubt(oh_nx_total+1,oh_ny_total)

Barotropic u-transport (nx_total+1 x ny_total)

real(kind=wp), intent(inout) :: vbt(oh_nx_total,oh_ny_total+1)

Barotropic v-transport (nx_total x ny_total+1)

logical, intent(in), optional :: device_resident

Forwarded to the three individual exchanges. See centre_2d.

public subroutine ocean_halo_bt_group_2d_wide(eta, ubt, vbt, ng_wide, device_resident)

Width-parameterized grouped barotropic exchange (eta+ubt+vbt). Bumps oh_count_bt_group; suppresses the three inner primitive counters exactly as ocean_halo_bt_group_2d does.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: eta(oh_nx_local+2*ng_wide,oh_ny_local+2*ng_wide)

Barotropic SSH (nx_local+2ng_wide, ny_local+2ng_wide)

real(kind=wp), intent(inout) :: ubt(oh_nx_local+2*ng_wide+1,oh_ny_local+2*ng_wide)

Barotropic u-transport (nx_local+2ng_wide+1, ny_local+2ng_wide)

real(kind=wp), intent(inout) :: vbt(oh_nx_local+2*ng_wide,oh_ny_local+2*ng_wide+1)

Barotropic v-transport (nx_local+2ng_wide, ny_local+2ng_wide+1)

integer, intent(in) :: ng_wide

Wide ghost cell width (>= oh_nghost)

logical, intent(in), optional :: device_resident

Forwarded to the three individual exchanges. See centre_2d.

public subroutine ocean_halo_centre_2d_wide(fld, ng_wide, device_resident)

Width-parameterized centre-2D halo exchange. Identical algorithm to ocean_halo_centre_2d but operates on a wider ghost band ng_wide (>= oh_nghost). Fail-loud guards prevent ng_wide from exceeding the neighbour interior.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: fld(oh_nx_local+2*ng_wide,oh_ny_local+2*ng_wide)

Cell-centred 2D field (nx_local + 2ng_wide, ny_local + 2ng_wide)

integer, intent(in) :: ng_wide

Wide ghost cell width (>= oh_nghost)

logical, intent(in), optional :: device_resident

If .false., operate on host memory. Default = .true.

public subroutine ocean_halo_destroy()

Release buffers and topology state. Idempotent.

Arguments

None

public subroutine ocean_halo_face_x_2d_wide(fld, ng_wide, device_resident)

Width-parameterized face-x-2D halo exchange.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: fld(oh_nx_local+2*ng_wide+1,oh_ny_local+2*ng_wide)

x-face 2D field (nx_local + 2ng_wide + 1, ny_local + 2ng_wide)

integer, intent(in) :: ng_wide

Wide ghost cell width (>= oh_nghost)

logical, intent(in), optional :: device_resident

If .false., operate on host memory. Default = .true.

public subroutine ocean_halo_face_y_2d_wide(fld, ng_wide, device_resident)

Width-parameterized face-y-2D halo exchange.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: fld(oh_nx_local+2*ng_wide,oh_ny_local+2*ng_wide+1)

y-face 2D field (nx_local + 2ng_wide, ny_local + 2ng_wide + 1)

integer, intent(in) :: ng_wide

Wide ghost cell width (>= oh_nghost)

logical, intent(in), optional :: device_resident

If .false., operate on host memory. Default = .true.

public subroutine ocean_halo_init(decomp, nghost, periodic_x, periodic_y, ierr)

Initialise topology and allocate persistent device-resident buffers. Idempotent: destroys prior state before re-init on grid change.

Arguments

Type IntentOptional Attributes Name
type(decomp_t), intent(in) :: decomp

Domain decomposition descriptor

integer, intent(in) :: nghost

Ghost cell width

logical, intent(in) :: periodic_x

Reentrant periodic in x

logical, intent(in) :: periodic_y

Reentrant periodic in y

integer, intent(out), optional :: ierr

Non-zero (OCEAN_STATUS_ERR_SETUP) on the decomposed-run nghost<3 seam-stencil guard when present; absent behaves as today (error stop). (F5 residual, P2.4)

public subroutine ocean_halo_reserve(nz, ng_wide, ierr)

Pre-size the pack/recv buffers to the worst-case capacity for this run at init time, so that NO device reallocation fires mid-run.

Read more…

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nz

Layer count for 3D batched exchanges (0 = not used)

integer, intent(in) :: ng_wide

Wide-ghost width for the barotropic march-in (0 = not used)

integer, intent(out), optional :: ierr

Non-zero (OCEAN_STATUS_ERR_SETUP) when called before ocean_halo_init when present; absent behaves as today (error stop). (F5 residual, P2.4)

private pure subroutine needs_flags(need_w, need_e, need_s, need_n)

Compute which directions need actual MPI or local-wrap work.

Arguments

Type IntentOptional Attributes Name
logical, intent(out) :: need_w
logical, intent(out) :: need_e
logical, intent(out) :: need_s
logical, intent(out) :: need_n

private subroutine ocean_halo_buffers_ensure_nz(nz)

Grow the persistent send/recv buffers to hold at least nz layers. Called at the top of each 3D exchange routine before pack/unpack. The 2D routines use the same buffers and always need <= any 3D capacity, so they are unaffected.

Read more…

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nz

Number of vertical layers required

private subroutine ocean_halo_buffers_ensure_wide(ng_wide)

Grow the persistent send/recv buffers to hold at least a wide 2D exchange at ghost width ng_wide. Uses the same exit-delete / dealloc / alloc / enter-create pattern as ocean_halo_buffers_ensure_nz. Safe to call with ng_wide == oh_nghost (no-op if already large enough).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: ng_wide

Wide ghost cell width required

private subroutine ocean_halo_centre_2d(fld, device_resident)

Two-pass X-then-Y halo exchange for a cell-centred 2D field.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: fld(oh_nx_total,oh_ny_total)

Cell-centred 2D field (nx_total, ny_total)

logical, intent(in), optional :: device_resident

If .false., operate on host memory (no OpenACC directives). Default (.true.) is the normal device-resident path.

private subroutine ocean_halo_centre_2d_impl(fld, ng, device_resident)

Two-pass X-then-Y halo exchange for a cell-centred 2D field. Core body shared by ocean_halo_centre_2d (ng=oh_nghost) and ocean_halo_centre_2d_wide (ng=ng_wide).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: fld(oh_nx_local+2*ng,oh_ny_local+2*ng)

Cell-centred 2D field

integer, intent(in) :: ng

Ghost cell width for this exchange

logical, intent(in), optional :: device_resident

If .false., operate on host memory. Default = .true.

private subroutine ocean_halo_centre_3d(fld, nz, device_resident)

Two-pass X-then-Y halo exchange for a cell-centred 3D field. Batched: packs ALL nz layers into one buffer per direction and posts ONE isend+irecv pair per needed direction (not per layer). Buffer index formula: ((L-1)rows + (row-1))width + k_within_strip where L=layer, rows=nyt, width=ng (centre X-pass).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: fld(oh_nx_total,oh_ny_total,nz)

Cell-centred 3D field (nx_total, ny_total, nz)

integer, intent(in) :: nz

Number of vertical layers

logical, intent(in), optional :: device_resident

If .false., operate on host memory (no OpenACC directives). Default (.true.) is the normal device-resident path.

private subroutine ocean_halo_face_x_2d(fld, device_resident)

Two-pass X-then-Y halo exchange for a 2D x-face field.

Read more…

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: fld(oh_nx_total+1,oh_ny_total)

x-face field (nx_total+1, ny_total)

logical, intent(in), optional :: device_resident

If .false., operate on host memory (no OpenACC directives). Default (.true.) is the normal device-resident path.

private subroutine ocean_halo_face_x_2d_impl(fld, ng, device_resident)

Two-pass X-then-Y halo exchange for a 2D x-face field. Core body shared by ocean_halo_face_x_2d (ng=oh_nghost) and ocean_halo_face_x_2d_wide (ng=ng_wide).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: fld(oh_nx_local+2*ng+1,oh_ny_local+2*ng)

x-face field (nx_local + 2ng + 1, ny_local + 2ng)

integer, intent(in) :: ng

Ghost cell width for this exchange

logical, intent(in), optional :: device_resident

If .false., operate on host memory. Default = .true.

private subroutine ocean_halo_face_x_3d(fld, nz, device_resident)

Two-pass X-then-Y halo exchange for a 3D x-face field. Batched: packs ALL nz layers into one buffer per direction. Face-x ownership: west rank sends (ng+1)nytnz eastward, east rank sends ngnytnz westward (D1 asymmetry preserved). Y-pass strip is nxt1ngnz (full face-x i extent × ng rows × nz).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: fld(oh_nx_total+1,oh_ny_total,nz)

x-face field (nx_total+1, ny_total, nz)

integer, intent(in) :: nz

Number of vertical layers

logical, intent(in), optional :: device_resident

If .false., operate on host memory (no OpenACC directives). Default (.true.) is the normal device-resident path.

private subroutine ocean_halo_face_y_2d(fld, device_resident)

Two-pass X-then-Y halo exchange for a 2D y-face field. Symmetric to face_x_2d with i↔j, x↔y.

Read more…

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: fld(oh_nx_total,oh_ny_total+1)

y-face field (nx_total, ny_total+1)

logical, intent(in), optional :: device_resident

If .false., operate on host memory (no OpenACC directives). Default (.true.) is the normal device-resident path.

private subroutine ocean_halo_face_y_2d_impl(fld, ng, device_resident)

Two-pass X-then-Y halo exchange for a 2D y-face field. Core body shared by ocean_halo_face_y_2d (ng=oh_nghost) and ocean_halo_face_y_2d_wide (ng=ng_wide).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: fld(oh_nx_local+2*ng,oh_ny_local+2*ng+1)

y-face field (nx_local + 2ng, ny_local + 2ng + 1)

integer, intent(in) :: ng

Ghost cell width for this exchange

logical, intent(in), optional :: device_resident

If .false., operate on host memory. Default = .true.

private subroutine ocean_halo_face_y_3d(fld, nz, device_resident)

Two-pass X-then-Y halo exchange for a 3D y-face field. Batched: packs ALL nz layers into one buffer per direction. Face-y ownership (D1): south rank sends (ng+1)nxtnz northward, north rank sends ngnxtnz southward. X-pass uses standard centre-style (ng per column per layer over nyt1 rows).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: fld(oh_nx_total,oh_ny_total+1,nz)

y-face field (nx_total, ny_total+1, nz)

integer, intent(in) :: nz

Number of vertical layers

logical, intent(in), optional :: device_resident

If .false., operate on host memory (no OpenACC directives). Default (.true.) is the normal device-resident path.

private subroutine wide_halo_guards(ng_wide, caller)

Fail-loud validation for wide halo entry points. Called at the top of every *_wide public routine.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: ng_wide

Requested wide ghost width

character(len=*), intent(in) :: caller

Caller name for error messages