public pure subroutine vcoord_target_dz_column_zstar_full(nz, H, z_ref_col, h_min, dz)
Compute target layer thicknesses for VCOORD_ZSTAR_FULL.
Inputs: z_ref_col(0:nz) local reference (top-down, 0=surface, nz=h_bed);
H current total depth (m) = h_bed + η; h_min vanishing-layer floor (m).
Output: dz(1:nz) ROMS-ordered (dz(1) bottom, dz(nz) surface),
sum(dz) = H exactly, vanishing rows set to h_min.
Surface layer absorbs η; if H < h_bed the deepest layers clip to h_min
and the surface is trimmed to keep sum = H.
Arguments
| Type |
Intent | Optional | Attributes |
|
Name |
|
|
integer,
|
intent(in) |
|
|
:: |
nz |
|
|
real(kind=wp),
|
intent(in) |
|
|
:: |
H |
|
|
real(kind=wp),
|
intent(in) |
|
|
:: |
z_ref_col(0:nz) |
|
|
real(kind=wp),
|
intent(in) |
|
|
:: |
h_min |
|
|
real(kind=wp),
|
intent(out) |
|
|
:: |
dz(nz) |
|
Variables
| Type |
Visibility | Attributes |
|
Name |
| Initial | |
|
real(kind=wp),
|
private |
|
:: |
H_eff |
|
|
|
|
real(kind=wp),
|
private |
|
:: |
deficit |
|
|
|
|
real(kind=wp),
|
private |
|
:: |
dz_top_kt |
|
|
|
|
real(kind=wp),
|
private |
|
:: |
eta |
|
|
|
|
real(kind=wp),
|
private |
|
:: |
h_bed_ref |
|
|
|
|
integer,
|
private |
|
:: |
k |
|
|
|
|
integer,
|
private |
|
:: |
kt |
|
|
|
|
real(kind=wp),
|
private |
|
:: |
sum_dz |
|
|
|
|
real(kind=wp),
|
private |
|
:: |
z_lower |
|
|
|
|
real(kind=wp),
|
private |
|
:: |
z_upper |
|
|
|
Source Code
pure subroutine vcoord_target_dz_column_zstar_full(nz, H, z_ref_col, &
h_min, dz)
!$acc routine seq
!! Compute target layer thicknesses for VCOORD_ZSTAR_FULL.
!! Inputs: z_ref_col(0:nz) local reference (top-down, 0=surface, nz=h_bed);
!! H current total depth (m) = h_bed + η; h_min vanishing-layer floor (m).
!! Output: dz(1:nz) ROMS-ordered (dz(1) bottom, dz(nz) surface),
!! sum(dz) = H exactly, vanishing rows set to h_min.
!! Surface layer absorbs η; if H < h_bed the deepest layers clip to h_min
!! and the surface is trimmed to keep sum = H.
integer, intent(in) :: nz
real(wp), intent(in) :: H
real(wp), intent(in) :: z_ref_col(0:nz)
real(wp), intent(in) :: h_min
real(wp), intent(out) :: dz(nz)
real(wp) :: dz_top_kt, z_upper, z_lower, H_eff, h_bed_ref, eta
real(wp) :: sum_dz, deficit
integer :: kt, k
h_bed_ref = z_ref_col(nz)
eta = H - h_bed_ref
H_eff = max(H, 0.0_wp)
if (eta >= 0.0_wp) then
! Column at or above reference depth. Subsurface layers keep
! their reference thicknesses; the surface layer absorbs the
! SSH offset. sum(dz) = h_bed_ref + eta = H exactly.
do kt = 1, nz
k = nz - kt + 1
dz_top_kt = max(z_ref_col(kt) - z_ref_col(kt - 1), 0.0_wp)
if (kt == 1) then
dz(k) = dz_top_kt + eta ! ROMS surface gets +η
else
dz(k) = dz_top_kt
end if
end do
else
! Column shallower than reference (H < h_bed_ref). Walk top-down:
! layer above bed keeps full thickness; straddling layer gets
! H_eff - z_upper; below-bed layer is vanishing (h_min). Then trim the
! surface so sum = H exactly (remap mass conservation needs this).
do kt = 1, nz
k = nz - kt + 1
z_upper = z_ref_col(kt - 1)
z_lower = z_ref_col(kt)
if (z_lower <= H_eff) then
dz(k) = z_lower - z_upper
else if (z_upper < H_eff) then
dz(k) = H_eff - z_upper
else
dz(k) = h_min
end if
end do
! Re-balance via the surface layer.
sum_dz = 0.0_wp
do k = 1, nz
sum_dz = sum_dz + dz(k)
end do
deficit = sum_dz - H_eff
if (deficit > 0.0_wp) then
if (dz(nz) - deficit >= h_min) then
dz(nz) = dz(nz) - deficit
else
! Too thin for the floor — set surface to h_min, let downstream
! physics guards (DRY_TOLERANCE) handle it; sum = H not enforced.
dz(nz) = h_min
end if
end if
end if
end subroutine vcoord_target_dz_column_zstar_full