cavity_mass_salt_mirror_impl Subroutine

public pure subroutine cavity_mass_salt_mirror_impl(nx, ny, nz, dt_over_rho0, inv_rho0_dt, s_ice, active, melt, s_far, hTr, k_top)

The pseudo-salt mirror of cavity_mass_apply_impl’s SALT increment, with no budget accumulation — budget_id = NONE, so it must not touch salt_budget_surface.

Pseudo-salt’s documented purpose is to be a PASSIVE tracer given exactly salinity’s surface salt flux, so the deviation measures the passive-vs-active transport-path error. Under the real-mass form salinity’s surface salt flux is w*s_ice (and the dilution by the added volume, which pseudo-salt gets for free because it shares h), so the mirror must receive the same correction — or it would keep the virtual flux salinity no longer has and the deviation would measure the bookkeeping instead of the transport.

The arithmetic is the SAME EXPRESSION as the salt branch above, so the increment is bit-identical to salinity’s.

Arguments

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

First dimension.

integer, intent(in) :: ny

Second dimension.

integer, intent(in) :: nz

Layer count.

real(kind=wp), intent(in) :: dt_over_rho0

dt/rho_0.

real(kind=wp), intent(in) :: inv_rho0_dt

The same dt/rho_0 (see the sibling’s docstring).

real(kind=wp), intent(in) :: s_ice

Ice salinity (g/kg).

real(kind=wp), intent(in) :: active(nx,ny)

Composed solve mask.

real(kind=wp), intent(in) :: melt(nx,ny)

Melt mass flux (kg/m^2/s).

real(kind=wp), intent(in) :: s_far(nx,ny)

Far-field salinity (g/kg); the virtual component being undone is rebuilt from it, exactly as in the sibling.

real(kind=wp), intent(inout) :: hTr(nx,ny,nz)

Pseudo-salt h*C.

integer, intent(in) :: k_top(nx,ny)

The SAME first-live-layer index the salt branch used — the mirror’s whole contract is that its increment is bit-identical to salinity’s, which includes landing on the same row.


Calls

proc~~cavity_mass_salt_mirror_impl~~CallsGraph proc~cavity_mass_salt_mirror_impl cavity_mass_salt_mirror_impl local local proc~cavity_mass_salt_mirror_impl->local

Called by

proc~~cavity_mass_salt_mirror_impl~~CalledByGraph proc~cavity_mass_salt_mirror_impl cavity_mass_salt_mirror_impl proc~ocean_cavity_mass_step ocean_cavity_mass_step proc~ocean_cavity_mass_step->proc~cavity_mass_salt_mirror_impl proc~run_stage run_stage proc~run_stage->proc~ocean_cavity_mass_step proc~run_stage_split run_stage_split proc~run_stage_split->proc~ocean_cavity_mass_step proc~ocean_dyn_step ocean_dyn_step proc~ocean_dyn_step->proc~run_stage 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 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

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private :: cell_s
integer, private :: i
integer, private :: j
real(kind=wp), private :: virt

Source Code

   pure subroutine cavity_mass_salt_mirror_impl(nx, ny, nz, dt_over_rho0, inv_rho0_dt, &
                                                s_ice, active, melt, s_far, hTr, k_top)
      !! The pseudo-salt mirror of `cavity_mass_apply_impl`'s SALT
      !! increment, with no budget accumulation — `budget_id = NONE`, so
      !! it must not touch `salt_budget_surface`.
      !!
      !! Pseudo-salt's documented purpose is to be a PASSIVE tracer given
      !! exactly salinity's surface salt flux, so the deviation measures
      !! the passive-vs-active transport-path error.  Under the real-mass
      !! form salinity's surface salt flux is `w*s_ice` (and the dilution
      !! by the added volume, which pseudo-salt gets for free because it
      !! shares `h`), so the mirror must receive the same correction — or
      !! it would keep the virtual flux salinity no longer has and the
      !! deviation would measure the bookkeeping instead of the transport.
      !!
      !! The arithmetic is the SAME EXPRESSION as the salt branch above,
      !! so the increment is bit-identical to salinity's.
      integer, intent(in) :: nx
         !! First dimension.
      integer, intent(in) :: ny
         !! Second dimension.
      integer, intent(in) :: nz
         !! Layer count.
      real(wp), intent(in) :: dt_over_rho0
         !! `dt/rho_0`.
      real(wp), intent(in) :: inv_rho0_dt
         !! The same `dt/rho_0` (see the sibling's docstring).
      real(wp), intent(in) :: s_ice
         !! Ice salinity (g/kg).
      real(wp), intent(in) :: active(nx, ny)
         !! Composed solve mask.
      real(wp), intent(in) :: melt(nx, ny)
         !! Melt mass flux (kg/m^2/s).
      real(wp), intent(in) :: s_far(nx, ny)
         !! Far-field salinity (g/kg); the virtual component being
         !! undone is rebuilt from it, exactly as in the sibling.
      real(wp), intent(inout) :: hTr(nx, ny, nz)
         !! Pseudo-salt `h*C`.
      integer, intent(in) :: k_top(nx, ny)
         !! The SAME first-live-layer index the salt branch used — the
         !! mirror's whole contract is that its increment is bit-identical
         !! to salinity's, which includes landing on the same row.
      integer :: i, j
      real(wp) :: cell_s, virt

      do concurrent(j=1:ny, i=1:nx) local(cell_s, virt)
         if (active(i, j) > 0.5_wp) then
            virt = -melt(i, j)*(s_far(i, j) - s_ice)
            cell_s = -inv_rho0_dt*virt + melt(i, j)*dt_over_rho0*s_ice
            hTr(i, j, k_top(i, j)) = hTr(i, j, k_top(i, j)) + cell_s
         end if
      end do
   end subroutine cavity_mass_salt_mirror_impl