ocean_sponge_apply_tracers Subroutine

public subroutine ocean_sponge_apply_tracers(grid, bc, ms, dt)

Relax tracer concentrations (hTr/h) toward per-edge targets in any sponge band with sponge_relax_tracers = .true.. Same cosine ramp and sponge_strength as the momentum kernel. No-op otherwise. Per-tracer loop outside the inner loops (outer-shim for the array-of-derived-types registry).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_bc_state_t), intent(in) :: bc
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: dt

Calls

proc~~ocean_sponge_apply_tracers~~CallsGraph proc~ocean_sponge_apply_tracers ocean_sponge_apply_tracers proc~sponge_relax_band_x_tracer sponge_relax_band_x_tracer proc~ocean_sponge_apply_tracers->proc~sponge_relax_band_x_tracer proc~sponge_relax_band_y_tracer sponge_relax_band_y_tracer proc~ocean_sponge_apply_tracers->proc~sponge_relax_band_y_tracer proc~relax_band_x_impl relax_band_x_impl proc~sponge_relax_band_x_tracer->proc~relax_band_x_impl proc~relax_band_y_impl relax_band_y_impl proc~sponge_relax_band_y_tracer->proc~relax_band_y_impl local local proc~relax_band_x_impl->local proc~relax_one relax_one proc~relax_band_x_impl->proc~relax_one proc~relax_band_y_impl->local proc~relax_band_y_impl->proc~relax_one proc~relax_toward relax_toward proc~relax_one->proc~relax_toward

Called by

proc~~ocean_sponge_apply_tracers~~CalledByGraph proc~ocean_sponge_apply_tracers ocean_sponge_apply_tracers proc~run_stage_split run_stage_split proc~run_stage_split->proc~ocean_sponge_apply_tracers proc~ocean_dyn_step_split ocean_dyn_step_split proc~ocean_dyn_step_split->proc~run_stage_split proc~engine_step engine_step proc~engine_step->proc~ocean_dyn_step_split proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_step proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private :: C_bc
integer, private :: band
integer, private :: i0
integer, private :: i1
integer, private :: it
integer, private :: j0
integer, private :: j1
integer, private :: nxt
integer, private :: nyt
integer, private :: nz
real(kind=wp), private :: strength
integer, private :: wall_face

Source Code

   subroutine ocean_sponge_apply_tracers(grid, bc, ms, dt)
      !! Relax tracer concentrations (hTr/h) toward per-edge targets in any
      !! sponge band with `sponge_relax_tracers = .true.`. Same cosine ramp
      !! and `sponge_strength` as the momentum kernel. No-op otherwise.
      !! Per-tracer loop outside the inner loops (outer-shim for the
      !! array-of-derived-types registry).
      type(hgrid_t), intent(in) :: grid
      type(ocean_bc_state_t), intent(in) :: bc
      type(multilayer_state_t), intent(inout) :: ms
      real(wp), intent(in) :: dt

      integer :: it
      integer :: i0, i1, j0, j1
      integer :: wall_face, band, nz, nxt, nyt
      real(wp) :: strength, C_bc

      nz = ms%nz_ml
      nxt = grid%nx_total
      nyt = grid%ny_total
      i0 = grid%nghost + 1
      i1 = grid%nghost + grid%nx_phys
      j0 = grid%nghost + 1
      j1 = grid%nghost + grid%ny_phys

      if (.not. allocated(ms%tracers)) return

      ! Per-tracer `it` loop stays OUTSIDE the `do concurrent` kernels
      ! (outer-shim): the hTr slice + h_layer reach the device as top-level
      ! explicit-shape allocatables in the `_impl` routines, never
      ! dereferenced as `ms%tracers(it)%hTr(...)` inside a device loop.

      ! ---- West edge ----
      ! has_* gate: a subdomain seam never carries a sponge band (O0).
      if (bc%west%bc_type == OBC_SPONGE .and. &
          bc%west%sponge_relax_tracers .and. &
          bc%west%sponge_width > 0 .and. &
          allocated(bc%west%clamped_tracer) .and. &
          bc%has_west) then
         band = bc%west%sponge_width
         strength = bc%west%sponge_strength
         wall_face = grid%nghost + 1
         do it = 1, size(ms%tracers)
            if (.not. allocated(ms%tracers(it)%hTr)) cycle
            if (it > size(bc%west%clamped_tracer)) cycle
            C_bc = bc%west%clamped_tracer(it)
            call sponge_relax_band_x_tracer(ms, it, nxt, nyt, nz, &
                                            j0, j1, wall_face, band, +1, strength, C_bc, dt)
         end do
      end if

      ! ---- East edge ----
      if (bc%east%bc_type == OBC_SPONGE .and. &
          bc%east%sponge_relax_tracers .and. &
          bc%east%sponge_width > 0 .and. &
          allocated(bc%east%clamped_tracer) .and. &
          bc%has_east) then
         band = bc%east%sponge_width
         strength = bc%east%sponge_strength
         wall_face = grid%nghost + grid%nx_phys + 1
         do it = 1, size(ms%tracers)
            if (.not. allocated(ms%tracers(it)%hTr)) cycle
            if (it > size(bc%east%clamped_tracer)) cycle
            C_bc = bc%east%clamped_tracer(it)
            call sponge_relax_band_x_tracer(ms, it, nxt, nyt, nz, &
                                            j0, j1, wall_face, band, -1, strength, C_bc, dt)
         end do
      end if

      ! ---- South edge ----
      if (bc%south%bc_type == OBC_SPONGE .and. &
          bc%south%sponge_relax_tracers .and. &
          bc%south%sponge_width > 0 .and. &
          allocated(bc%south%clamped_tracer) .and. &
          bc%has_south) then
         band = bc%south%sponge_width
         strength = bc%south%sponge_strength
         wall_face = grid%nghost + 1
         do it = 1, size(ms%tracers)
            if (.not. allocated(ms%tracers(it)%hTr)) cycle
            if (it > size(bc%south%clamped_tracer)) cycle
            C_bc = bc%south%clamped_tracer(it)
            call sponge_relax_band_y_tracer(ms, it, nxt, nyt, nz, &
                                            i0, i1, wall_face, band, +1, strength, C_bc, dt)
         end do
      end if

      ! ---- North edge ----
      if (bc%north%bc_type == OBC_SPONGE .and. &
          bc%north%sponge_relax_tracers .and. &
          bc%north%sponge_width > 0 .and. &
          allocated(bc%north%clamped_tracer) .and. &
          bc%has_north) then
         band = bc%north%sponge_width
         strength = bc%north%sponge_strength
         wall_face = grid%nghost + grid%ny_phys + 1
         do it = 1, size(ms%tracers)
            if (.not. allocated(ms%tracers(it)%hTr)) cycle
            if (it > size(bc%north%clamped_tracer)) cycle
            C_bc = bc%north%clamped_tracer(it)
            call sponge_relax_band_y_tracer(ms, it, nxt, nyt, nz, &
                                            i0, i1, wall_face, band, -1, strength, C_bc, dt)
         end do
      end if
   end subroutine ocean_sponge_apply_tracers