ice_optics_csim4 Subroutine

public pure subroutine ice_optics_csim4(nk, hs, hi, ts, sal_ice_top, albedo, abs_sfc, abs_snow, abs_ice_lay, abs_ocn, abs_int, pen)

CSIM4 albedo + Beer’s-law vertical SW partition (SIS_optics.F90:371-409). Exact port; inline literals 0.1235/0.075 (melt-albedo reductions) and 5.0/0.5 (thin-ice atan ramp) and 0.06 (thin-ice albedo floor) stay inline per SIS2 (SIS_optics.F90:378-384).

Partition identity (up to ~1 exp round-off): abs_sfc + abs_snow + sum(abs_ice_lay) + abs_ocn == 1, because opt_decay_lay**nk == exp(-hi/ICE_OPT_DEP_ICE).

Arguments

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

Number of ice layers (declared first — decl-order).

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

Snow thickness (m).

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

Ice thickness (m).

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

Skin/surface temperature stand-in (degC).

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

Bulk salinity of the top ice layer (PSU) — sets the melt-onset freezing temperature.

real(kind=wp), intent(out) :: albedo

Combined snow+ice broadband albedo (nondim).

real(kind=wp), intent(out) :: abs_sfc

Fraction of absorbed SW deposited at the surface skin.

real(kind=wp), intent(out) :: abs_snow

Fraction of absorbed SW deposited in the snow (always 0 in the CSIM4 branch — SIS2 keeps the term for symmetry with the delta-Eddington branch).

real(kind=wp), intent(out) :: abs_ice_lay(nk)

Fraction of absorbed SW deposited per ice layer, TOP-DOWN (abs_ice_lay(1) = top ice layer).

real(kind=wp), intent(out) :: abs_ocn

Fraction of absorbed SW transmitted through to the ocean.

real(kind=wp), intent(out) :: abs_int

Fraction of absorbed SW deposited in the ice interior (pen - sw_frac_top after the Beer’s-law drain).

real(kind=wp), intent(out) :: pen

Fraction of the total (post-albedo) SW that penetrates below the surface skin.


Calls

proc~~ice_optics_csim4~~CallsGraph proc~ice_optics_csim4 ice_optics_csim4 proc~ice_t_freeze ice_t_freeze proc~ice_optics_csim4->proc~ice_t_freeze

Called by

proc~~ice_optics_csim4~~CalledByGraph proc~ice_optics_csim4 ice_optics_csim4 proc~ice_column_step ice_column_step proc~ice_column_step->proc~ice_optics_csim4 proc~ice_thermo_columns ice_thermo_columns proc~ice_thermo_columns->proc~ice_column_step proc~ice_thermo_driver_step ice_thermo_driver_step proc~ice_thermo_driver_step->proc~ice_thermo_columns proc~engine_step_ice engine_step_ice proc~engine_step_ice->proc~ice_thermo_driver_step proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_step_ice proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step_ice

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private :: ai
real(kind=wp), private :: as
real(kind=wp), private :: fh
integer, private :: m
real(kind=wp), private :: melt_ramp
real(kind=wp), private :: opt_decay_lay
real(kind=wp), private :: snow_cover
real(kind=wp), private :: sw_frac_top
real(kind=wp), private :: temp_ice_freeze

Source Code

   pure subroutine ice_optics_csim4(nk, hs, hi, ts, sal_ice_top, &
                                    albedo, abs_sfc, abs_snow, abs_ice_lay, &
                                    abs_ocn, abs_int, pen)
      !! CSIM4 albedo + Beer's-law vertical SW partition
      !! (SIS_optics.F90:371-409). Exact port; inline literals
      !! `0.1235`/`0.075` (melt-albedo reductions) and `5.0`/`0.5`
      !! (thin-ice atan ramp) and `0.06` (thin-ice albedo floor) stay
      !! inline per SIS2 (SIS_optics.F90:378-384).
      !!
      !! Partition identity (up to ~1 `exp` round-off): `abs_sfc +
      !! abs_snow + sum(abs_ice_lay) + abs_ocn == 1`, because
      !! `opt_decay_lay**nk == exp(-hi/ICE_OPT_DEP_ICE)`.
      !$acc routine seq
      integer, intent(in) :: nk
         !! Number of ice layers (declared first — decl-order).
      real(wp), intent(in) :: hs
         !! Snow thickness (m).
      real(wp), intent(in) :: hi
         !! Ice thickness (m).
      real(wp), intent(in) :: ts
         !! Skin/surface temperature stand-in (degC).
      real(wp), intent(in) :: sal_ice_top
         !! Bulk salinity of the top ice layer (PSU) — sets the
         !! melt-onset freezing temperature.
      real(wp), intent(out) :: albedo
         !! Combined snow+ice broadband albedo (nondim).
      real(wp), intent(out) :: abs_sfc
         !! Fraction of absorbed SW deposited at the surface skin.
      real(wp), intent(out) :: abs_snow
         !! Fraction of absorbed SW deposited in the snow (always 0
         !! in the CSIM4 branch — SIS2 keeps the term for symmetry
         !! with the delta-Eddington branch).
      real(wp), intent(out) :: abs_ice_lay(nk)
         !! Fraction of absorbed SW deposited per ice layer, TOP-DOWN
         !! (`abs_ice_lay(1)` = top ice layer).
      real(wp), intent(out) :: abs_ocn
         !! Fraction of absorbed SW transmitted through to the ocean.
      real(wp), intent(out) :: abs_int
         !! Fraction of absorbed SW deposited in the ice interior
         !! (`pen - sw_frac_top` after the Beer's-law drain).
      real(wp), intent(out) :: pen
         !! Fraction of the total (post-albedo) SW that penetrates
         !! below the surface skin.

      real(wp) :: as, ai, snow_cover, temp_ice_freeze, fh, melt_ramp
      real(wp) :: opt_decay_lay, sw_frac_top
      integer :: m

      as = ICE_ALB_SNOW
      ai = ICE_ALB_ICE
      snow_cover = hs/(hs + ICE_SNOW_PATCH)
      temp_ice_freeze = ice_t_freeze(sal_ice_top)

      fh = min(atan(5.0_wp*hi)/atan(5.0_wp*0.5_wp), 1.0_wp)

      if (ts + ICE_T_RANGE_MELT > temp_ice_freeze) then
         ! Reduce albedo for melting, CSIM4 0.53/0.47 vis/ir split
         ! (SIS_optics.F90:378-384).
         melt_ramp = min((ts + ICE_T_RANGE_MELT - temp_ice_freeze)/ICE_T_RANGE_MELT, 1.0_wp)
         as = as - 0.1235_wp*melt_ramp
         ai = ai - 0.075_wp*melt_ramp
      end if
      ai = fh*ai + (1.0_wp - fh)*0.06_wp

      albedo = snow_cover*as + (1.0_wp - snow_cover)*ai

      pen = (1.0_wp - snow_cover)*ICE_PEN_ICE
      opt_decay_lay = exp(-hi/(real(nk, wp)*ICE_OPT_DEP_ICE))
      abs_ocn = pen*exp(-hi/ICE_OPT_DEP_ICE)
      abs_sfc = 1.0_wp - pen
      abs_snow = 0.0_wp

      sw_frac_top = pen
      do m = 1, nk
         abs_ice_lay(m) = sw_frac_top*(1.0_wp - opt_decay_lay)
         sw_frac_top = sw_frac_top*opt_decay_lay
      end do
      abs_int = pen - sw_frac_top
   end subroutine ice_optics_csim4