pure subroutine update_reservoir_meridional_north(hTr, h_layer, mass_flux_y, &
tres_n, T_data, &
nx_total, ny_total, nz, &
j_n, i0, i1, &
L_out, L_in, dt, it, n_tr)
!! Update reservoir for the north open edge.
!! Wall-face index = j_n+1; interior cell = j_n.
!! Outward normal = +y: u_n = +mass_flux_y(i,j_n+1,k)/max(h,hmin).
integer, intent(in) :: nx_total, ny_total, nz, n_tr, it
integer, intent(in) :: j_n, i0, i1
real(wp), intent(in) :: hTr(nx_total, ny_total, nz)
real(wp), intent(in) :: h_layer(nx_total, ny_total, nz)
real(wp), intent(in) :: mass_flux_y(nx_total, ny_total + 1, nz)
real(wp), intent(inout) :: tres_n(nx_total, nz, n_tr)
real(wp), intent(in) :: T_data
real(wp), intent(in) :: L_out, L_in, dt
integer :: i, k
real(wp) :: h_int, T_int, u_n, c_out, c_in, tres_old, denom
do concurrent(i=i0:i1, k=1:nz) local(h_int, T_int, u_n, c_out, c_in, tres_old, denom)
h_int = max(h_layer(i, j_n, k), RES_H_MIN)
T_int = hTr(i, j_n, k)/h_int
u_n = mass_flux_y(i, j_n + 1, k)/h_int
tres_old = tres_n(i, k, it)
if (L_out == 0.0_wp .and. u_n > 0.0_wp) then
tres_n(i, k, it) = T_int
else if (L_in == 0.0_wp .and. u_n < 0.0_wp) then
tres_n(i, k, it) = T_data
else
c_out = merge(max(0.0_wp, u_n)*dt/L_out, 0.0_wp, L_out > 0.0_wp)
c_in = merge(max(0.0_wp, -u_n)*dt/L_in, 0.0_wp, L_in > 0.0_wp)
denom = 1.0_wp + c_out + c_in
tres_n(i, k, it) = (tres_old + c_out*T_int + c_in*T_data)/denom
end if
end do
end subroutine update_reservoir_meridional_north