ice_thermo_columns Subroutine

public pure subroutine ice_thermo_columns(nghost, nx, ny, ncat, nk, dtt, do_snow_ice, wet_mask, m_ice, m_snow, enth_ice, enth_snow, sal_ice, sf_0, dsf_dt, sw_dn, fprec, tfw, fb, sst, s_surf, tsurf_out, h2o_ocn_to_ice, h2o_ice_to_ocn, heat_to_ocn, sw_thru, snow_to_ice)

do concurrent cell driver: PHYSICAL cells only, inner if gate (never a masked DC header), serial do cat loop inside. Per (i,j,cat): outputs zeroed unconditionally, then gated on wet_mask > 0.5 .and. m_ice > ICE_RHO_ICE*H_VANISHED (dynamic- vanish taxonomy: skip intact, never clamp/divide a vanished column). part_size is deliberately NOT an argument — thermo is per unit ice area.

Arguments

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

Grid + category + layer extents (declared first — decl-order).

integer, intent(in) :: nx

Grid + category + layer extents (declared first — decl-order).

integer, intent(in) :: ny

Grid + category + layer extents (declared first — decl-order).

integer, intent(in) :: ncat

Grid + category + layer extents (declared first — decl-order).

integer, intent(in) :: nk

Grid + category + layer extents (declared first — decl-order).

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

Timestep (s).

logical, intent(in) :: do_snow_ice

Archimedes freeboard flood gate (&ocean_ice_nml snow_ice, PR 27), captured by value into the DC loop (same treatment as dtt). .false. (the default) is a bit-identical no-op.

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

Ocean wet mask (>0.5 = wet).

real(kind=wp), intent(inout) :: m_ice(nx,ny,ncat)

Total ice mass per unit area per category (kg/m²).

real(kind=wp), intent(inout) :: m_snow(nx,ny,ncat)

Snow mass per unit area per category (kg/m²).

real(kind=wp), intent(inout) :: enth_ice(nx,ny,ncat,nk)

Ice specific enthalpy (J/kg), BOTTOM-UP (k=1 = ice bottom).

real(kind=wp), intent(inout) :: enth_snow(nx,ny,ncat,1)

Snow specific enthalpy (J/kg).

real(kind=wp), intent(inout) :: sal_ice(nx,ny,ncat,nk)

Ice bulk salinity (PSU), BOTTOM-UP.

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

Linearized SEB intercept (W/m²), upward-positive.

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

Linearized SEB slope (W/m²/K), upward-positive.

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

Downwelling shortwave at the surface (W/m²).

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

Frozen-precipitation rate onto the ice top (kg/m²/s), >= 0 — PR 26 snowfall seam (ice%atm_fprec). Passed to ice_column_step as fprec(i,j)*dtt; 0 (the &ocean_ice_nml snowfall=0 default) is a bit-identical no-op.

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

Seawater freezing temperature at the ice base (degC).

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

Ocean -> ice-base heat flux (W/m²).

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

Sea-surface temperature (degC).

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

Sea-surface salinity (PSU).

real(kind=wp), intent(inout) :: tsurf_out(nx,ny,ncat)

Surface skin temperature (degC).

real(kind=wp), intent(inout) :: h2o_ocn_to_ice(nx,ny,ncat)

Mass flux frozen from the ocean onto the ice base (kg/m²).

real(kind=wp), intent(inout) :: h2o_ice_to_ocn(nx,ny,ncat)

Meltwater mass flux to the ocean (kg/m²).

real(kind=wp), intent(inout) :: heat_to_ocn(nx,ny,ncat)

Leftover melt heat dumped to the ocean (J/m²).

real(kind=wp), intent(inout) :: sw_thru(nx,ny,ncat)

Shortwave transmitted through the ice to the ocean (W/m²).

real(kind=wp), intent(inout) :: snow_to_ice(nx,ny,ncat)

Mass converted from snow to the top ice layer this call (kg/m²), >= 0 — SIS2 SN2IC (PR 27). Zeroed unconditionally every thermo step, same lifecycle as sw_thru.


Calls

proc~~ice_thermo_columns~~CallsGraph proc~ice_thermo_columns ice_thermo_columns local local proc~ice_thermo_columns->local proc~ice_column_step ice_column_step proc~ice_thermo_columns->proc~ice_column_step proc~ice_bottom_freeze ice_bottom_freeze proc~ice_column_step->proc~ice_bottom_freeze proc~ice_bottom_melt_peel ice_bottom_melt_peel proc~ice_column_step->proc~ice_bottom_melt_peel proc~ice_enth_from_ts ice_enth_from_ts proc~ice_column_step->proc~ice_enth_from_ts proc~ice_enthalpy_liquid ice_enthalpy_liquid proc~ice_column_step->proc~ice_enthalpy_liquid proc~ice_optics_csim4 ice_optics_csim4 proc~ice_column_step->proc~ice_optics_csim4 proc~ice_rebalance_layers ice_rebalance_layers proc~ice_column_step->proc~ice_rebalance_layers proc~ice_snow_accumulate ice_snow_accumulate proc~ice_column_step->proc~ice_snow_accumulate proc~ice_snow_ice_flood ice_snow_ice_flood proc~ice_column_step->proc~ice_snow_ice_flood proc~ice_temp_from_en_s ice_temp_from_en_s proc~ice_column_step->proc~ice_temp_from_en_s proc~ice_temp_sis2 ice_temp_sis2 proc~ice_column_step->proc~ice_temp_sis2 proc~ice_top_melt_peel ice_top_melt_peel proc~ice_column_step->proc~ice_top_melt_peel proc~ice_enthalpy_liquid_freeze ice_enthalpy_liquid_freeze proc~ice_bottom_melt_peel->proc~ice_enthalpy_liquid_freeze proc~ice_t_freeze ice_t_freeze proc~ice_optics_csim4->proc~ice_t_freeze proc~ice_temp_sis2->proc~ice_enth_from_ts proc~ice_temp_sis2->proc~ice_temp_from_en_s proc~ice_temp_sis2->proc~ice_t_freeze proc~laytemp_sis2 laytemp_sis2 proc~ice_temp_sis2->proc~laytemp_sis2 proc~update_lay_enth update_lay_enth proc~ice_temp_sis2->proc~update_lay_enth proc~ice_top_melt_peel->proc~ice_enthalpy_liquid_freeze proc~update_lay_enth->proc~ice_enth_from_ts proc~update_lay_enth->proc~ice_enthalpy_liquid proc~update_lay_enth->proc~ice_enthalpy_liquid_freeze proc~update_lay_enth->proc~ice_t_freeze

Called by

proc~~ice_thermo_columns~~CalledByGraph proc~ice_thermo_columns ice_thermo_columns 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 proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean

Variables

Type Visibility Attributes Name Initial
integer, private :: cat
real(kind=wp), private :: enth_ice_col(ICE_NK_MAX)
real(kind=wp), private :: enth_snow_pt
real(kind=wp), private :: h2o_ice_to_ocn_pt
real(kind=wp), private :: h2o_ocn_to_ice_pt
real(kind=wp), private :: heat_to_ocn_pt
integer, private :: i
integer, private :: i_hi
integer, private :: i_lo
integer, private :: j
integer, private :: j_hi
integer, private :: j_lo
real(kind=wp), private :: m_ice_pt
real(kind=wp), private :: m_snow_pt
real(kind=wp), private :: sal_ice_col(ICE_NK_MAX)
real(kind=wp), private :: snow_to_ice_pt
real(kind=wp), private :: sw_thru_pt
real(kind=wp), private :: tsurf_pt

Source Code

   pure subroutine ice_thermo_columns(nghost, nx, ny, ncat, nk, dtt, do_snow_ice, wet_mask, &
                                      m_ice, m_snow, enth_ice, enth_snow, sal_ice, &
                                      sf_0, dsf_dt, sw_dn, fprec, tfw, fb, sst, s_surf, &
                                      tsurf_out, h2o_ocn_to_ice, h2o_ice_to_ocn, &
                                      heat_to_ocn, sw_thru, snow_to_ice)
      !! `do concurrent` cell driver: PHYSICAL cells only, inner `if`
      !! gate (never a masked DC header), serial `do cat` loop inside.
      !! Per (i,j,cat): outputs zeroed unconditionally, then gated on
      !! `wet_mask > 0.5 .and. m_ice > ICE_RHO_ICE*H_VANISHED` (dynamic-
      !! vanish taxonomy: skip intact, never clamp/divide a vanished
      !! column). `part_size` is deliberately NOT an argument — thermo
      !! is per unit ice area.
      integer, intent(in) :: nghost, nx, ny, ncat, nk
         !! Grid + category + layer extents (declared first — decl-order).
      real(wp), intent(in) :: dtt
         !! Timestep (s).
      logical, intent(in) :: do_snow_ice
         !! Archimedes freeboard flood gate (`&ocean_ice_nml snow_ice`,
         !! PR 27), captured by value into the DC loop (same treatment
         !! as `dtt`). `.false.` (the default) is a bit-identical no-op.
      real(wp), intent(in) :: wet_mask(nx, ny)
         !! Ocean wet mask (>0.5 = wet).
      real(wp), intent(inout) :: m_ice(nx, ny, ncat)
         !! Total ice mass per unit area per category (kg/m²).
      real(wp), intent(inout) :: m_snow(nx, ny, ncat)
         !! Snow mass per unit area per category (kg/m²).
      real(wp), intent(inout) :: enth_ice(nx, ny, ncat, nk)
         !! Ice specific enthalpy (J/kg), BOTTOM-UP (k=1 = ice bottom).
      real(wp), intent(inout) :: enth_snow(nx, ny, ncat, 1)
         !! Snow specific enthalpy (J/kg).
      real(wp), intent(inout) :: sal_ice(nx, ny, ncat, nk)
         !! Ice bulk salinity (PSU), BOTTOM-UP.
      real(wp), intent(in) :: sf_0(nx, ny)
         !! Linearized SEB intercept (W/m²), upward-positive.
      real(wp), intent(in) :: dsf_dt(nx, ny)
         !! Linearized SEB slope (W/m²/K), upward-positive.
      real(wp), intent(in) :: sw_dn(nx, ny)
         !! Downwelling shortwave at the surface (W/m²).
      real(wp), intent(in) :: fprec(nx, ny)
         !! Frozen-precipitation rate onto the ice top (kg/m²/s), >= 0 —
         !! PR 26 snowfall seam (`ice%atm_fprec`). Passed to
         !! `ice_column_step` as `fprec(i,j)*dtt`; 0 (the
         !! `&ocean_ice_nml snowfall=0` default) is a bit-identical no-op.
      real(wp), intent(in) :: tfw(nx, ny)
         !! Seawater freezing temperature at the ice base (degC).
      real(wp), intent(in) :: fb(nx, ny)
         !! Ocean -> ice-base heat flux (W/m²).
      real(wp), intent(in) :: sst(nx, ny)
         !! Sea-surface temperature (degC).
      real(wp), intent(in) :: s_surf(nx, ny)
         !! Sea-surface salinity (PSU).
      real(wp), intent(inout) :: tsurf_out(nx, ny, ncat)
         !! Surface skin temperature (degC).
      real(wp), intent(inout) :: h2o_ocn_to_ice(nx, ny, ncat)
         !! Mass flux frozen from the ocean onto the ice base (kg/m²).
      real(wp), intent(inout) :: h2o_ice_to_ocn(nx, ny, ncat)
         !! Meltwater mass flux to the ocean (kg/m²).
      real(wp), intent(inout) :: heat_to_ocn(nx, ny, ncat)
         !! Leftover melt heat dumped to the ocean (J/m²).
      real(wp), intent(inout) :: sw_thru(nx, ny, ncat)
         !! Shortwave transmitted through the ice to the ocean (W/m²).
      real(wp), intent(inout) :: snow_to_ice(nx, ny, ncat)
         !! Mass converted from snow to the top ice layer this call
         !! (kg/m²), >= 0 — SIS2 `SN2IC` (PR 27). Zeroed unconditionally
         !! every thermo step, same lifecycle as `sw_thru`.

      integer :: i, j, cat, i_lo, i_hi, j_lo, j_hi
      real(wp) :: m_snow_pt, m_ice_pt, enth_snow_pt
      real(wp) :: enth_ice_col(ICE_NK_MAX), sal_ice_col(ICE_NK_MAX)
      real(wp) :: tsurf_pt, h2o_ocn_to_ice_pt, h2o_ice_to_ocn_pt, heat_to_ocn_pt, sw_thru_pt
      real(wp) :: snow_to_ice_pt

      i_lo = nghost + 1
      i_hi = nx - nghost
      j_lo = nghost + 1
      j_hi = ny - nghost

      do concurrent(j=j_lo:j_hi, i=i_lo:i_hi) &
         local(cat, m_snow_pt, m_ice_pt, enth_snow_pt, enth_ice_col, sal_ice_col, &
               tsurf_pt, h2o_ocn_to_ice_pt, h2o_ice_to_ocn_pt, heat_to_ocn_pt, sw_thru_pt, &
               snow_to_ice_pt)
         do cat = 1, ncat
            tsurf_out(i, j, cat) = 0.0_wp
            h2o_ocn_to_ice(i, j, cat) = 0.0_wp
            h2o_ice_to_ocn(i, j, cat) = 0.0_wp
            heat_to_ocn(i, j, cat) = 0.0_wp
            sw_thru(i, j, cat) = 0.0_wp
            snow_to_ice(i, j, cat) = 0.0_wp

            if (wet_mask(i, j) > 0.5_wp .and. m_ice(i, j, cat) > ICE_RHO_ICE*H_VANISHED) then
               m_snow_pt = m_snow(i, j, cat)
               m_ice_pt = m_ice(i, j, cat)
               enth_snow_pt = enth_snow(i, j, cat, 1)
               enth_ice_col(1:nk) = enth_ice(i, j, cat, 1:nk)
               sal_ice_col(1:nk) = sal_ice(i, j, cat, 1:nk)

               call ice_column_step(nk, m_snow_pt, m_ice_pt, enth_snow_pt, &
                                    enth_ice_col(1:nk), sal_ice_col(1:nk), &
                                    sf_0(i, j), dsf_dt(i, j), sw_dn(i, j), &
                                    tfw(i, j), fb(i, j), sst(i, j), s_surf(i, j), dtt, &
                                    do_snow_ice, &
                                    fprec(i, j)*dtt, tsurf_pt, h2o_ocn_to_ice_pt, &
                                    h2o_ice_to_ocn_pt, heat_to_ocn_pt, sw_thru_pt, &
                                    snow_to_ice_pt)

               m_snow(i, j, cat) = m_snow_pt
               m_ice(i, j, cat) = m_ice_pt
               enth_snow(i, j, cat, 1) = enth_snow_pt
               enth_ice(i, j, cat, 1:nk) = enth_ice_col(1:nk)
               sal_ice(i, j, cat, 1:nk) = sal_ice_col(1:nk)
               tsurf_out(i, j, cat) = tsurf_pt
               h2o_ocn_to_ice(i, j, cat) = h2o_ocn_to_ice_pt
               h2o_ice_to_ocn(i, j, cat) = h2o_ice_to_ocn_pt
               heat_to_ocn(i, j, cat) = heat_to_ocn_pt
               sw_thru(i, j, cat) = sw_thru_pt
               snow_to_ice(i, j, cat) = snow_to_ice_pt
            end if
         end do
      end do
   end subroutine ice_thermo_columns