LCOV - code coverage report
Current view: top level - columnphysics - icepack_therm_vertical.F90 (source / functions) Coverage Total Hit
Test: 250117-002718:9f4b99afd9:4:base,io,travis,quick Lines: 74.51 % 910 678
Test Date: 2025-01-16 18:02:43 Functions: 100.00 % 8 8

            Line data    Source code
       1              : !=========================================================================
       2              : !
       3              : ! Update ice and snow internal temperatures and compute
       4              : ! thermodynamic growth rates and atmospheric fluxes.
       5              : !
       6              : ! NOTE: The thermodynamic calculation is split in two for load balancing.
       7              : !       First icepack_therm_vertical computes vertical growth rates and coupler
       8              : !       fluxes.  Then icepack_therm_itd does thermodynamic calculations not
       9              : !       needed for coupling.
      10              : !
      11              : ! authors: William H. Lipscomb, LANL
      12              : !          C. M. Bitz, UW
      13              : !          Elizabeth C. Hunke, LANL
      14              : !
      15              : ! 2003: Vectorized by Clifford Chen (Fujitsu) and William Lipscomb
      16              : ! 2004: Block structure added by William Lipscomb
      17              : ! 2006: Streamlined for efficiency by Elizabeth Hunke
      18              : !       Converted to free source form (F90)
      19              : 
      20              :       module icepack_therm_vertical
      21              : 
      22              :       use icepack_kinds
      23              : 
      24              :       use icepack_fsd, only: floe_rad_c, floe_binwidth
      25              : 
      26              :       use icepack_parameters, only: c0, c1, c2, p001, p5, puny
      27              :       use icepack_parameters, only: pi, depressT, Lvap, hs_min, cp_ice, min_salin
      28              :       use icepack_parameters, only: cp_ocn, rhow, rhoi, rhos, Lfresh, rhofresh, ice_ref_salinity
      29              :       use icepack_parameters, only: ktherm, calc_Tsfc, rsnw_fall, rsnw_tmax
      30              :       use icepack_parameters, only: ustar_min, fbot_xfer_type, formdrag, calc_strair
      31              :       use icepack_parameters, only: rfracmin, rfracmax, dpscale, frzpnd, snwgrain, snwlvlfac
      32              :       use icepack_parameters, only: phi_i_mushy, floeshape, floediam, use_smliq_pnd, snwredist
      33              :       use icepack_parameters, only: saltflux_option, congel_freeze
      34              :       use icepack_parameters, only: icepack_chkoptargflag
      35              : 
      36              :       use icepack_tracers, only: ncat, nilyr, nslyr, nfsd
      37              :       use icepack_tracers, only: tr_iage, tr_FY, tr_aero, tr_pond, tr_fsd, tr_iso
      38              :       use icepack_tracers, only: tr_pond_lvl, tr_pond_topo
      39              :       use icepack_tracers, only: n_aero, n_iso
      40              : 
      41              :       use icepack_therm_shared, only: ferrmax, l_brine
      42              :       use icepack_therm_shared, only: calculate_tin_from_qin, Tmin
      43              :       use icepack_therm_shared, only: adjust_enthalpy
      44              :       use icepack_therm_bl99,   only: temperature_changes
      45              :       use icepack_therm_mushy,  only: temperature_changes_salinity
      46              : 
      47              :       use icepack_warnings, only: warnstr, icepack_warnings_add
      48              :       use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted
      49              : 
      50              :       use icepack_mushy_physics, only: icepack_mushy_temperature_mush
      51              :       use icepack_mushy_physics, only: liquidus_temperature_mush
      52              :       use icepack_mushy_physics, only: icepack_enthalpy_mush, enthalpy_of_melting
      53              :       use icepack_mushy_physics, only: enthalpy_mush_liquid_fraction, enthalpy_brine
      54              : 
      55              :       use icepack_aerosol, only: update_aerosol
      56              :       use icepack_isotope, only: update_isotope
      57              :       use icepack_atmo, only: neutral_drag_coeffs, icepack_atm_boundary
      58              :       use icepack_age, only: increment_age
      59              :       use icepack_firstyear, only: update_FYarea
      60              :       use icepack_flux, only: set_sfcflux, merge_fluxes
      61              :       use icepack_meltpond_lvl, only: compute_ponds_lvl
      62              :       use icepack_meltpond_topo, only: compute_ponds_topo
      63              :       use icepack_snow, only: drain_snow
      64              : 
      65              :       implicit none
      66              : 
      67              :       private
      68              :       public :: icepack_step_therm1
      69              : 
      70              : !=======================================================================
      71              : 
      72              :       contains
      73              : 
      74              : !=======================================================================
      75              : !
      76              : ! Driver for updating ice and snow internal temperatures and
      77              : ! computing thermodynamic growth rates and atmospheric fluxes.
      78              : !
      79              : ! authors: William H. Lipscomb, LANL
      80              : !          C. M. Bitz, UW
      81              : 
      82      8777938 :       subroutine thermo_vertical (dt,          aicen,     &
      83              :                                   vicen,       vsnon,     &
      84            0 :                                   Tsf,         zSin,      &
      85      8777938 :                                   zqin,        zqsn,      &
      86              :                                   apond,       hpond,     &
      87              :                                   flw,         potT,      &
      88              :                                   Qa,          rhoa,      &
      89              :                                   fsnow,       fpond,     &
      90              :                                   fbot,        Tbot,      &
      91              :                                   Tsnice,      sss,       &
      92            0 :                                   sst,         rsnw,      &
      93              :                                   lhcoef,      shcoef,    &
      94              :                                   fswsfc,      fswint,    &
      95      8777938 :                                   Sswabs,      Iswabs,    &
      96              :                                   fsurfn,      fcondtopn, &
      97              :                                   fcondbotn,              &
      98              :                                   fsensn,      flatn,     &
      99              :                                   flwoutn,     evapn,     &
     100              :                                   evapsn,      evapin,    &
     101              :                                   freshn,      fsaltn,    &
     102              :                                   fhocnn,      frain,     &
     103              :                                   meltt,       melts,     &
     104              :                                   meltb,       meltsliq,  &
     105     17555876 :                                   smice,       massice,   &
     106     17555876 :                                   smliq,       massliq,   &
     107              :                                   congel,      snoice,    &
     108              :                                   mlt_onset,   frz_onset, &
     109              :                                   yday,        dsnow,     &
     110              :                                   prescribed_ice)
     111              : 
     112              :       real (kind=dbl_kind), intent(in) :: &
     113              :          dt      , & ! time step
     114              :          frain       ! rainfall rate (kg/m2/s)
     115              : 
     116              :       ! ice state variables
     117              :       real (kind=dbl_kind), intent(inout) :: &
     118              :          aicen   , & ! concentration of ice
     119              :          vicen   , & ! volume per unit area of ice          (m)
     120              :          vsnon       ! volume per unit area of snow         (m)
     121              : 
     122              :       ! tracers
     123              :       real (kind=dbl_kind), intent(inout) :: &
     124              :          Tsf     , & ! ice/snow top surface temp, same as Tsfcn (deg C)
     125              :          apond   , & ! melt pond area fraction of category
     126              :          hpond       ! melt pond depth (m)
     127              : !        iage        ! ice age (s)
     128              : 
     129              :       logical (kind=log_kind), intent(in), optional :: &
     130              :          prescribed_ice  ! if .true., use prescribed ice instead of computed
     131              : 
     132              :       real (kind=dbl_kind), dimension (:), intent(inout) :: &
     133              :          zqsn    , & ! snow layer enthalpy, zqsn < 0 (J m-3)
     134              :          zqin    , & ! ice layer enthalpy, zqin < 0 (J m-3)
     135              :          zSin    , & ! internal ice layer salinities
     136              :          rsnw    , & ! snow grain radius (10^-6 m)
     137              :          smice   , & ! ice mass tracer in snow (kg/m^3)
     138              :          smliq       ! liquid water mass tracer in snow (kg/m^3)
     139              : 
     140              :       real (kind=dbl_kind), dimension (:), intent(out) :: &
     141              :          massice , & ! ice mass in snow (kg/m^2)
     142              :          massliq     ! liquid water mass in snow (kg/m^2)
     143              : 
     144              :       ! input from atmosphere
     145              :       real (kind=dbl_kind), intent(in) :: &
     146              :          flw     , & ! incoming longwave radiation (W/m^2)
     147              :          potT    , & ! air potential temperature  (K)
     148              :          Qa      , & ! specific humidity (kg/kg)
     149              :          rhoa    , & ! air density (kg/m^3)
     150              :          fsnow   , & ! snowfall rate (kg m-2 s-1)
     151              :          shcoef  , & ! transfer coefficient for sensible heat
     152              :          lhcoef      ! transfer coefficient for latent heat
     153              : 
     154              :       real (kind=dbl_kind), intent(inout) :: &
     155              :          fswsfc  , & ! SW absorbed at ice/snow surface (W m-2)
     156              :          fswint  , & ! SW absorbed in ice interior, below surface (W m-2)
     157              :          fpond       ! fresh water flux to ponds (kg/m^2/s)
     158              : 
     159              :       real (kind=dbl_kind), dimension (:), intent(inout) :: &
     160              :          Sswabs  , & ! SW radiation absorbed in snow layers (W m-2)
     161              :          Iswabs      ! SW radiation absorbed in ice layers (W m-2)
     162              : 
     163              :       ! input from ocean
     164              :       real (kind=dbl_kind), intent(in) :: &
     165              :          fbot    , & ! ice-ocean heat flux at bottom surface (W/m^2)
     166              :          Tbot    , & ! ice bottom surface temperature (deg C)
     167              :          sst     , & ! sea surface temperature (C)
     168              :          sss         ! ocean salinity
     169              : 
     170              :       ! coupler fluxes to atmosphere
     171              :       real (kind=dbl_kind), intent(out):: &
     172              :          flwoutn , & ! outgoing longwave radiation (W/m^2)
     173              :          evapn   , & ! evaporative water flux (kg/m^2/s)
     174              :          evapsn  , & ! evaporative water flux over snow (kg/m^2/s)
     175              :          evapin      ! evaporative water flux over ice (kg/m^2/s)
     176              : 
     177              :       ! Note: these are intent out if calc_Tsfc = T, otherwise intent in
     178              :       real (kind=dbl_kind), intent(inout):: &
     179              :          fsensn   , & ! sensible heat flux (W/m^2)
     180              :          flatn    , & ! latent heat flux   (W/m^2)
     181              :          fsurfn   , & ! net flux to top surface, excluding fcondtopn
     182              :          fcondtopn, & ! downward cond flux at top surface (W m-2)
     183              :          fcondbotn    ! downward cond flux at bottom surface (W m-2)
     184              : 
     185              :       ! coupler fluxes to ocean
     186              :       real (kind=dbl_kind), intent(out):: &
     187              :          freshn  , & ! fresh water flux to ocean (kg/m^2/s)
     188              :          fsaltn  , & ! salt flux to ocean (kg/m^2/s)
     189              :          fhocnn      ! net heat flux to ocean (W/m^2)
     190              : 
     191              :       ! diagnostic fields
     192              :       real (kind=dbl_kind), intent(inout):: &
     193              :          Tsnice   , & ! snow ice interface temperature (deg C)
     194              :          meltt    , & ! top ice melt             (m/step-->cm/day)
     195              :          melts    , & ! snow melt                (m/step-->cm/day)
     196              :          meltsliq , & ! snow melt mass           (kg/m^2/step-->kg/m^2/day)
     197              :          meltb    , & ! basal ice melt           (m/step-->cm/day)
     198              :          congel   , & ! basal ice growth         (m/step-->cm/day)
     199              :          snoice   , & ! snow-ice formation       (m/step-->cm/day)
     200              :          dsnow    , & ! change in snow thickness (m/step-->cm/day)
     201              :          mlt_onset, & ! day of year that sfc melting begins
     202              :          frz_onset    ! day of year that freezing begins (congel or frazil)
     203              : 
     204              :       real (kind=dbl_kind), intent(in) :: &
     205              :          yday         ! day of year
     206              : 
     207              :       ! local variables
     208              : 
     209              :       integer (kind=int_kind) :: &
     210              :          k               ! ice layer index
     211              : 
     212              :       real (kind=dbl_kind) :: &
     213              :          dhi         , & ! change in ice thickness
     214              :          dhs             ! change in snow thickness
     215              : 
     216              : ! 2D state variables (thickness, temperature)
     217              : 
     218              :       real (kind=dbl_kind) :: &
     219              :          hilyr       , & ! ice layer thickness
     220              :          hslyr       , & ! snow layer thickness
     221              :          hin         , & ! ice thickness (m)
     222              :          hsn         , & ! snow thickness (m)
     223              :          hsn_new     , & ! thickness of new snow (m)
     224              :          worki       , & ! local work array
     225              :          works           ! local work array
     226              : 
     227              :       real (kind=dbl_kind), dimension (nilyr) :: &
     228      8777938 :          zTin            ! internal ice layer temperatures
     229              : 
     230              :       real (kind=dbl_kind), dimension (nslyr) :: &
     231      8777938 :          zTsn            ! internal snow layer temperatures
     232              : 
     233              : ! other 2D flux and energy variables
     234              : 
     235              :       real (kind=dbl_kind) :: &
     236              :          einit       , & ! initial energy of melting (J m-2)
     237              :          efinal      , & ! final energy of melting (J m-2)
     238              :          einter          ! intermediate energy
     239              : 
     240              :       real (kind=dbl_kind) :: &
     241              :          fadvocn, saltvol, dfsalt ! advective heat flux to ocean
     242              : 
     243              :       character(len=*),parameter :: subname='(thermo_vertical)'
     244              : 
     245              :       !-----------------------------------------------------------------
     246              :       ! Initialize
     247              :       !-----------------------------------------------------------------
     248              : 
     249      8777938 :       flwoutn = c0
     250      8777938 :       evapn   = c0
     251      8777938 :       evapsn  = c0
     252      8777938 :       evapin  = c0
     253      8777938 :       freshn  = c0
     254      8777938 :       fsaltn  = c0
     255      8777938 :       fhocnn  = c0
     256      8777938 :       fadvocn = c0
     257              : 
     258      8777938 :       meltt   = c0
     259      8777938 :       meltb   = c0
     260      8777938 :       melts   = c0
     261      8777938 :       congel  = c0
     262      8777938 :       snoice  = c0
     263      8777938 :       dsnow   = c0
     264     22512048 :       zTsn(:) = c0
     265     68489396 :       zTin(:) = c0
     266      8777938 :       meltsliq= c0
     267     22512048 :       massice(:) = c0
     268     22512048 :       massliq(:) = c0
     269              : 
     270      8777938 :       if (calc_Tsfc) then
     271      8777938 :          fsensn  = c0
     272      8777938 :          flatn     = c0
     273      8777938 :          fsurfn    = c0
     274      8777938 :          fcondtopn = c0
     275              :       endif
     276              : 
     277              :       !-----------------------------------------------------------------
     278              :       ! Compute variables needed for vertical thermo calculation
     279              :       !-----------------------------------------------------------------
     280              : 
     281              :       call init_vertical_profile (aicen,             &
     282              :                                   vicen,    vsnon,   &
     283              :                                   hin,      hilyr,   &
     284              :                                   hsn,      hslyr,   &
     285              :                                   zqin,     zTin,    &
     286              :                                   zqsn,     zTsn,    &
     287              :                                   zSin,              &
     288      8777938 :                                   einit )
     289      8777938 :       if (icepack_warnings_aborted(subname)) return
     290              : 
     291              :       ! Save initial ice and snow thickness (for fresh and fsalt)
     292      8777938 :       worki = hin
     293      8777938 :       works = hsn
     294              : 
     295              :       ! Save initial salt volume for prognostic flux
     296      8777938 :       if (saltflux_option == 'prognostic') then
     297       225452 :          saltvol = c0
     298      1803616 :          do k=1,nilyr
     299      1803616 :             saltvol = saltvol + rhoi*zSin(k)*hin*p001 / real(nilyr,kind=dbl_kind)
     300              :          enddo
     301              :       endif
     302              : 
     303              :       !-----------------------------------------------------------------
     304              :       ! Compute new surface temperature and internal ice and snow
     305              :       !  temperatures.
     306              :       !-----------------------------------------------------------------
     307              : 
     308      8777938 :          if (ktherm == 2) then
     309              : 
     310              :             call temperature_changes_salinity(dt,                   &
     311              :                                               rhoa,      flw,       &
     312              :                                               potT,      Qa,        &
     313              :                                               shcoef,    lhcoef,    &
     314              :                                               fswsfc,    fswint,    &
     315              :                                               Sswabs,    Iswabs,    &
     316              :                                               hilyr,     hslyr,     &
     317              :                                               apond,     hpond,     &
     318              :                                               zqin,      zTin,      &
     319              :                                               zqsn,      zTsn,      &
     320              :                                               zSin,                 &
     321              :                                               Tsf,       Tbot,      &
     322              :                                               sss,                  &
     323              :                                               fsensn,    flatn,     &
     324              :                                               flwoutn,   fsurfn,    &
     325              :                                               fcondtopn, fcondbotn, &
     326              :                                               fadvocn,   snoice,    &
     327      7258715 :                                               smice,     smliq)
     328      7258715 :             if (icepack_warnings_aborted(subname)) return
     329              : 
     330              :          else ! ktherm
     331              : 
     332              :             call temperature_changes(dt,                   &
     333              :                                      rhoa,      flw,       &
     334              :                                      potT,      Qa,        &
     335              :                                      shcoef,    lhcoef,    &
     336              :                                      fswsfc,    fswint,    &
     337              :                                      Sswabs,    Iswabs,    &
     338              :                                      hilyr,     hslyr,     &
     339              :                                      zqin,      zTin,      &
     340              :                                      zqsn,      zTsn,      &
     341              :                                      zSin,                 &
     342              :                                      Tsf,       Tbot,      &
     343              :                                      fsensn,    flatn,     &
     344              :                                      flwoutn,   fsurfn,    &
     345              :                                      fcondtopn, fcondbotn,  &
     346      1519223 :                                      einit                 )
     347      1519223 :             if (icepack_warnings_aborted(subname)) return
     348              : 
     349              :          endif ! ktherm
     350              : 
     351              :          !  mass of ice and liquid water in snow
     352      8777938 :          if (snwgrain) then
     353      5311734 :             massice(:) = smice(:) * hslyr
     354      5311734 :             massliq(:) = smliq(:) * hslyr
     355              :          endif
     356              : 
     357              :       ! intermediate energy for error check
     358              : 
     359      8777938 :       einter = c0
     360     22512048 :       do k = 1, nslyr
     361     22512048 :          einter = einter + hslyr * zqsn(k)
     362              :       enddo ! k
     363     68489396 :       do k = 1, nilyr
     364     68489396 :          einter = einter + hilyr * zqin(k)
     365              :       enddo ! k
     366              : 
     367      8777938 :       Tsnice = c0
     368      8777938 :       if ((hslyr+hilyr) > puny) then
     369      8777938 :          if (hslyr > puny) then
     370      8219042 :             Tsnice = (hslyr*zTsn(nslyr) + hilyr*zTin(1)) / (hslyr+hilyr)
     371              :          else
     372       558896 :             Tsnice = Tsf
     373              :          endif
     374              :       endif
     375              : 
     376      8777938 :       if (icepack_warnings_aborted(subname)) return
     377              : 
     378              :       !-----------------------------------------------------------------
     379              :       ! Compute growth and/or melting at the top and bottom surfaces.
     380              :       ! Add new snowfall.
     381              :       ! Repartition ice into equal-thickness layers, conserving energy.
     382              :       !-----------------------------------------------------------------
     383              : 
     384              :       call thickness_changes(dt,          yday,      &
     385              :                              efinal,                 &
     386              :                              hin,         hilyr,     &
     387              :                              hsn,         hslyr,     &
     388              :                              zqin,        zqsn,      &
     389              :                              smice,       massice,   &
     390              :                              smliq,       massliq,   &
     391              :                              fbot,        Tbot,      &
     392              :                              flatn,       fsurfn,    &
     393              :                              fcondtopn,   fcondbotn, &
     394              :                              fsnow,       hsn_new,   &
     395              :                              fhocnn,      evapn,     &
     396              :                              evapsn,      evapin,    &
     397              :                              meltt,       melts,     &
     398              :                              meltsliq,    frain,     &
     399              :                              meltb,                  &
     400              :                              congel,      snoice,    &
     401              :                              mlt_onset,   frz_onset, &
     402              :                              zSin,        sss,       &
     403              :                              sst,                    &
     404      8777938 :                              dsnow,       rsnw)
     405      8777938 :       if (icepack_warnings_aborted(subname)) return
     406              : 
     407              :       !-----------------------------------------------------------------
     408              :       ! Check for energy conservation by comparing the change in energy
     409              :       ! to the net energy input
     410              :       !-----------------------------------------------------------------
     411              : 
     412              :       call conservation_check_vthermo(dt,                  &
     413              :                                       fsurfn,    flatn,    &
     414              :                                       fhocnn,    fswint,   &
     415              :                                       fsnow,     einit,    &
     416              :                                       einter,    efinal,   &
     417              :                                       fcondtopn, fcondbotn, &
     418      8777938 :                                       fadvocn,   fbot      )
     419      8777938 :       if (icepack_warnings_aborted(subname)) return
     420              : 
     421              :       !-----------------------------------------------------------------
     422              :       ! If prescribed ice, set hi back to old values
     423              :       !-----------------------------------------------------------------
     424              : 
     425      8777938 :       if (present(prescribed_ice)) then
     426      8777938 :           if (prescribed_ice) then
     427            0 :             hin    = worki
     428            0 :             fhocnn = c0             ! for diagnostics
     429              :           endif
     430              :       endif
     431              : 
     432              :       !-----------------------------------------------------------------
     433              :       ! Compute fluxes of water and salt from ice to ocean.
     434              :       ! evapn < 0 => sublimation, evapn > 0 => condensation
     435              :       ! aerosol flux is accounted for in icepack_aerosol.F90
     436              :       !-----------------------------------------------------------------
     437              : 
     438      8777938 :       dhi = hin - worki
     439      8777938 :       dhs = hsn - works - hsn_new
     440              : 
     441      8777938 :       freshn = freshn + evapn - (rhoi*dhi + rhos*dhs) / dt
     442      8777938 :       if (saltflux_option == 'prognostic') then
     443       225452 :          dfsalt = c0
     444      1803616 :          do k=1,nilyr
     445      1803616 :             dfsalt = dfsalt + rhoi*zSin(k)*hin*p001 / real(nilyr,kind=dbl_kind)
     446              :          enddo
     447       225452 :          fsaltn = fsaltn - (dfsalt - saltvol) / dt
     448              :       else
     449      8552486 :          fsaltn = fsaltn - rhoi*dhi*ice_ref_salinity*p001/dt
     450              :       endif
     451      8777938 :       fhocnn = fhocnn + fadvocn ! for ktherm=2
     452              : 
     453      8777938 :       if (hin == c0) then
     454            4 :          if (tr_pond_topo) fpond = fpond - aicen * apond * hpond
     455              :       endif
     456              : 
     457              :       !-----------------------------------------------------------------
     458              :       !  Given the vertical thermo state variables, compute the new ice
     459              :       !   state variables.
     460              :       !-----------------------------------------------------------------
     461              : 
     462              :       call update_state_vthermo(Tbot,    Tsf,     &
     463              :                                 hin,     hsn,     &
     464              :                                 zqin,    zSin,    &
     465              :                                 zqsn,             &
     466              :                                 aicen,            &
     467      8777938 :                                 vicen,   vsnon)
     468      8777938 :       if (icepack_warnings_aborted(subname)) return
     469              : 
     470              :     end subroutine thermo_vertical
     471              : 
     472              : !=======================================================================
     473              : !
     474              : ! Compute heat flux to bottom surface.
     475              : ! Compute fraction of ice that melts laterally.
     476              : !
     477              : ! authors C. M. Bitz, UW
     478              : !         William H. Lipscomb, LANL
     479              : !         Elizabeth C. Hunke, LANL
     480              : 
     481      2629488 :       subroutine frzmlt_bottom_lateral (dt,                 &
     482              :                                         aice,     frzmlt,   &
     483            0 :                                         vicen,    vsnon,    &
     484      5258976 :                                         qicen,    qsnon,    &
     485              :                                         sst,      Tf,       &
     486              :                                         ustar_min,          &
     487              :                                         fbot_xfer_type,     &
     488              :                                         strocnxT, strocnyT, &
     489              :                                         Tbot,     fbot,     &
     490      2629488 :                                         rsiden,    Cdn_ocn,  &
     491      2629488 :                                         wlat,      aicen, &
     492      2629488 :                                         afsdn)
     493              : 
     494              :       real (kind=dbl_kind), intent(in) :: &
     495              :          dt                  ! time step
     496              : 
     497              :       real (kind=dbl_kind), intent(in) :: &
     498              :          aice    , & ! ice concentration
     499              :          frzmlt  , & ! freezing/melting potential (W/m^2)
     500              :          sst     , & ! sea surface temperature (C)
     501              :          Tf      , & ! freezing temperature (C)
     502              :          ustar_min,& ! minimum friction velocity for ice-ocean heat flux
     503              :          Cdn_ocn , & ! ocean-ice neutral drag coefficient
     504              :          strocnxT, & ! ice-ocean stress, x-direction
     505              :          strocnyT    ! ice-ocean stress, y-direction
     506              : 
     507              :       character (char_len), intent(in) :: &
     508              :          fbot_xfer_type  ! transfer coefficient type for ice-ocean heat flux
     509              : 
     510              :       real (kind=dbl_kind), dimension(:), intent(in) :: &
     511              :          vicen   , & ! ice volume (m)
     512              :          vsnon       ! snow volume (m)
     513              : 
     514              :       real (kind=dbl_kind), dimension(:,:), intent(in) :: &
     515              :          qicen   , & ! ice layer enthalpy (J m-3)
     516              :          qsnon       ! snow layer enthalpy (J m-3)
     517              : 
     518              :       real (kind=dbl_kind), intent(out) :: &
     519              :          Tbot    , & ! ice bottom surface temperature (deg C)
     520              :          fbot        ! heat flux to ice bottom  (W/m^2)
     521              : 
     522              :       real (kind=dbl_kind), dimension(:), intent(out) :: &
     523              :          rsiden      ! fraction of ice that melts laterally
     524              : 
     525              :       real (kind=dbl_kind), intent(out), optional :: &
     526              :          wlat        ! lateral melt rate (m/s)
     527              : 
     528              :       real (kind=dbl_kind), dimension(:), intent(in) :: &
     529              :          aicen     ! ice concentration
     530              : 
     531              :       real (kind=dbl_kind), dimension (:,:), intent(in), optional :: &
     532              :          afsdn     ! area floe size distribution
     533              : 
     534              :       ! local variables
     535              :       real (kind=dbl_kind), dimension (ncat) :: &
     536      2629488 :          delta_an  , & ! change in the ITD
     537      2629488 :          G_radialn     ! lateral melt rate in FSD (m/s)
     538              : 
     539              :       real (kind=dbl_kind) :: &
     540              :          rside     , & !
     541              :          fside       ! lateral heat flux (W/m^2)
     542              : 
     543              :       integer (kind=int_kind) :: &
     544              :          n              , & ! thickness category index
     545              :          k                  ! layer index
     546              : 
     547              :       real (kind=dbl_kind) :: &
     548              :          etot    , & ! total energy in column
     549              :          wlat_loc, & ! lateral melt rate (m/s)
     550              :          qavg        ! average enthalpy in column (approximate)
     551              : 
     552              :       real (kind=dbl_kind) :: &
     553              :          deltaT    , & ! SST - Tbot >= 0
     554              :          ustar     , & ! skin friction velocity for fbot (m/s)
     555              :          bin1_arealoss, &
     556              :          xtmp          ! temporary variable
     557              : 
     558              :       ! Parameters for bottom melting
     559              : 
     560              :       real (kind=dbl_kind) :: &
     561              :          cpchr         ! -cp_ocn*rhow*exchange coefficient
     562              : 
     563              :       ! Parameters for lateral melting
     564              : 
     565              :       real (kind=dbl_kind), parameter :: &
     566              :          m1 = 1.6e-6_dbl_kind     , & ! constant from Maykut & Perovich
     567              :                                       ! (m/s/deg^(-m2))
     568              :          m2 = 1.36_dbl_kind           ! constant from Maykut & Perovich
     569              :                                       ! (unitless)
     570              : 
     571              :       character(len=*),parameter :: subname='(frzmlt_bottom_lateral)'
     572              : 
     573              :       !-----------------------------------------------------------------
     574              :       ! Identify grid cells where ice can melt.
     575              :       !-----------------------------------------------------------------
     576              : 
     577     15390816 :       rsiden(:) = c0
     578      2629488 :       Tbot  = Tf
     579      2629488 :       fbot  = c0
     580      2629488 :       wlat_loc = c0
     581      2629488 :       if (present(wlat)) wlat=c0
     582              : 
     583      2629488 :       if (aice > puny .and. frzmlt < c0) then ! ice can melt
     584              : 
     585              :       !-----------------------------------------------------------------
     586              :       ! Use boundary layer theory for fbot.
     587              :       ! See Maykut and McPhee (1995): JGR, 100, 24,691-24,703.
     588              :       !-----------------------------------------------------------------
     589              : 
     590      1232072 :          deltaT = max((sst-Tbot),c0)
     591              : 
     592              :          ! strocnx has units N/m^2 so strocnx/rho has units m^2/s^2
     593      1232072 :          ustar = sqrt (sqrt(strocnxT**2+strocnyT**2)/rhow)
     594      1232072 :          ustar = max (ustar,ustar_min)
     595              : 
     596      1232072 :          if (trim(fbot_xfer_type) == 'Cdn_ocn') then
     597              :             ! Note: Cdn_ocn has already been used for calculating ustar
     598              :             ! (formdrag only) --- David Schroeder (CPOM)
     599            0 :             cpchr = -cp_ocn*rhow*Cdn_ocn
     600              :          else ! fbot_xfer_type == 'constant'
     601              :             ! 0.006 = unitless param for basal heat flx ala McPhee and Maykut
     602      1232072 :             cpchr = -cp_ocn*rhow*0.006_dbl_kind
     603              :          endif
     604              : 
     605      1232072 :          fbot = cpchr * deltaT * ustar ! < 0
     606      1232072 :          fbot = max (fbot, frzmlt) ! frzmlt < fbot < 0
     607              : 
     608              : !!! uncomment to use all frzmlt for standalone runs
     609              :    !     fbot = min (c0, frzmlt)
     610              : 
     611              :       !-----------------------------------------------------------------
     612              :       ! Compute rside.  See these references:
     613              :       !    Maykut and Perovich (1987): JGR, 92, 7032-7044
     614              :       !    Steele (1992): JGR, 97, 17,729-17,738
     615              :       !-----------------------------------------------------------------
     616              : 
     617      1232072 :          wlat_loc = m1 * deltaT**m2 ! Maykut & Perovich
     618      1232072 :          rside = wlat_loc*dt*pi/(floeshape*floediam) ! Steele
     619      1232072 :          rside = max(c0,min(rside,c1))
     620              : 
     621      1232072 :          if (rside == c0) return ! nothing more to do so get out
     622              : 
     623      7390024 :          rsiden(:) = rside
     624              : 
     625      1232072 :          if (tr_fsd) then ! alter rsiden now since floes are not of size floediam
     626              : 
     627       363060 :             do n = 1, ncat
     628       302550 :                G_radialn(n) = -wlat_loc ! negative
     629              : 
     630              :                ! afsdn present check up the calling tree
     631      2941940 :                if (any(afsdn(:,n) < c0)) then
     632            0 :                   write(warnstr,*) subname, 'lateral_melt B afsd < 0 ',n
     633            0 :                   call icepack_warnings_add(warnstr)
     634              :                endif
     635              : 
     636       302550 :                bin1_arealoss = -afsdn(1,n)  / floe_binwidth(1) ! when scaled by *G_radialn(n)*dt*aicen(n)
     637              : 
     638       302550 :                delta_an(n) = c0
     639      2941940 :                do k = 1, nfsd
     640              :                   ! this is delta_an(n) when scaled by *G_radialn(n)*dt*aicen(n)
     641      2941940 :                   delta_an(n) = delta_an(n) + ((c2/floe_rad_c(k)) * afsdn(k,n)) ! delta_an < 0
     642              :                end do
     643              : 
     644              :                ! add negative area loss from fsd
     645       302550 :                delta_an(n) = (delta_an(n) - bin1_arealoss)*G_radialn(n)*dt
     646              : 
     647       302550 :                if (delta_an(n) > c0) then
     648            0 :                   write(warnstr,*) subname, 'ERROR delta_an > 0 ',delta_an(n)
     649            0 :                   call icepack_warnings_add(warnstr)
     650              :                endif
     651              : 
     652              :                ! following original code, not necessary for fsd
     653       302550 :                if (aicen(n) > c0) rsiden(n) = MIN(-delta_an(n),c1)
     654              : 
     655       363060 :                if (rsiden(n) < c0) then
     656            0 :                   write(warnstr,*) subname, 'ERROR rsiden < 0 ',rsiden(n)
     657            0 :                   call icepack_warnings_add(warnstr)
     658              :                endif
     659              :             enddo ! ncat
     660              : 
     661              :          endif ! if tr_fsd
     662              : 
     663              :       !-----------------------------------------------------------------
     664              :       ! Compute heat flux associated with this value of rside.
     665              :       !-----------------------------------------------------------------
     666      1232072 :          fside = c0
     667      7390024 :          do n = 1, ncat
     668              : 
     669      6157952 :             etot = c0
     670              :             ! melting energy/unit area in each column, etot < 0
     671              : 
     672     16990104 :             do k = 1, nslyr
     673     16990104 :                etot = etot + qsnon(k,n) * vsnon(n)/real(nslyr,kind=dbl_kind)
     674              :             enddo
     675              : 
     676     47842864 :             do k = 1, nilyr
     677     47842864 :                etot = etot + qicen(k,n) * vicen(n)/real(nilyr,kind=dbl_kind)
     678              :             enddo                  ! nilyr
     679              : 
     680              :             ! lateral heat flux, fside < 0
     681      7390024 :             fside = fside + rsiden(n)*etot/dt
     682              : 
     683              :          enddo                     ! n
     684              : 
     685              :       !-----------------------------------------------------------------
     686              :       ! Limit bottom and lateral heat fluxes if necessary.
     687              :       ! Limit rside so we don't melt laterally more ice than frzmlt permits
     688              :       !-----------------------------------------------------------------
     689              : 
     690      1232072 :          xtmp = frzmlt/(fbot + fside - puny)
     691      1232072 :          xtmp = min(xtmp, c1)
     692      1232072 :          xtmp = max(xtmp, c0)
     693      1232072 :          fbot  = fbot  * xtmp
     694              : 
     695      7390024 :          do n = 1, ncat
     696      7390024 :             rsiden(n) = rsiden(n) * xtmp  ! xtmp is almost always 1 so usually nothing happens here
     697              :          enddo ! ncat
     698              : 
     699              :       endif
     700              : 
     701      2629488 :       if (present(wlat)) wlat=wlat_loc
     702              : 
     703              :       end subroutine frzmlt_bottom_lateral
     704              : 
     705              : !=======================================================================
     706              : !
     707              : ! Given the state variables (vicen, vsnon, zqin, etc.),
     708              : ! compute variables needed for the vertical thermodynamics
     709              : ! (hin, hsn, zTin, etc.)
     710              : !
     711              : ! authors William H. Lipscomb, LANL
     712              : !         C. M. Bitz, UW
     713              : 
     714      8777938 :       subroutine init_vertical_profile(aicen,    vicen,    &
     715              :                                        vsnon,              &
     716              :                                        hin,      hilyr,    &
     717              :                                        hsn,      hslyr,    &
     718      8777938 :                                        zqin,     zTin,     &
     719      8777938 :                                        zqsn,     zTsn,     &
     720      8777938 :                                        zSin,               &
     721              :                                        einit )
     722              : 
     723              :       real (kind=dbl_kind), intent(in) :: &
     724              :          aicen , & ! concentration of ice
     725              :          vicen , & ! volume per unit area of ice          (m)
     726              :          vsnon     ! volume per unit area of snow         (m)
     727              : 
     728              :       real (kind=dbl_kind), intent(out):: &
     729              :          hilyr       , & ! ice layer thickness
     730              :          hslyr       , & ! snow layer thickness
     731              :          einit           ! initial energy of melting (J m-2)
     732              : 
     733              :       real (kind=dbl_kind), intent(out):: &
     734              :          hin         , & ! ice thickness (m)
     735              :          hsn             ! snow thickness (m)
     736              : 
     737              :       real (kind=dbl_kind), dimension (:), intent(inout) :: &
     738              :          zqin        , & ! ice layer enthalpy (J m-3)
     739              :          zTin            ! internal ice layer temperatures
     740              : 
     741              :       real (kind=dbl_kind), dimension (:), intent(in) :: &
     742              :          zSin            ! internal ice layer salinities
     743              : 
     744              :       real (kind=dbl_kind), dimension (:), intent(inout) :: &
     745              :          zqsn        , & ! snow enthalpy
     746              :          zTsn            ! snow temperature
     747              : 
     748              :       ! local variables
     749              :       real (kind=dbl_kind), dimension(nilyr) :: &
     750      8777938 :          Tmlts           ! melting temperature
     751              : 
     752              :       integer (kind=int_kind) :: &
     753              :          k               ! ice layer index
     754              : 
     755              :       real (kind=dbl_kind) :: &
     756              :          rnslyr,       & ! real(nslyr)
     757              :          Tmax            ! maximum allowed snow/ice temperature (deg C)
     758              : 
     759              :       logical (kind=log_kind) :: &   ! for vector-friendly error checks
     760              :          tsno_high   , & ! flag for zTsn > Tmax
     761              :          tice_high   , & ! flag for zTin > Tmlt
     762              :          tsno_low    , & ! flag for zTsn < Tmin
     763              :          tice_low        ! flag for zTin < Tmin
     764              : 
     765              :       character(len=*),parameter :: subname='(init_vertical_profile)'
     766              : 
     767              :       !-----------------------------------------------------------------
     768              :       ! Initialize
     769              :       !-----------------------------------------------------------------
     770              : 
     771      8777938 :       rnslyr = real(nslyr,kind=dbl_kind)
     772              : 
     773      8777938 :       tsno_high = .false.
     774      8777938 :       tice_high = .false.
     775      8777938 :       tsno_low  = .false.
     776      8777938 :       tice_low  = .false.
     777              : 
     778      8777938 :       einit = c0
     779              : 
     780              :       !-----------------------------------------------------------------
     781              :       ! Surface temperature, ice and snow thickness
     782              :       ! Initialize internal energy
     783              :       !-----------------------------------------------------------------
     784              : 
     785      8777938 :       hin    = vicen / aicen
     786      8777938 :       hsn    = vsnon / aicen
     787      8777938 :       hilyr    = hin / real(nilyr,kind=dbl_kind)
     788      8777938 :       hslyr    = hsn / rnslyr
     789              : 
     790              :       !-----------------------------------------------------------------
     791              :       ! Snow enthalpy and maximum allowed snow temperature
     792              :       !-----------------------------------------------------------------
     793              : 
     794     22512048 :       do k = 1, nslyr
     795              : 
     796              :       !-----------------------------------------------------------------
     797              :       ! Tmax based on the idea that dT ~ dq / (rhos*cp_ice)
     798              :       !                             dq ~ q dv / v
     799              :       !                             dv ~ puny = eps11
     800              :       ! where 'd' denotes an error due to roundoff.
     801              :       !-----------------------------------------------------------------
     802              : 
     803     13734110 :          if (hslyr > hs_min/rnslyr) then
     804              :             ! zqsn < 0
     805              :             Tmax = -zqsn(k)*puny*rnslyr / &
     806     10188405 :                  (rhos*cp_ice*vsnon)
     807              :          else
     808      3545705 :             zqsn  (k) = -rhos * Lfresh
     809      3545705 :             Tmax = puny
     810              :          endif
     811              : 
     812              :       !-----------------------------------------------------------------
     813              :       ! Compute snow temperatures from enthalpies.
     814              :       ! Note: zqsn <= -rhos*Lfresh, so zTsn <= 0.
     815              :       !-----------------------------------------------------------------
     816     13734110 :          zTsn(k) = (Lfresh + zqsn(k)/rhos)/cp_ice
     817              : 
     818              :       !-----------------------------------------------------------------
     819              :       ! Check for zTsn > Tmax (allowing for roundoff error) and zTsn < Tmin.
     820              :       !-----------------------------------------------------------------
     821     22512048 :          if (zTsn(k) > Tmax) then
     822            0 :             tsno_high = .true.
     823     13734110 :          elseif (zTsn(k) < Tmin) then
     824            0 :             tsno_low  = .true.
     825              :          endif
     826              : 
     827              :       enddo                     ! nslyr
     828              : 
     829              :       !-----------------------------------------------------------------
     830              :       ! If zTsn is out of bounds, print diagnostics and exit.
     831              :       !-----------------------------------------------------------------
     832              : 
     833      8777938 :       if (tsno_high) then
     834            0 :          do k = 1, nslyr
     835              : 
     836            0 :             if (hslyr > hs_min/rnslyr) then
     837              :                Tmax = -zqsn(k)*puny*rnslyr / &
     838            0 :                     (rhos*cp_ice*vsnon)
     839              :             else
     840            0 :                Tmax = puny
     841              :             endif
     842              : 
     843            0 :             if (zTsn(k) > Tmax) then
     844            0 :                write(warnstr,*) ' '
     845            0 :                call icepack_warnings_add(warnstr)
     846            0 :                write(warnstr,*) subname, 'Starting thermo, zTsn > Tmax'
     847            0 :                call icepack_warnings_add(warnstr)
     848            0 :                write(warnstr,*) subname, 'zTsn=',zTsn(k)
     849            0 :                call icepack_warnings_add(warnstr)
     850            0 :                write(warnstr,*) subname, 'Tmax=',Tmax
     851            0 :                call icepack_warnings_add(warnstr)
     852            0 :                write(warnstr,*) subname, 'zqsn',zqsn(k),-Lfresh*rhos,zqsn(k)+Lfresh*rhos
     853            0 :                call icepack_warnings_add(warnstr)
     854            0 :                call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
     855            0 :                call icepack_warnings_add(subname//" init_vertical_profile: Starting thermo, zTsn > Tmax" )
     856            0 :                return
     857              :             endif
     858              : 
     859              :          enddo                  ! nslyr
     860              :       endif                     ! tsno_high
     861              : 
     862      8777938 :       if (tsno_low) then
     863            0 :          do k = 1, nslyr
     864              : 
     865            0 :             if (zTsn(k) < Tmin) then ! allowing for roundoff error
     866            0 :                write(warnstr,*) ' '
     867            0 :                call icepack_warnings_add(warnstr)
     868            0 :                write(warnstr,*) subname, 'Starting thermo, zTsn < Tmin'
     869            0 :                call icepack_warnings_add(warnstr)
     870            0 :                write(warnstr,*) subname, 'zTsn=', zTsn(k)
     871            0 :                call icepack_warnings_add(warnstr)
     872            0 :                write(warnstr,*) subname, 'Tmin=', Tmin
     873            0 :                call icepack_warnings_add(warnstr)
     874            0 :                write(warnstr,*) subname, 'zqsn', zqsn(k)
     875            0 :                call icepack_warnings_add(warnstr)
     876            0 :                write(warnstr,*) subname, hin
     877            0 :                call icepack_warnings_add(warnstr)
     878            0 :                write(warnstr,*) subname, hsn
     879            0 :                call icepack_warnings_add(warnstr)
     880            0 :                call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
     881            0 :                call icepack_warnings_add(subname//" init_vertical_profile: Starting thermo, zTsn < Tmin" )
     882            0 :                return
     883              :             endif
     884              : 
     885              :          enddo                  ! nslyr
     886              :       endif                     ! tsno_low
     887              : 
     888     22512048 :       do k = 1, nslyr
     889              : 
     890     13734110 :          if (zTsn(k) > c0) then   ! correct roundoff error
     891        30304 :             zTsn(k) = c0
     892        30304 :             zqsn(k) = -rhos*Lfresh
     893              :          endif
     894              : 
     895              :       !-----------------------------------------------------------------
     896              :       ! initial energy per unit area of ice/snow, relative to 0 C
     897              :       !-----------------------------------------------------------------
     898     22512048 :          einit = einit + hslyr*zqsn(k)
     899              : 
     900              :       enddo                     ! nslyr
     901              : 
     902     68489396 :       do k = 1, nilyr
     903              : 
     904              :       !---------------------------------------------------------------------
     905              :       !  Use initial salinity profile for thin ice
     906              :       !---------------------------------------------------------------------
     907              : 
     908     59711458 :          if (ktherm == 1 .and. zSin(k) < min_salin-puny) then
     909            0 :             write(warnstr,*) ' '
     910            0 :             call icepack_warnings_add(warnstr)
     911            0 :             write(warnstr,*) subname, 'Starting zSin < min_salin, layer', k
     912            0 :             call icepack_warnings_add(warnstr)
     913            0 :             write(warnstr,*) subname, 'zSin =', zSin(k)
     914            0 :             call icepack_warnings_add(warnstr)
     915            0 :             write(warnstr,*) subname, 'min_salin =', min_salin
     916            0 :             call icepack_warnings_add(warnstr)
     917            0 :             call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
     918            0 :             call icepack_warnings_add(subname//" init_vertical_profile: Starting zSin < min_salin, layer" )
     919            0 :             return
     920              :          endif
     921              : 
     922     59711458 :          if (ktherm == 2) then
     923     50811005 :             Tmlts(k) = liquidus_temperature_mush(zSin(k))
     924              :          else
     925      8900453 :             Tmlts(k) = -zSin(k) * depressT
     926              :          endif
     927              : 
     928              :       !-----------------------------------------------------------------
     929              :       ! Compute ice temperatures from enthalpies using quadratic formula
     930              :       !-----------------------------------------------------------------
     931              : 
     932     59711458 :          if (ktherm == 2) then
     933     50811005 :             zTin(k) = icepack_mushy_temperature_mush(zqin(k),zSin(k))
     934              :          else
     935      8900453 :             zTin(k) = calculate_Tin_from_qin(zqin(k),Tmlts(k))
     936              :          endif
     937              : 
     938     59711458 :          if (l_brine) then
     939     59711458 :             Tmax = Tmlts(k)
     940              :          else                ! fresh ice
     941            0 :             Tmax = -zqin(k)*puny/(rhos*cp_ice*vicen)
     942              :          endif
     943              : 
     944              :       !-----------------------------------------------------------------
     945              :       ! Check for zTin > Tmax and zTin < Tmin
     946              :       !-----------------------------------------------------------------
     947     59711458 :          if (zTin(k) > Tmax) then
     948            0 :             tice_high = .true.
     949     59711458 :          elseif (zTin(k) < Tmin) then
     950            0 :             tice_low  = .true.
     951              :          endif
     952              : 
     953              :       !-----------------------------------------------------------------
     954              :       ! If zTin is out of bounds, print diagnostics and exit.
     955              :       !-----------------------------------------------------------------
     956              : 
     957     59711458 :          if (tice_high) then
     958            0 :             write(warnstr,*) ' '
     959            0 :             call icepack_warnings_add(warnstr)
     960            0 :             write(warnstr,*) subname, 'Starting thermo, zTin > Tmax, layer', k
     961            0 :             call icepack_warnings_add(warnstr)
     962            0 :             write(warnstr,*) subname, 'k:', k
     963            0 :             call icepack_warnings_add(warnstr)
     964            0 :             write(warnstr,*) subname, 'zTin =',zTin(k),', Tmax=',Tmax
     965            0 :             call icepack_warnings_add(warnstr)
     966            0 :             write(warnstr,*) subname, 'zSin =',zSin(k)
     967            0 :             call icepack_warnings_add(warnstr)
     968            0 :             write(warnstr,*) subname, 'hin =',hin
     969            0 :             call icepack_warnings_add(warnstr)
     970            0 :             write(warnstr,*) subname, 'zqin =',zqin(k)
     971            0 :             call icepack_warnings_add(warnstr)
     972            0 :             write(warnstr,*) subname, 'qmlt=',enthalpy_of_melting(zSin(k))
     973            0 :             call icepack_warnings_add(warnstr)
     974            0 :             write(warnstr,*) subname, 'Tmlt=',Tmlts(k)
     975            0 :             call icepack_warnings_add(warnstr)
     976              : 
     977            0 :             if (ktherm == 2) then
     978            0 :                zqin(k) = enthalpy_of_melting(zSin(k)) - c1
     979            0 :                zTin(k) = icepack_mushy_temperature_mush(zqin(k),zSin(k))
     980            0 :                write(warnstr,*) subname, 'Corrected quantities'
     981            0 :                call icepack_warnings_add(warnstr)
     982            0 :                write(warnstr,*) subname, 'zqin=',zqin(k)
     983            0 :                call icepack_warnings_add(warnstr)
     984            0 :                write(warnstr,*) subname, 'zTin=',zTin(k)
     985            0 :                call icepack_warnings_add(warnstr)
     986              :             else
     987            0 :                call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
     988            0 :                call icepack_warnings_add(subname//" init_vertical_profile: Starting thermo, zTin > Tmax, layer" )
     989            0 :                return
     990              :             endif
     991              :          endif                  ! tice_high
     992              : 
     993     59711458 :          if (tice_low) then
     994            0 :             write(warnstr,*) ' '
     995            0 :             call icepack_warnings_add(warnstr)
     996            0 :             write(warnstr,*) subname, 'Starting thermo T < Tmin, layer', k
     997            0 :             call icepack_warnings_add(warnstr)
     998            0 :             write(warnstr,*) subname, 'zTin =', zTin(k)
     999            0 :             call icepack_warnings_add(warnstr)
    1000            0 :             write(warnstr,*) subname, 'Tmin =', Tmin
    1001            0 :             call icepack_warnings_add(warnstr)
    1002            0 :             call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    1003            0 :             call icepack_warnings_add(subname//" init_vertical_profile: Starting thermo, zTin < Tmin, layer" )
    1004            0 :             return
    1005              :          endif                  ! tice_low
    1006              : 
    1007              :       !-----------------------------------------------------------------
    1008              :       ! correct roundoff error
    1009              :       !-----------------------------------------------------------------
    1010              : 
    1011     59711458 :          if (ktherm /= 2) then
    1012      8900453 :             if (zTin(k) > c0) then
    1013            0 :                 zTin(k) = c0
    1014            0 :                 zqin(k) = -rhoi*Lfresh
    1015              :             endif
    1016              :          endif
    1017              : 
    1018     59711458 :          if (ktherm == 1) then
    1019      8900453 :             if (zTin(k)>= -zSin(k)*depressT) then
    1020            0 :                 zTin(k) = -zSin(k)*depressT - puny
    1021            0 :                 zqin(k) = -zSin(k)*depressT*rhoi*cp_ocn
    1022              :             endif
    1023              :          endif
    1024              : 
    1025              :       !-----------------------------------------------------------------
    1026              :       ! initial energy per unit area of ice/snow, relative to 0 C
    1027              :       !-----------------------------------------------------------------
    1028              : 
    1029     68489396 :          einit = einit + hilyr*zqin(k)
    1030              : 
    1031              :       enddo                     ! nilyr
    1032              : 
    1033              :       end subroutine init_vertical_profile
    1034              : 
    1035              : !=======================================================================
    1036              : !
    1037              : ! Compute growth and/or melting at the top and bottom surfaces.
    1038              : ! Convert snow to ice if necessary.
    1039              : !
    1040              : ! authors William H. Lipscomb, LANL
    1041              : !         C. M. Bitz, UW
    1042              : 
    1043      8777938 :       subroutine thickness_changes (dt,        yday,     &
    1044              :                                     efinal,              &
    1045              :                                     hin,       hilyr,    &
    1046              :                                     hsn,       hslyr,    &
    1047      8777938 :                                     zqin,      zqsn,     &
    1048     17555876 :                                     smice,     massice,  &
    1049     17555876 :                                     smliq,     massliq,  &
    1050              :                                     fbot,      Tbot,     &
    1051              :                                     flatn,     fsurfn,   &
    1052              :                                     fcondtopn, fcondbotn, &
    1053              :                                     fsnow,     hsn_new,  &
    1054              :                                     fhocnn,    evapn,    &
    1055              :                                     evapsn,    evapin,   &
    1056              :                                     meltt,     melts,    &
    1057              :                                     meltsliq,  frain,    &
    1058              :                                     meltb,     &
    1059              :                                     congel,    snoice,   &
    1060              :                                     mlt_onset, frz_onset,&
    1061      8777938 :                                     zSin,      sss,      &
    1062              :                                     sst,                 &
    1063      8777938 :                                     dsnow,     rsnw)
    1064              : 
    1065              :       real (kind=dbl_kind), intent(in) :: &
    1066              :          dt          , & ! time step
    1067              :          yday            ! day of the year
    1068              : 
    1069              :       real (kind=dbl_kind), intent(in) :: &
    1070              :          fbot        , & ! ice-ocean heat flux at bottom surface (W/m^2)
    1071              :          Tbot        , & ! ice bottom surface temperature (deg C)
    1072              :          fsnow       , & ! snowfall rate (kg m-2 s-1)
    1073              :          flatn       , & ! surface downward latent heat (W m-2)
    1074              :          fsurfn      , & ! net flux to top surface, excluding fcondtopn
    1075              :          fcondtopn   , & ! downward cond flux at top surface (W m-2)
    1076              :          frain           ! rainfall rate (kg/m2/s)
    1077              : 
    1078              :       real (kind=dbl_kind), intent(inout) :: &
    1079              :          fcondbotn       ! downward cond flux at bottom surface (W m-2)
    1080              : 
    1081              :       real (kind=dbl_kind), dimension (:), intent(inout) :: &
    1082              :          zqin        , & ! ice layer enthalpy (J m-3)
    1083              :          zqsn        , & ! snow layer enthalpy (J m-3)
    1084              :          rsnw        , & ! snow grain radius (10^-6 m)
    1085              :          smice       , & ! ice mass tracer in snow (kg/m^3)
    1086              :          smliq       , & ! liquid water mass tracer in snow (kg/m^3)
    1087              :          massice     , & ! ice mass in snow (kg/m^2)
    1088              :          massliq         ! liquid water mass in snow (kg/m^2)
    1089              : 
    1090              :       real (kind=dbl_kind), intent(inout) :: &
    1091              :          hilyr       , & ! ice layer thickness (m)
    1092              :          hslyr           ! snow layer thickness (m)
    1093              : 
    1094              :       real (kind=dbl_kind), intent(inout) :: &
    1095              :          meltt       , & ! top ice melt             (m/step-->cm/day)
    1096              :          melts       , & ! snow melt                (m/step-->cm/day)
    1097              :          meltsliq    , & ! snow melt mass           (kg/m^2/step-->kg/m^2/day)
    1098              :          meltb       , & ! basal ice melt           (m/step-->cm/day)
    1099              :          congel      , & ! basal ice growth         (m/step-->cm/day)
    1100              :          snoice      , & ! snow-ice formation       (m/step-->cm/day)
    1101              :          dsnow       , & ! snow  formation          (m/step-->cm/day)
    1102              : !        iage        , & ! ice age (s)
    1103              :          mlt_onset   , & ! day of year that sfc melting begins
    1104              :          frz_onset       ! day of year that freezing begins (congel or frazil)
    1105              : 
    1106              :       real (kind=dbl_kind), intent(inout) :: &
    1107              :          hin         , & ! total ice thickness (m)
    1108              :          hsn             ! total snow thickness (m)
    1109              : 
    1110              :       real (kind=dbl_kind), intent(out):: &
    1111              :          efinal          ! final energy of melting (J m-2)
    1112              : 
    1113              :       real (kind=dbl_kind), intent(out):: &
    1114              :          fhocnn      , & ! fbot, corrected for any surplus energy (W m-2)
    1115              :          evapn       , & ! ice/snow mass sublimated/condensed (kg m-2 s-1)
    1116              :          evapsn      , & ! ice/snow mass sublimated/condensed over snow (kg m-2 s-1)
    1117              :          evapin          ! ice/snow mass sublimated/condensed over ice (kg m-2 s-1)
    1118              : 
    1119              :       real (kind=dbl_kind), intent(out):: &
    1120              :          hsn_new         ! thickness of new snow (m)
    1121              : 
    1122              :       ! changes to zSin in this subroutine are not reloaded into the
    1123              :       ! trcrn array for ktherm /= 2, so we could remove ktherm=2 conditionals
    1124              :       real (kind=dbl_kind), dimension (:), intent(inout) :: &
    1125              :          zSin            ! ice layer salinity (ppt)
    1126              : 
    1127              :       real (kind=dbl_kind), intent(in) :: &
    1128              :          sst         , & ! sea surface temperature (C)
    1129              :          sss             ! ocean salinity (PSU)
    1130              : 
    1131              :       ! local variables
    1132              : 
    1133              :       integer (kind=int_kind) :: &
    1134              :          k               ! vertical index
    1135              : 
    1136              :       real (kind=dbl_kind) :: &
    1137              :          esub        , & ! energy for sublimation, > 0    (J m-2)
    1138              :          econ        , & ! energy for condensation, < 0   (J m-2)
    1139              :          etop_mlt    , & ! energy for top melting, > 0    (J m-2)
    1140              :          ebot_mlt    , & ! energy for bottom melting, > 0 (J m-2)
    1141              :          ebot_gro    , & ! energy for bottom growth, < 0  (J m-2)
    1142              :          emlt_atm    , & ! total energy of brine, from atmosphere (J m-2)
    1143              :          emlt_ocn        ! total energy of brine, to ocean        (J m-2)
    1144              : 
    1145              :       real (kind=dbl_kind) :: &
    1146              :          qbotmax     , & ! max enthalpy of ice growing at bottom
    1147              :          dhi         , & ! change in ice thickness
    1148              :          dhs         , & ! change in snow thickness
    1149              :          Ti          , & ! ice temperature
    1150              :          Ts          , & ! snow temperature
    1151              :          qbot        , & ! enthalpy of ice growing at bottom surface (J m-3)
    1152              :          qsub        , & ! energy/unit volume to sublimate ice/snow (J m-3)
    1153              :          hqtot       , & ! sum of h*q for two layers
    1154              :          wk1         , & ! temporary variable
    1155              :          zqsnew      , & ! enthalpy of new snow (J m-3)
    1156              :          hstot       , & ! snow thickness including new snow (m)
    1157              :          Tmlts           ! melting temperature (deg C)
    1158              : 
    1159              :       real (kind=dbl_kind), dimension (nilyr+1) :: &
    1160     17555876 :          zi1         , & ! depth of ice layer boundaries (m)
    1161     17555876 :          zi2             ! adjusted depths, with equal hilyr (m)
    1162              : 
    1163              :       real (kind=dbl_kind), dimension (nslyr+1) :: &
    1164     17555876 :          zs1         , & ! depth of snow layer boundaries (m)
    1165     17555876 :          zs2             ! adjusted depths, with equal hslyr (m)
    1166              : 
    1167              :       real (kind=dbl_kind), dimension (nilyr) :: &
    1168     26333814 :          dzi             ! ice layer thickness after growth/melting (m)
    1169              : 
    1170              :       real (kind=dbl_kind), dimension (nslyr) :: &
    1171     17555876 :          dzs             ! snow layer thickness after growth/melting (m)
    1172              : 
    1173              :       real (kind=dbl_kind), dimension (nilyr) :: &
    1174     17555876 :          qm          , & ! energy of melting (J m-3) = zqin in BL99 formulation
    1175      8777938 :          qmlt            ! enthalpy of melted ice (J m-3) = zero in BL99 formulation
    1176              : 
    1177              :       real (kind=dbl_kind) :: &
    1178              :          qbotm       , & ! enthalpy of newly formed congelation ice
    1179              :          qbotp       , & ! enthalpy needed to grow new congelation ice (includes ocean enthalpy)
    1180              :          qbotw       , & ! enthalpy transferred to ocean during congelation freezing
    1181              :          mass        , & ! total  mass from snow density tracers (kg/m^2)
    1182              :          massi       , & ! ice mass change factor
    1183              :          tmp1            ! temporary scalar
    1184              : 
    1185              :       character(len=*),parameter :: subname='(thickness_changes)'
    1186              : 
    1187              :       !-----------------------------------------------------------------
    1188              :       ! Initialize
    1189              :       !-----------------------------------------------------------------
    1190              : 
    1191      8777938 :       dhi = c0
    1192      8777938 :       dhs = c0
    1193      8777938 :       hsn_new  = c0
    1194              : 
    1195     68489396 :       do k = 1, nilyr
    1196     68489396 :          dzi(k) = hilyr
    1197              :       enddo
    1198              : 
    1199     22512048 :       do k = 1, nslyr
    1200     22512048 :          dzs(k) = hslyr
    1201              :       enddo
    1202              : 
    1203     68489396 :       do k = 1, nilyr
    1204     59711458 :          if (ktherm == 2) then
    1205     50811005 :             qmlt(k) = enthalpy_of_melting(zSin(k))
    1206              :          else
    1207      8900453 :             qmlt(k) = c0
    1208              :          endif
    1209     59711458 :          qm(k) = zqin(k) - qmlt(k)
    1210     59711458 :          emlt_atm = c0
    1211     68489396 :          emlt_ocn = c0
    1212              :       enddo
    1213              : 
    1214              :       !-----------------------------------------------------------------
    1215              :       ! For l_brine = false (fresh ice), check for temperatures > 0.
    1216              :       !  Melt ice or snow as needed to bring temperatures back to 0.
    1217              :       ! For l_brine = true, this should not be necessary.
    1218              :       !-----------------------------------------------------------------
    1219              : 
    1220      8777938 :       if (.not. l_brine) then
    1221              : 
    1222            0 :          do k = 1, nslyr
    1223            0 :             Ts = (Lfresh + zqsn(k)/rhos) / cp_ice
    1224            0 :             if (Ts > c0) then
    1225            0 :                dhs = cp_ice*Ts*dzs(k) / Lfresh
    1226              : 
    1227            0 :                mass = massice(k) + massliq(k)
    1228            0 :                massi = c0
    1229            0 :                if (dzs(k) > puny) massi = max(c0, c1 - dhs/dzs(k))
    1230            0 :                massice(k) = massice(k) * massi
    1231            0 :                massliq(k) = mass - massice(k) ! conserve mass
    1232              : 
    1233            0 :                dzs(k) = dzs(k) - dhs  ! dhs > 0
    1234            0 :                melts = melts + dhs
    1235            0 :                zqsn(k) = -rhos*Lfresh
    1236              :             endif
    1237              :          enddo
    1238              : 
    1239            0 :          do k = 1, nilyr
    1240            0 :             Ti = (Lfresh + zqin(k)/rhoi) / cp_ice
    1241            0 :             if (Ti > c0) then
    1242            0 :                dhi = cp_ice*Ti*dzi(k) / Lfresh
    1243            0 :                dzi(k) = dzi(k) - dhi
    1244            0 :                zqin(k) = -rhoi*Lfresh
    1245              :             endif
    1246              :          enddo                  ! k
    1247              : 
    1248              :       endif                     ! .not. l_brine
    1249              : 
    1250              :       !-----------------------------------------------------------------
    1251              :       ! Compute energy available for sublimation/condensation, top melt,
    1252              :       ! and bottom growth/melt.
    1253              :       !-----------------------------------------------------------------
    1254              : 
    1255      8777938 :       wk1 = -flatn * dt
    1256      8777938 :       esub = max(wk1, c0)     ! energy for sublimation, > 0
    1257      8777938 :       econ = min(wk1, c0)     ! energy for condensation, < 0
    1258              : 
    1259      8777938 :       wk1 = (fsurfn - fcondtopn) * dt
    1260      8777938 :       etop_mlt = max(wk1, c0)           ! etop_mlt > 0
    1261              : 
    1262      8777938 :       wk1 = (fcondbotn - fbot) * dt
    1263      8777938 :       ebot_mlt = max(wk1, c0)           ! ebot_mlt > 0
    1264      8777938 :       ebot_gro = min(wk1, c0)           ! ebot_gro < 0
    1265              : 
    1266              :       !--------------------------------------------------------------
    1267              :       ! Condensation (evapn > 0)
    1268              :       ! Note: evapn here has unit of kg/m^2.  Divide by dt later.
    1269              :       ! This is the only case in which energy from the atmosphere
    1270              :       ! is used for changes in the brine energy (emlt_atm).
    1271              :       !--------------------------------------------------------------
    1272              : 
    1273      8777938 :       evapn  = c0          ! initialize
    1274      8777938 :       evapsn = c0          ! initialize
    1275      8777938 :       evapin = c0          ! initialize
    1276              : 
    1277      8777938 :       if (hsn > puny) then    ! add snow with enthalpy zqsn(1)
    1278      8219155 :          dhs = econ / (zqsn(1) - rhos*Lvap) ! econ < 0, dhs > 0
    1279              : 
    1280              :          ! assume all condensation becomes ice (no liquid)
    1281      8219155 :          massice(1) = massice(1) + dhs*rhos
    1282              : 
    1283      8219155 :          dzs(1) = dzs(1) + dhs
    1284      8219155 :          evapn = evapn + dhs*rhos
    1285      8219155 :          evapsn = evapsn + dhs*rhos
    1286              :       else                        ! add ice with enthalpy zqin(1)
    1287       558783 :          dhi = econ / (qm(1) - rhoi*Lvap) ! econ < 0, dhi > 0
    1288       558783 :          dzi(1) = dzi(1) + dhi
    1289       558783 :          evapn = evapn + dhi*rhoi
    1290       558783 :          evapin = evapin + dhi*rhoi
    1291              :          ! enthalpy of melt water
    1292       558783 :          emlt_atm = emlt_atm - qmlt(1) * dhi
    1293              :       endif
    1294              : 
    1295              :       !--------------------------------------------------------------
    1296              :       ! Grow ice (bottom)
    1297              :       !--------------------------------------------------------------
    1298              : 
    1299      8777938 :       if (ktherm == 2) then
    1300              : 
    1301      7258715 :          if (congel_freeze == 'one-step') then
    1302              :             ! Plante et al., The Cryosphere, 18, 1685-1708, 2024
    1303       349134 :             qbotm = enthalpy_mush_liquid_fraction(Tbot, phi_i_mushy)
    1304       349134 :             qbotw = enthalpy_brine(sst)
    1305       349134 :             qbotp = qbotm - qbotw
    1306       349134 :             dhi = ebot_gro / qbotp     ! dhi > 0
    1307       349134 :             hstot = dzi(nilyr)*zSin(nilyr) + dhi*sss*phi_i_mushy
    1308       349134 :             hqtot = dzi(nilyr)*zqin(nilyr) + dhi*qbotm
    1309       349134 :             emlt_ocn = emlt_ocn - qbotw * dhi
    1310              :          else ! two-step
    1311      6909581 :             qbotm = icepack_enthalpy_mush(Tbot, sss)
    1312      6909581 :             qbotp = -Lfresh * rhoi * (c1 - phi_i_mushy)
    1313      6909581 :             qbotw = qbotm - qbotp
    1314      6909581 :             dhi = ebot_gro / qbotp     ! dhi > 0
    1315      6909581 :             hstot = dzi(nilyr)*zSin(nilyr) + dhi*sss
    1316      6909581 :             hqtot = dzi(nilyr)*zqin(nilyr) + dhi*qbotm
    1317      6909581 :             emlt_ocn = emlt_ocn - qbotw * dhi
    1318              :          endif
    1319              : 
    1320              :       else
    1321              : 
    1322      1519223 :          Tmlts = -zSin(nilyr) * depressT
    1323              : 
    1324              :          ! enthalpy of new ice growing at bottom surface
    1325      1519223 :             if (l_brine) then
    1326      1519223 :                qbotmax = -p5*rhoi*Lfresh  ! max enthalpy of ice growing at bottom
    1327              :                qbot = -rhoi * (cp_ice * (Tmlts-Tbot) &
    1328              :                     + Lfresh * (c1-Tmlts/Tbot) &
    1329      1519223 :                     - cp_ocn * Tmlts)
    1330      1519223 :                qbot = min (qbot, qbotmax)      ! in case Tbot is close to Tmlt
    1331              :             else
    1332            0 :                qbot = -rhoi * (-cp_ice * Tbot + Lfresh)
    1333              :             endif
    1334      1519223 :          dhi = ebot_gro / qbot     ! dhi > 0
    1335              : 
    1336      1519223 :          hqtot = dzi(nilyr)*zqin(nilyr) + dhi*qbot
    1337      1519223 :          hstot = c0
    1338              :       endif ! ktherm
    1339              : 
    1340      8777938 :       dzi(nilyr) = dzi(nilyr) + dhi
    1341      8777938 :       if (dzi(nilyr) > puny) then
    1342      8777938 :          zqin(nilyr) = hqtot / dzi(nilyr)
    1343      8777938 :          if (ktherm == 2) then
    1344      7258715 :             zSin(nilyr) = hstot / dzi(nilyr)
    1345      7258715 :             qmlt(nilyr) = enthalpy_of_melting(zSin(nilyr))
    1346              :          else
    1347      1519223 :             qmlt(nilyr) = c0
    1348              :          endif
    1349      8777938 :          qm(nilyr) = zqin(nilyr) - qmlt(nilyr)
    1350              :       endif
    1351              : 
    1352              :       ! update ice age due to freezing (new ice age = dt)
    1353              :       !         if (tr_iage) &
    1354              :       !            iage = (iage*hin + dt*dhi) / (hin + dhi)
    1355              : 
    1356              :       ! history diagnostics
    1357      8777938 :       congel = congel + dhi
    1358      8777938 :       if (dhi > puny .and. frz_onset < puny) &
    1359          177 :            frz_onset = yday
    1360              : 
    1361     22512048 :       do k = 1, nslyr
    1362              : 
    1363              :          !--------------------------------------------------------------
    1364              :          ! Remove internal snow melt
    1365              :          !--------------------------------------------------------------
    1366              : 
    1367              : !  more efficient formulation using Ts, dhs > 0 (not BFB)
    1368              : !         Ts = (Lfresh + zqsn(k)/rhos) / cp_ice
    1369              : !         if (ktherm == 2 .and. Ts > c0) then
    1370              : !            dhs = -dzs(k) * cp_ice*Ts/Lfresh ! dhs < 0
    1371              : 
    1372     13734110 :          if (ktherm == 2 .and. zqsn(k) > -rhos * Lfresh) then
    1373              :             dhs = max(-dzs(k), &
    1374       184339 :                 -((zqsn(k) + rhos*Lfresh) / (rhos*Lfresh)) * dzs(k))
    1375              : 
    1376       184339 :             mass = massice(k) + massliq(k)
    1377       184339 :             massi = c0
    1378       184339 :             if (dzs(k) > puny) massi = max(c0, c1 + dhs/dzs(k))
    1379       184339 :             massice(k) = massice(k) * massi
    1380       184339 :             massliq(k) = mass - massice(k) ! conserve mass
    1381              : 
    1382       184339 :             dzs(k) = dzs(k) + dhs      ! dhs < 0
    1383       184339 :             zqsn(k) = -rhos * Lfresh
    1384       184339 :             melts = melts - dhs
    1385              :             ! delta E = zqsn(k) + rhos * Lfresh
    1386              :          endif
    1387              : 
    1388              :          !--------------------------------------------------------------
    1389              :          ! Sublimation of snow (evapn < 0)
    1390              :          !--------------------------------------------------------------
    1391              : 
    1392     13734110 :          qsub = zqsn(k) - rhos*Lvap ! qsub < 0
    1393     13734110 :          dhs  = max (-dzs(k), esub/qsub)  ! esub > 0, dhs < 0
    1394              : 
    1395     13734110 :          mass  = massice(k) + massliq(k)
    1396     13734110 :          massi = c0
    1397     13734110 :          if (dzs(k) > puny) massi = c1 + dhs/dzs(k)
    1398     13734110 :          massice(k) = massice(k) * massi
    1399     13734110 :          massliq(k) = max(c0, mass + rhos*dhs - massice(k)) ! conserve new total mass
    1400              : 
    1401     13734110 :          dzs(k) = dzs(k) + dhs
    1402     13734110 :          esub = esub - dhs*qsub
    1403     13734110 :          esub = max(esub, c0)   ! in case of roundoff error
    1404     13734110 :          evapn  = evapn  + dhs*rhos
    1405     13734110 :          evapsn = evapsn + dhs*rhos
    1406              : 
    1407              :          !--------------------------------------------------------------
    1408              :          ! Melt snow (top)
    1409              :          !--------------------------------------------------------------
    1410              : 
    1411     13734110 :          dhs = max(-dzs(k), etop_mlt/zqsn(k))
    1412              : 
    1413     13734110 :          mass = massice(k) + massliq(k)
    1414     13734110 :          massi = c0
    1415     13734110 :          if (dzs(k) > puny) massi = max(c0, c1 + dhs/dzs(k))
    1416     13734110 :          massice(k) = massice(k) * massi
    1417     13734110 :          massliq(k) = mass - massice(k) ! conserve mass
    1418              : 
    1419     13734110 :          dzs(k) = dzs(k) + dhs         ! zqsn < 0, dhs < 0
    1420     13734110 :          etop_mlt = etop_mlt - dhs*zqsn(k)
    1421     13734110 :          etop_mlt = max(etop_mlt, c0) ! in case of roundoff error
    1422              : 
    1423              :          ! history diagnostics
    1424     13734110 :          if (dhs < -puny .and. mlt_onset < puny) &
    1425           85 :               mlt_onset = yday
    1426     22512048 :          melts = melts - dhs
    1427              : 
    1428              :       enddo                     ! nslyr
    1429              : 
    1430     68489396 :       do k = 1, nilyr
    1431              : 
    1432              :          !--------------------------------------------------------------
    1433              :          ! Sublimation of ice (evapn < 0)
    1434              :          !--------------------------------------------------------------
    1435              : 
    1436     59711458 :          qsub = qm(k) - rhoi*Lvap              ! qsub < 0
    1437     59711458 :          dhi  = max (-dzi(k), esub/qsub) ! esub < 0, dhi < 0
    1438     59711458 :          dzi(k) = dzi(k) + dhi
    1439     59711458 :          esub = esub - dhi*qsub
    1440     59711458 :          esub = max(esub, c0)
    1441     59711458 :          evapn = evapn + dhi*rhoi
    1442     59711458 :          evapin = evapin + dhi*rhoi
    1443     59711458 :          emlt_ocn = emlt_ocn - qmlt(k) * dhi
    1444              : 
    1445              :          !--------------------------------------------------------------
    1446              :          ! Melt ice (top)
    1447              :          !--------------------------------------------------------------
    1448              : 
    1449     59711458 :          if (qm(k) < c0) then
    1450     59711153 :             dhi = max(-dzi(k), etop_mlt/qm(k))
    1451              :          else
    1452          305 :             qm(k) = c0
    1453          305 :             dhi = -dzi(k)
    1454              :          endif
    1455     59711458 :          emlt_ocn = emlt_ocn - max(zqin(k),qmlt(k)) * dhi
    1456              : 
    1457     59711458 :          dzi(k) = dzi(k) + dhi         ! zqin < 0, dhi < 0
    1458     59711458 :          etop_mlt = max(etop_mlt - dhi*qm(k), c0)
    1459              : 
    1460              :          ! history diagnostics
    1461     59711458 :          if (dhi < -puny .and. mlt_onset < puny) &
    1462          143 :               mlt_onset = yday
    1463     68489396 :          meltt = meltt - dhi
    1464              : 
    1465              :       enddo                     ! nilyr
    1466              : 
    1467     68489396 :       do k = nilyr, 1, -1
    1468              : 
    1469              :          !--------------------------------------------------------------
    1470              :          ! Melt ice (bottom)
    1471              :          !--------------------------------------------------------------
    1472              : 
    1473     59711458 :          if (qm(k) < c0) then
    1474     59711153 :             dhi = max(-dzi(k), ebot_mlt/qm(k))
    1475              :          else
    1476          305 :             qm(k) = c0
    1477          305 :             dhi = -dzi(k)
    1478              :          endif
    1479     59711458 :          emlt_ocn = emlt_ocn - max(zqin(k),qmlt(k)) * dhi
    1480              : 
    1481     59711458 :          dzi(k) = dzi(k) + dhi         ! zqin < 0, dhi < 0
    1482     59711458 :          ebot_mlt = max(ebot_mlt - dhi*qm(k), c0)
    1483              : 
    1484              :          ! history diagnostics
    1485     68489396 :          meltb = meltb -dhi
    1486              : 
    1487              :       enddo                     ! nilyr
    1488              : 
    1489     22512048 :       do k = nslyr, 1, -1
    1490              : 
    1491              :          !--------------------------------------------------------------
    1492              :          ! Melt snow (only if all the ice has melted)
    1493              :          !--------------------------------------------------------------
    1494              : 
    1495     13734110 :          dhs = max(-dzs(k), ebot_mlt/zqsn(k))
    1496              : 
    1497     13734110 :          mass = massice(k) + massliq(k)
    1498     13734110 :          massi = c0
    1499     13734110 :          if (dzs(k) > puny) massi = max(c0, c1 + dhs/dzs(k))
    1500     13734110 :          massice(k) = massice(k) * massi
    1501     13734110 :          massliq(k) = mass - massice(k) ! conserve mass
    1502              : 
    1503     13734110 :          dzs(k) = dzs(k) + dhs         ! zqsn < 0, dhs < 0
    1504     13734110 :          ebot_mlt = ebot_mlt - dhs*zqsn(k)
    1505     13734110 :          ebot_mlt = max(ebot_mlt, c0)
    1506     22512048 :          melts = melts - dhs
    1507              :       enddo                     ! nslyr
    1508              : 
    1509              :       !-----------------------------------------------------------------
    1510              :       ! Compute heat flux used by the ice (<=0).
    1511              :       ! fhocn is the available ocean heat that is left after use by ice
    1512              :       !-----------------------------------------------------------------
    1513              : 
    1514              :       fhocnn = fbot &
    1515      8777938 :              + (esub + etop_mlt + ebot_mlt)/dt
    1516              : 
    1517              :     !-----------------------------------------------------------------
    1518              :     ! Add new snowfall at top surface
    1519              :     !----------------------------------------------------------------
    1520              :       ! NOTE: If heat flux diagnostics are to work, new snow should
    1521              :       !       have T = 0 (i.e. q = -rhos*Lfresh) and should not be
    1522              :       !       converted to rain.
    1523              :       !----------------------------------------------------------------
    1524              : 
    1525      8777938 :       if (fsnow > c0) then
    1526      7657473 :          hsn_new = fsnow/rhos * dt
    1527      7657473 :          zqsnew = -rhos*Lfresh
    1528      7657473 :          hstot = dzs(1) + hsn_new
    1529              : 
    1530      7657473 :          if (hstot > c0) then
    1531              :             zqsn(1) = (dzs(1) * zqsn(1) &
    1532      7657473 :                     + hsn_new * zqsnew) / hstot
    1533      7657473 :             zqsn(1) = min(zqsn(1), zqsnew) ! avoid roundoff errors
    1534      7657473 :             dzs(1) = hstot
    1535      7657473 :             massice(1) = massice(1) + fsnow*dt
    1536              :          endif
    1537              :       endif
    1538              : 
    1539              :     !-----------------------------------------------------------------
    1540              :     ! Add rain at top surface (only to liquid tracer)
    1541              :     !-----------------------------------------------------------------
    1542              : 
    1543      8777938 :       massliq(1) = massliq(1) + frain*dt
    1544              : 
    1545              :     !-----------------------------------------------------------------
    1546              :     ! Find the new ice and snow thicknesses.
    1547              :     !-----------------------------------------------------------------
    1548              : 
    1549      8777938 :       hin = c0
    1550      8777938 :       hsn = c0
    1551              : 
    1552     68489396 :       do k = 1, nilyr
    1553     68489396 :          hin = hin + dzi(k)
    1554              :       enddo                     ! k
    1555              : 
    1556     22512048 :       do k = 1, nslyr
    1557     13734110 :          hsn = hsn + dzs(k)
    1558     22512048 :          dsnow = dsnow + dzs(k) - hslyr
    1559              :       enddo                     ! k
    1560              : 
    1561              :     !-------------------------------------------------------------------
    1562              :     ! Incorporate new snow for snow grain radius in upper layer
    1563              :     !-------------------------------------------------------------------
    1564              : 
    1565      8777938 :       if (snwgrain .and. hsn_new > c0) then
    1566       832619 :          tmp1    = max(c0, dzs(1) - hsn_new)
    1567              :          rsnw(1) =    (rsnw_fall * hsn_new + rsnw(1) * tmp1) &
    1568       832619 :                  / max(            hsn_new +           tmp1, puny)
    1569       832619 :          rsnw(1) = max(rsnw_fall, min(rsnw_tmax, rsnw(1)))
    1570              :       endif
    1571              : 
    1572              :     !-------------------------------------------------------------------
    1573              :     ! Convert snow to ice if snow lies below freeboard.
    1574              :     !-------------------------------------------------------------------
    1575              : 
    1576      8777938 :       if (ktherm /= 2) &
    1577              :          call freeboard (snoice,                 &
    1578              :                          hin,      hsn,          &
    1579              :                          zqin,     zqsn,         &
    1580              :                          dzi,      dzs,          &
    1581              :                          dsnow,                  &
    1582      1519223 :                          massice,  massliq)
    1583      8777938 :          if (icepack_warnings_aborted(subname)) return
    1584              : 
    1585              :     !-------------------------------------------------------------------
    1586              :     ! Update snow mass tracers for uneven layers
    1587              :     !-------------------------------------------------------------------
    1588              : 
    1589      8777938 :       if (snwgrain) then
    1590              : 
    1591      5311734 :          do k = 1, nslyr
    1592      4426445 :             meltsliq   = meltsliq + massliq(k) ! used in drain_snow when all snow has melted
    1593      5311734 :             if (dzs(k) > puny) then
    1594      3763191 :                smice(k) = massice(k) / dzs(k)
    1595      3763191 :                smliq(k) = massliq(k) / dzs(k)
    1596              :             else
    1597       663254 :                smice(k) = c0 ! reset to rhos below
    1598       663254 :                smliq(k) = c0
    1599       663254 :                massice(k) = c0
    1600       663254 :                massliq(k) = c0
    1601              :             endif
    1602              :          enddo
    1603              : 
    1604              :     !-------------------------------------------------------------------
    1605              :     ! Check for negative snow mass tracers
    1606              :     !-------------------------------------------------------------------
    1607              : 
    1608      5311734 :          do k = 1, nslyr
    1609      4426445 :             if (massice(k) < c0) then
    1610            0 :                if (massice(k) > -puny) then
    1611            0 :                    massice(k) = c0
    1612              :                else
    1613            0 :                   call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    1614            0 :                   call icepack_warnings_add(subname//" Snow: ice mass tracer error" )
    1615            0 :                   write(warnstr,*) subname, ' negative massice', k,massice(k)
    1616            0 :                   call icepack_warnings_add(warnstr)
    1617            0 :                   write(warnstr,*) subname, ' dzs, smice', k,dzs(k), smice(k)
    1618            0 :                   call icepack_warnings_add(warnstr)
    1619              :                endif
    1620              :             endif
    1621      4426445 :             if (massliq(k) < c0) then
    1622            0 :                if (massliq(k) > -puny) then
    1623            0 :                    massliq(k) = c0
    1624              :                else
    1625            0 :                   call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    1626            0 :                   call icepack_warnings_add(subname//" Snow: liquid mass tracer error" )
    1627            0 :                   write(warnstr,*) subname, ' negative massliq', k,massliq(k)
    1628            0 :                   call icepack_warnings_add(warnstr)
    1629            0 :                   write(warnstr,*) subname, ' dzs, smliq', k,dzs(k), smliq(k)
    1630            0 :                   call icepack_warnings_add(warnstr)
    1631              :                endif
    1632              :             endif
    1633      5311734 :             if (smice(k) > rhofresh) then
    1634            0 :                   call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    1635            0 :                   call icepack_warnings_add(subname//" Snow: large density " )
    1636            0 :                   write(warnstr,*) subname, ' large massice', k,massice(k)
    1637            0 :                   call icepack_warnings_add(warnstr)
    1638            0 :                   write(warnstr,*) subname, ' dzs, smice', k,dzs(k), smice(k)
    1639            0 :                   call icepack_warnings_add(warnstr)
    1640              :                endif
    1641              :          enddo
    1642              : 
    1643              :       endif ! snwgrain
    1644              : 
    1645              : !---!-------------------------------------------------------------------
    1646              : !---! Repartition the ice and snow into equal-thickness layers,
    1647              : !---! conserving energy.
    1648              : !---!-------------------------------------------------------------------
    1649              : 
    1650              :       !-----------------------------------------------------------------
    1651              :       ! Compute desired layer thicknesses.
    1652              :       !-----------------------------------------------------------------
    1653              : 
    1654      8777938 :       if (hin > c0) then
    1655      8777934 :          hilyr = hin / real(nilyr,kind=dbl_kind)
    1656              :       else
    1657            4 :          hin = c0
    1658            4 :          hilyr = c0
    1659              :       endif
    1660      8777938 :       if (hsn > c0) then
    1661      8180059 :          hslyr = hsn / real(nslyr,kind=dbl_kind)
    1662              :       else
    1663       597879 :          hsn = c0
    1664       597879 :          hslyr = c0
    1665              :       endif
    1666              : 
    1667              :       !-----------------------------------------------------------------
    1668              :       ! Compute depths zi1 of old layers (unequal thickness).
    1669              :       ! Compute depths zi2 of new layers (equal thickness).
    1670              :       !-----------------------------------------------------------------
    1671              : 
    1672      8777938 :       zi1(1) = c0
    1673      8777938 :       zi1(1+nilyr) = hin
    1674              : 
    1675      8777938 :       zi2(1) = c0
    1676      8777938 :       zi2(1+nilyr) = hin
    1677              : 
    1678     59711458 :          do k = 1, nilyr-1
    1679     50933520 :             zi1(k+1) = zi1(k) + dzi(k)
    1680     59422440 :             zi2(k+1) = zi2(k) + hilyr
    1681              :          enddo
    1682              : 
    1683              :         !-----------------------------------------------------------------
    1684              :         ! Conserving energy, compute the enthalpy of the new equal layers.
    1685              :         !-----------------------------------------------------------------
    1686              : 
    1687              :          call adjust_enthalpy (nilyr,              &
    1688              :                                zi1,      zi2,      &
    1689              :                                hilyr,    hin,      &
    1690      8777938 :                                zqin)
    1691      8777938 :          if (icepack_warnings_aborted(subname)) return
    1692              : 
    1693      8777938 :          if (ktherm == 2) &
    1694              :               call adjust_enthalpy (nilyr,              &
    1695              :                                     zi1,      zi2,      &
    1696              :                                     hilyr,    hin,      &
    1697      7258715 :                                     zSin)
    1698      8777938 :          if (icepack_warnings_aborted(subname)) return
    1699              : 
    1700      8777938 :       if (nslyr > 1) then
    1701              : 
    1702              :       !-----------------------------------------------------------------
    1703              :       ! Compute depths zs1 of old layers (unequal thickness).
    1704              :       ! Compute depths zs2 of new layers (equal thickness).
    1705              :       !-----------------------------------------------------------------
    1706              : 
    1707      1239043 :          zs1(1) = c0
    1708      1239043 :          zs1(1+nslyr) = hsn
    1709              : 
    1710      1239043 :          zs2(1) = c0
    1711      1239043 :          zs2(1+nslyr) = hsn
    1712              : 
    1713      6195215 :          do k = 1, nslyr-1
    1714      4956172 :             zs1(k+1) = zs1(k) + dzs(k)
    1715      6195215 :             zs2(k+1) = zs2(k) + hslyr
    1716              :          enddo
    1717              : 
    1718              :       !-----------------------------------------------------------------
    1719              :       ! Conserving energy, compute the enthalpy of the new equal layers.
    1720              :       ! Also adjust snow grain radius, ice content and liquid content.
    1721              :       !-----------------------------------------------------------------
    1722              : 
    1723              :          call adjust_enthalpy (nslyr,              &
    1724              :                                zs1,      zs2,      &
    1725              :                                hslyr,    hsn,      &
    1726      1239043 :                                zqsn)
    1727              : 
    1728      1239043 :          if (snwgrain) then
    1729              :             call adjust_enthalpy (nslyr,              &
    1730              :                                   zs1(:),   zs2(:),   &
    1731              :                                   hslyr,    hsn,      &
    1732       885289 :                                   rsnw(:))
    1733              :             call adjust_enthalpy (nslyr,              & ! need a routine to adjust
    1734              :                                   zs1(:),   zs2(:),   & ! mass instead of tracer
    1735              :                                   hslyr,    hsn,      &
    1736       885289 :                                   smice(:))
    1737              :             call adjust_enthalpy (nslyr,              &
    1738              :                                   zs1(:),   zs2(:),   &
    1739              :                                   hslyr,    hsn,      &
    1740       885289 :                                   smliq(:))
    1741              :             ! Update snow mass
    1742      5311734 :             do k = 1, nslyr
    1743      4426445 :                massice(k) = smice(k) * hslyr
    1744      5311734 :                massliq(k) = smliq(k) * hslyr
    1745              :             enddo
    1746              :          endif
    1747      1239043 :          if (icepack_warnings_aborted(subname)) return
    1748              : 
    1749              :       endif   ! nslyr > 1
    1750              : 
    1751              :       !-----------------------------------------------------------------
    1752              :       ! Remove very thin snow layers (ktherm = 2)
    1753              :       !-----------------------------------------------------------------
    1754              : 
    1755      8777938 :       if (ktherm == 2) then
    1756      7258715 :          if (hsn <= puny .or. hin <= c0) then
    1757       379376 :             do k = 1, nslyr
    1758              :                fhocnn = fhocnn &
    1759       255554 :                       + zqsn(k)*hsn/(real(nslyr,kind=dbl_kind)*dt)
    1760       255554 :                zqsn(k) = -rhos*Lfresh
    1761       379376 :                if (snwgrain) then
    1762       131640 :                   meltsliq = meltsliq + massice(k)  ! add to meltponds
    1763       131640 :                   smice(k) = rhos
    1764       131640 :                   smliq(k) = c0
    1765       131640 :                   rsnw(k) = rsnw_fall
    1766              :                endif
    1767              :             enddo
    1768       123822 :             melts = melts + hsn
    1769       123822 :             hsn = c0
    1770       123822 :             hslyr = c0
    1771              :          endif
    1772              :       endif
    1773              : 
    1774              :       !-----------------------------------------------------------------
    1775              :       ! Compute final ice-snow energy, including the energy of
    1776              :       !  sublimated/condensed ice.
    1777              :       !-----------------------------------------------------------------
    1778              : 
    1779      8777938 :       efinal = -evapn*Lvap
    1780      8777938 :       evapn =  evapn/dt
    1781      8777938 :       evapsn =  evapsn/dt
    1782      8777938 :       evapin =  evapin/dt
    1783              : 
    1784     22512048 :       do k = 1, nslyr
    1785     22512048 :          efinal = efinal + hslyr*zqsn(k)
    1786              :       enddo
    1787              : 
    1788     68489396 :       do k = 1, nilyr
    1789     68489396 :          efinal = efinal + hilyr*zqin(k)
    1790              :       enddo                     ! k
    1791              : 
    1792      8777938 :       if (ktherm < 2) then
    1793      1519223 :          emlt_atm = c0
    1794      1519223 :          emlt_ocn = c0
    1795              :       endif
    1796              : 
    1797              :       ! melt water is no longer zero enthalpy with ktherm=2
    1798      8777938 :       fhocnn = fhocnn + emlt_ocn/dt
    1799      8777938 :       efinal = efinal + emlt_atm ! for conservation check
    1800              : 
    1801              :       end subroutine thickness_changes
    1802              : 
    1803              : !=======================================================================
    1804              : !
    1805              : ! If there is enough snow to lower the ice/snow interface below
    1806              : ! sea level, convert enough snow to ice to bring the interface back
    1807              : ! to sea level.
    1808              : !
    1809              : ! authors William H. Lipscomb, LANL
    1810              : !         Elizabeth C. Hunke, LANL
    1811              : 
    1812      1519223 :       subroutine freeboard (snoice,             &
    1813              :                             hin,      hsn,      &
    1814            0 :                             zqin,     zqsn,     &
    1815      3038446 :                             dzi,      dzs,      &
    1816              :                             dsnow,              &
    1817      1519223 :                             massice,  massliq)
    1818              : 
    1819              : !     real (kind=dbl_kind), intent(in) :: &
    1820              : !        dt      ! time step
    1821              : 
    1822              :       real (kind=dbl_kind), intent(inout) :: &
    1823              :          snoice  , & ! snow-ice formation       (m/step-->cm/day)
    1824              :          dsnow       ! change in snow thickness after snow-ice formation (m)
    1825              : !        iage        ! ice age (s)
    1826              : 
    1827              :       real (kind=dbl_kind), intent(inout) :: &
    1828              :          hin     , & ! ice thickness (m)
    1829              :          hsn         ! snow thickness (m)
    1830              : 
    1831              :       real (kind=dbl_kind), dimension (:), intent(in) :: &
    1832              :          zqsn        ! snow layer enthalpy (J m-3)
    1833              : 
    1834              :       real (kind=dbl_kind), dimension (:), intent(inout) :: &
    1835              :          zqin     , & ! ice layer enthalpy (J m-3)
    1836              :          dzi      , & ! ice layer thicknesses (m)
    1837              :          dzs      , & ! snow layer thicknesses (m)
    1838              :          massice  , & ! total ice mass of snow in each layer (kg/m^2)
    1839              :          massliq      ! total liquid mass of snow in each layer (kg/m^2)
    1840              : 
    1841              :       ! local variables
    1842              : 
    1843              :       integer (kind=int_kind) :: &
    1844              :          k               ! vertical index
    1845              : 
    1846              :       real (kind=dbl_kind) :: &
    1847              :          dhin        , & ! change in ice thickness (m)
    1848              :          dhsn        , & ! change in snow thickness (m)
    1849              :          hqs             ! sum of h*q for snow (J m-2)
    1850              : 
    1851              :       real (kind=dbl_kind) :: &
    1852              :          wk1         , & ! temporary variable
    1853              :          dhs         , & ! snow to remove from layer (m)
    1854              :          mass        , & ! total snow mass from tracers (kg/m^2)
    1855              :          massi           ! mass change factor
    1856              : 
    1857              :       character(len=*),parameter :: subname='(freeboard)'
    1858              : 
    1859              :       !-----------------------------------------------------------------
    1860              :       ! Determine whether snow lies below freeboard.
    1861              :       !-----------------------------------------------------------------
    1862              : 
    1863      1519223 :       dhin = c0
    1864      1519223 :       dhsn = c0
    1865      1519223 :       hqs  = c0
    1866              : 
    1867      1519223 :       wk1 = hsn - hin*(rhow-rhoi)/rhos  ! not yet consistent with smice/smliq
    1868              : 
    1869      1519223 :       if (wk1 > puny .and. hsn > puny) then  ! snow below freeboard
    1870        24000 :          dhsn = min(wk1*rhoi/rhow, hsn) ! snow to remove
    1871        24000 :          dhin = dhsn * rhos/rhoi        ! ice to add
    1872              :       endif
    1873              : 
    1874              :       !-----------------------------------------------------------------
    1875              :       ! Adjust snow layer thickness.
    1876              :       ! Compute energy to transfer from snow to ice.
    1877              :       !-----------------------------------------------------------------
    1878              : 
    1879      3944942 :       do k = nslyr, 1, -1
    1880      3944942 :          if (dhin > puny) then
    1881        49760 :             dhs = min(dhsn, dzs(k)) ! snow to remove from layer
    1882        49760 :             hsn = hsn - dhs
    1883        49760 :             dsnow = dsnow - dhs   ! new snow
    1884              : 
    1885              :             ! remove both ice and liquid from snow to add to ice
    1886        49760 :             mass = massice(k) + massliq(k)
    1887        49760 :             massi = c0
    1888        49760 :             if (dzs(k) > puny) massi = max(c0, c1 - dhs/dzs(k))
    1889        49760 :             massice(k) = massice(k) * massi
    1890        49760 :             massliq(k) = massliq(k) * massi
    1891              : !            massice(k) = max(c0, massice(k)) ! for roundoff
    1892              : !            massliq(k) = max(c0, massliq(k)) ! for roundoff
    1893              : 
    1894        49760 :             dzs(k) = dzs(k) - dhs
    1895        49760 :             dhsn = dhsn - dhs
    1896        49760 :             dhsn = max(dhsn,c0)
    1897        49760 :             hqs = hqs + dhs * zqsn(k)
    1898              :          endif               ! dhin > puny
    1899              :       enddo
    1900              : 
    1901              :       !-----------------------------------------------------------------
    1902              :       ! Transfer volume and energy from snow to top ice layer.
    1903              :       !-----------------------------------------------------------------
    1904              : 
    1905      1519223 :       if (dhin > puny) then
    1906              :          ! update ice age due to freezing (new ice age = dt)
    1907              :          !            if (tr_iage) &
    1908              :          !               iage = (iage*hin+dt*dhin)/(hin+dhin)
    1909              : 
    1910        24000 :          wk1 = dzi(1) + dhin
    1911        24000 :          hin = hin + dhin
    1912        24000 :          zqin(1) = (dzi(1)*zqin(1) + hqs) / wk1
    1913        24000 :          dzi(1) = wk1
    1914              : 
    1915              :          ! history diagnostic
    1916        24000 :          snoice = snoice + dhin
    1917              :       endif               ! dhin > puny
    1918              : 
    1919      1519223 :       end subroutine freeboard
    1920              : 
    1921              : !=======================================================================
    1922              : !
    1923              : ! Check for energy conservation by comparing the change in energy
    1924              : ! to the net energy input.
    1925              : !
    1926              : ! authors William H. Lipscomb, LANL
    1927              : !         C. M. Bitz, UW
    1928              : !         Adrian K. Turner, LANL
    1929              : 
    1930      8777938 :       subroutine conservation_check_vthermo(dt,                 &
    1931              :                                             fsurfn,   flatn,    &
    1932              :                                             fhocnn,   fswint,   &
    1933              :                                             fsnow,              &
    1934              :                                             einit,    einter,   &
    1935              :                                             efinal,             &
    1936              :                                             fcondtopn,fcondbotn, &
    1937              :                                             fadvocn,  fbot      )
    1938              : 
    1939              :       real (kind=dbl_kind), intent(in) :: &
    1940              :          dt              ! time step
    1941              : 
    1942              :       real (kind=dbl_kind), intent(in) :: &
    1943              :          fsurfn      , & ! net flux to top surface, excluding fcondtopn
    1944              :          flatn       , & ! surface downward latent heat (W m-2)
    1945              :          fhocnn      , & ! fbot, corrected for any surplus energy
    1946              :          fswint      , & ! SW absorbed in ice interior, below surface (W m-2)
    1947              :          fsnow       , & ! snowfall rate (kg m-2 s-1)
    1948              :          fcondtopn   , &
    1949              :          fadvocn     , &
    1950              :          fbot
    1951              : 
    1952              :       real (kind=dbl_kind), intent(in) :: &
    1953              :          einit       , & ! initial energy of melting (J m-2)
    1954              :          einter      , & ! intermediate energy of melting (J m-2)
    1955              :          efinal      , & ! final energy of melting (J m-2)
    1956              :          fcondbotn
    1957              : 
    1958              :       ! local variables
    1959              : 
    1960              :       real (kind=dbl_kind) :: &
    1961              :          einp        , & ! energy input during timestep (J m-2)
    1962              :          ferr            ! energy conservation error (W m-2)
    1963              : 
    1964              :       character(len=*),parameter :: subname='(conservation_check_vthermo)'
    1965              : 
    1966              :       !----------------------------------------------------------------
    1967              :       ! If energy is not conserved, print diagnostics and exit.
    1968              :       !----------------------------------------------------------------
    1969              : 
    1970              :       !-----------------------------------------------------------------
    1971              :       ! Note that fsurf - flat = fsw + flw + fsens; i.e., the latent
    1972              :       ! heat is not included in the energy input, since (efinal - einit)
    1973              :       ! is the energy change in the system ice + vapor, and the latent
    1974              :       ! heat lost by the ice is equal to that gained by the vapor.
    1975              :       !-----------------------------------------------------------------
    1976              : 
    1977              :       einp = (fsurfn - flatn + fswint - fhocnn &
    1978      8777938 :            - fsnow*Lfresh - fadvocn) * dt
    1979      8777938 :       ferr = abs(efinal-einit-einp) / dt
    1980              : 
    1981      8777938 :       if (ferr > 1.1_dbl_kind*ferrmax) then
    1982            0 :          call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    1983            0 :          call icepack_warnings_add(subname//" conservation_check_vthermo: Thermo energy conservation error" )
    1984              : 
    1985            0 :          write(warnstr,*) subname, 'Thermo energy conservation error'
    1986            0 :          call icepack_warnings_add(warnstr)
    1987            0 :          write(warnstr,*) subname, 'Flux error (W/m^2) =', ferr
    1988            0 :          call icepack_warnings_add(warnstr)
    1989            0 :          write(warnstr,*) subname, 'Energy error (J) =', ferr*dt
    1990            0 :          call icepack_warnings_add(warnstr)
    1991            0 :          write(warnstr,*) subname, 'Initial energy =', einit
    1992            0 :          call icepack_warnings_add(warnstr)
    1993            0 :          write(warnstr,*) subname, 'Final energy   =', efinal
    1994            0 :          call icepack_warnings_add(warnstr)
    1995            0 :          write(warnstr,*) subname, 'efinal - einit  =', efinal-einit
    1996            0 :          call icepack_warnings_add(warnstr)
    1997            0 :          write(warnstr,*) subname, 'fsurfn,flatn,fswint,fhocn, fsnow*Lfresh:'
    1998            0 :          call icepack_warnings_add(warnstr)
    1999            0 :          write(warnstr,*) subname, fsurfn,flatn,fswint,fhocnn, fsnow*Lfresh
    2000            0 :          call icepack_warnings_add(warnstr)
    2001            0 :          write(warnstr,*) subname, 'Input energy =', einp
    2002            0 :          call icepack_warnings_add(warnstr)
    2003            0 :          write(warnstr,*) subname, 'fbot,fcondbot:'
    2004            0 :          call icepack_warnings_add(warnstr)
    2005            0 :          write(warnstr,*) subname, fbot,fcondbotn
    2006            0 :          call icepack_warnings_add(warnstr)
    2007              : 
    2008              :          !         if (ktherm == 2) then
    2009            0 :          write(warnstr,*) subname, 'Intermediate energy =', einter
    2010            0 :          call icepack_warnings_add(warnstr)
    2011            0 :          write(warnstr,*) subname, 'efinal - einter =', &
    2012            0 :               efinal-einter
    2013            0 :          call icepack_warnings_add(warnstr)
    2014            0 :          write(warnstr,*) subname, 'einter - einit  =', &
    2015            0 :               einter-einit
    2016            0 :          call icepack_warnings_add(warnstr)
    2017            0 :          write(warnstr,*) subname, 'Conduction Error =', (einter-einit) &
    2018            0 :               - (fcondtopn*dt - fcondbotn*dt + fswint*dt)
    2019            0 :          call icepack_warnings_add(warnstr)
    2020            0 :          write(warnstr,*) subname, 'Melt/Growth Error =', (einter-einit) &
    2021            0 :               + ferr*dt - (fcondtopn*dt - fcondbotn*dt + fswint*dt)
    2022            0 :          call icepack_warnings_add(warnstr)
    2023            0 :          write(warnstr,*) subname, 'Advection Error =', fadvocn*dt
    2024            0 :          call icepack_warnings_add(warnstr)
    2025              :          !         endif
    2026              : 
    2027              :          !         write(warnstr,*) subname, fsurfn,flatn,fswint,fhocnn
    2028              :          !         call icepack_warnings_add(warnstr)
    2029              : 
    2030            0 :          write(warnstr,*) subname, 'dt*(fsurfn, flatn, fswint, fhocn, fsnow*Lfresh, fadvocn):'
    2031            0 :          call icepack_warnings_add(warnstr)
    2032            0 :          write(warnstr,*) subname, fsurfn*dt, flatn*dt, &
    2033            0 :               fswint*dt, fhocnn*dt, &
    2034            0 :               fsnow*Lfresh*dt, fadvocn*dt
    2035            0 :          call icepack_warnings_add(warnstr)
    2036            0 :          return
    2037              :       endif
    2038              : 
    2039              :       end subroutine conservation_check_vthermo
    2040              : 
    2041              : !=======================================================================
    2042              : !
    2043              : ! Given the vertical thermo state variables (hin, hsn),
    2044              : ! compute the new ice state variables (vicen, vsnon).
    2045              : ! Zero out state variables if ice has melted entirely.
    2046              : !
    2047              : ! authors William H. Lipscomb, LANL
    2048              : !         C. M. Bitz, UW
    2049              : !         Elizabeth C. Hunke, LANL
    2050              : 
    2051      8777938 :       subroutine update_state_vthermo(Tf,       Tsf,      &
    2052              :                                       hin,      hsn,      &
    2053      8777938 :                                       zqin,     zSin,     &
    2054      8777938 :                                       zqsn,               &
    2055              :                                       aicen,    vicen,    &
    2056              :                                       vsnon)
    2057              : 
    2058              :       real (kind=dbl_kind), intent(in) :: &
    2059              :          Tf              ! freezing temperature (C)
    2060              : 
    2061              :       real (kind=dbl_kind), intent(inout) :: &
    2062              :          Tsf             ! ice/snow surface temperature, Tsfcn
    2063              : 
    2064              :       real (kind=dbl_kind), intent(in) :: &
    2065              :          hin         , & ! ice thickness (m)
    2066              :          hsn             ! snow thickness (m)
    2067              : 
    2068              :       real (kind=dbl_kind), dimension (:), intent(inout) :: &
    2069              :          zqin        , & ! ice layer enthalpy (J m-3)
    2070              :          zSin        , & ! ice salinity    (ppt)
    2071              :          zqsn            ! snow layer enthalpy (J m-3)
    2072              : 
    2073              :       real (kind=dbl_kind), intent(inout) :: &
    2074              :          aicen       , & ! concentration of ice
    2075              :          vicen       , & ! volume per unit area of ice          (m)
    2076              :          vsnon           ! volume per unit area of snow         (m)
    2077              : 
    2078              :       ! local variables
    2079              : 
    2080              :       integer (kind=int_kind) :: &
    2081              :          k               ! ice layer index
    2082              : 
    2083              :       character(len=*),parameter :: subname='(update_state_vthermo)'
    2084              : 
    2085      8777938 :       if (hin <= c0) then
    2086            4 :          aicen = c0
    2087            4 :          vicen = c0
    2088            4 :          vsnon = c0
    2089            4 :          Tsf = Tf
    2090           32 :          do k = 1, nilyr
    2091           32 :             zqin(k) = c0
    2092              :          enddo
    2093            4 :          if (ktherm == 2) then
    2094           32 :             do k = 1, nilyr
    2095           32 :                zSin(k) = c0
    2096              :             enddo
    2097              :          endif
    2098            8 :          do k = 1, nslyr
    2099            8 :             zqsn(k) = c0
    2100              :          enddo
    2101              :       else
    2102              :          ! aicen is already up to date
    2103      8777934 :          vicen = aicen * hin
    2104      8777934 :          vsnon = aicen * hsn
    2105              :       endif
    2106              : 
    2107      8777938 :       end subroutine update_state_vthermo
    2108              : 
    2109              : !=======================================================================
    2110              : !autodocument_start icepack_step_therm1
    2111              : ! Driver for thermodynamic changes not needed for coupling:
    2112              : ! transport in thickness space, lateral growth and melting.
    2113              : !
    2114              : ! authors: William H. Lipscomb, LANL
    2115              : !          Elizabeth C. Hunke, LANL
    2116              : 
    2117      2629488 :       subroutine icepack_step_therm1(dt,                        &
    2118            0 :                                     aicen_init  ,               &
    2119      2629488 :                                     vicen_init  , vsnon_init  , &
    2120            0 :                                     aice        , aicen       , &
    2121            0 :                                     vice        , vicen       , &
    2122      2629488 :                                     vsno        , vsnon       , &
    2123              :                                     uvel        , vvel        , &
    2124      5258976 :                                     Tsfc        , zqsn        , &
    2125      5258976 :                                     zqin        , zSin        , &
    2126      5258976 :                                     alvl        , vlvl        , &
    2127      5258976 :                                     apnd        , hpnd        , &
    2128            0 :                                     ipnd        ,               &
    2129      2629488 :                                     iage        , FY          , &
    2130      2629488 :                                     aerosno     , aeroice     , &
    2131      2629488 :                                     isosno      , isoice      , &
    2132              :                                     uatm        , vatm        , &
    2133              :                                     wind        , zlvl        , &
    2134              :                                     Qa          , rhoa        , &
    2135      2629488 :                                     Qa_iso      , &
    2136              :                                     Tair        , Tref        , &
    2137              :                                     Qref        , Uref        , &
    2138      2629488 :                                     Qref_iso    , &
    2139              :                                     Cdn_atm_ratio,              &
    2140              :                                     Cdn_ocn     , Cdn_ocn_skin, &
    2141              :                                     Cdn_ocn_floe, Cdn_ocn_keel, &
    2142              :                                     Cdn_atm     , Cdn_atm_skin, &
    2143              :                                     Cdn_atm_floe, Cdn_atm_pond, &
    2144              :                                     Cdn_atm_rdg , hfreebd     , &
    2145              :                                     hdraft      , hridge      , &
    2146              :                                     distrdg     , hkeel       , &
    2147              :                                     dkeel       , lfloe       , &
    2148              :                                     dfloe       ,               &
    2149              :                                     strax       , stray       , &
    2150              :                                     strairxT    , strairyT    , &
    2151              :                                     potT        , sst         , &
    2152              :                                     sss         , Tf          , &
    2153              :                                     strocnxT    , strocnyT    , &
    2154              :                                     fbot        ,               &
    2155              :                                     Tbot        , Tsnice      , &
    2156      2629488 :                                     frzmlt      , rsiden      , &
    2157              :                                     wlat        ,               &
    2158              :                                     fsnow       , frain       , &
    2159              :                                     fpond       , fsloss      , &
    2160            0 :                                     fsurf       , fsurfn      , &
    2161      2629488 :                                     fcondtop    , fcondtopn   , &
    2162            0 :                                     fcondbot    , fcondbotn   , &
    2163      2629488 :                                     fswsfcn     , fswintn     , &
    2164      2629488 :                                     fswthrun    ,               &
    2165      2629488 :                                     fswthrun_vdr,               &
    2166      2629488 :                                     fswthrun_vdf,               &
    2167      2629488 :                                     fswthrun_idr,               &
    2168      2629488 :                                     fswthrun_idf,               &
    2169              :                                     fswabs      ,               &
    2170              :                                     flwout      ,               &
    2171      2629488 :                                     Sswabsn     , Iswabsn     , &
    2172              :                                     flw         , &
    2173      2629488 :                                     fsens       , fsensn      , &
    2174      2629488 :                                     flat        , flatn       , &
    2175              :                                     evap        ,               &
    2176              :                                     evaps       , evapi       , &
    2177              :                                     fresh       , fsalt       , &
    2178              :                                     fhocn       ,               &
    2179              :                                     fswthru     ,               &
    2180              :                                     fswthru_vdr ,               &
    2181              :                                     fswthru_vdf ,               &
    2182              :                                     fswthru_idr ,               &
    2183              :                                     fswthru_idf ,               &
    2184      2629488 :                                     flatn_f     , fsensn_f    , &
    2185      2629488 :                                     fsurfn_f    , fcondtopn_f , &
    2186      2629488 :                                     faero_atm   , faero_ocn   , &
    2187      2629488 :                                     fiso_atm    , fiso_ocn    , &
    2188      2629488 :                                     fiso_evap   , &
    2189              :                                     HDO_ocn     , H2_16O_ocn  , &
    2190              :                                     H2_18O_ocn  ,  &
    2191      2629488 :                                     dhsn        , ffracn      , &
    2192            0 :                                     meltt       , melttn      , &
    2193      2629488 :                                     meltb       , meltbn      , &
    2194      2629488 :                                     melts       , meltsn      , &
    2195      2629488 :                                     congel      , congeln     , &
    2196      2629488 :                                     snoice      , snoicen     , &
    2197      2629488 :                                     dsnow       , dsnown      , &
    2198      2629488 :                                     meltsliq    , meltsliqn   , &
    2199      2629488 :                                     rsnwn       , &
    2200      2629488 :                                     smicen      , smliqn      , &
    2201              :                                     lmask_n     , lmask_s     , &
    2202              :                                     mlt_onset   , frz_onset   , &
    2203              :                                     yday        , prescribed_ice, &
    2204      2629488 :                                     zlvs        , afsdn)
    2205              : 
    2206              :       real (kind=dbl_kind), intent(in) :: &
    2207              :          dt          , & ! time step
    2208              :          uvel        , & ! x-component of velocity              (m/s)
    2209              :          vvel        , & ! y-component of velocity              (m/s)
    2210              :          strax       , & ! wind stress components             (N/m^2)
    2211              :          stray       , & !
    2212              :          yday            ! day of year
    2213              : 
    2214              :       logical (kind=log_kind), intent(in) :: &
    2215              :          lmask_n     , & ! northern hemisphere mask
    2216              :          lmask_s         ! southern hemisphere mask
    2217              : 
    2218              :       logical (kind=log_kind), intent(in), optional :: &
    2219              :          prescribed_ice  ! if .true., use prescribed ice instead of computed
    2220              : 
    2221              :       real (kind=dbl_kind), intent(inout) :: &
    2222              :          aice        , & ! sea ice concentration
    2223              :          vice        , & ! volume per unit area of ice            (m)
    2224              :          vsno        , & ! volume per unit area of snow           (m)
    2225              :          zlvl        , & ! atm level height for momentum (and scalars if zlvs is not present) (m)
    2226              :          uatm        , & ! wind velocity components             (m/s)
    2227              :          vatm        , & !                                      (m/s)
    2228              :          wind        , & ! wind speed                           (m/s)
    2229              :          potT        , & ! air potential temperature              (K)
    2230              :          Tair        , & ! air temperature                        (K)
    2231              :          Qa          , & ! specific humidity                  (kg/kg)
    2232              :          rhoa        , & ! air density                       (kg/m^3)
    2233              :          frain       , & ! rainfall rate                   (kg/m^2 s)
    2234              :          fsnow       , & ! snowfall rate                   (kg/m^2 s)
    2235              :          fpond       , & ! fresh water flux to ponds       (kg/m^2/s)
    2236              :          fresh       , & ! fresh water flux to ocean       (kg/m^2/s)
    2237              :          fsalt       , & ! salt flux to ocean              (kg/m^2/s)
    2238              :          fhocn       , & ! net heat flux to ocean             (W/m^2)
    2239              :          fswthru     , & ! shortwave penetrating to ocean     (W/m^2)
    2240              :          fsurf       , & ! net surface heat flux (excluding fcondtop)(W/m^2)
    2241              :          fcondtop    , & ! top surface conductive flux        (W/m^2)
    2242              :          fcondbot    , & ! bottom surface conductive flux     (W/m^2)
    2243              :          fsens       , & ! sensible heat flux                 (W/m^2)
    2244              :          flat        , & ! latent heat flux                   (W/m^2)
    2245              :          fswabs      , & ! shortwave flux absorbed in ice and ocean (W/m^2)
    2246              :          flw         , & ! incoming longwave radiation        (W/m^2)
    2247              :          flwout      , & ! outgoing longwave radiation        (W/m^2)
    2248              :          evap        , & ! evaporative water flux          (kg/m^2/s)
    2249              :          evaps       , & ! evaporative water flux over snow(kg/m^2/s)
    2250              :          evapi       , & ! evaporative water flux over ice (kg/m^2/s)
    2251              :          congel      , & ! basal ice growth         (m/step-->cm/day)
    2252              :          snoice      , & ! snow-ice formation       (m/step-->cm/day)
    2253              :          Tref        , & ! 2m atm reference temperature           (K)
    2254              :          Qref        , & ! 2m atm reference spec humidity     (kg/kg)
    2255              :          Uref        , & ! 10m atm reference wind speed         (m/s)
    2256              :          Cdn_atm     , & ! atm drag coefficient
    2257              :          Cdn_ocn     , & ! ocn drag coefficient
    2258              :          hfreebd     , & ! freeboard                              (m)
    2259              :          hdraft      , & ! draft of ice + snow column (Stoessel1993)
    2260              :          hridge      , & ! ridge height
    2261              :          distrdg     , & ! distance between ridges
    2262              :          hkeel       , & ! keel depth
    2263              :          dkeel       , & ! distance between keels
    2264              :          lfloe       , & ! floe length
    2265              :          dfloe       , & ! distance between floes
    2266              :          Cdn_atm_skin, & ! neutral skin drag coefficient
    2267              :          Cdn_atm_floe, & ! neutral floe edge drag coefficient
    2268              :          Cdn_atm_pond, & ! neutral pond edge drag coefficient
    2269              :          Cdn_atm_rdg , & ! neutral ridge drag coefficient
    2270              :          Cdn_ocn_skin, & ! skin drag coefficient
    2271              :          Cdn_ocn_floe, & ! floe edge drag coefficient
    2272              :          Cdn_ocn_keel, & ! keel drag coefficient
    2273              :          Cdn_atm_ratio,& ! ratio drag atm / neutral drag atm
    2274              :          strairxT    , & ! stress on ice by air, x-direction
    2275              :          strairyT    , & ! stress on ice by air, y-direction
    2276              :          strocnxT    , & ! ice-ocean stress, x-direction
    2277              :          strocnyT    , & ! ice-ocean stress, y-direction
    2278              :          fbot        , & ! ice-ocean heat flux at bottom surface (W/m^2)
    2279              :          frzmlt      , & ! freezing/melting potential         (W/m^2)
    2280              :          sst         , & ! sea surface temperature                (C)
    2281              :          Tf          , & ! freezing temperature                   (C)
    2282              :          Tbot        , & ! ice bottom surface temperature     (deg C)
    2283              :          Tsnice      , & ! snow ice interface temperature     (deg C)
    2284              :          sss         , & ! sea surface salinity                 (ppt)
    2285              :          meltt       , & ! top ice melt             (m/step-->cm/day)
    2286              :          melts       , & ! snow melt                (m/step-->cm/day)
    2287              :          meltb       , & ! basal ice melt           (m/step-->cm/day)
    2288              :          mlt_onset   , & ! day of year that sfc melting begins
    2289              :          frz_onset       ! day of year that freezing begins (congel or frazil)
    2290              : 
    2291              :       real (kind=dbl_kind), intent(out), optional :: &
    2292              :          wlat            ! lateral melt rate (m/s)
    2293              : 
    2294              :       real (kind=dbl_kind), intent(inout), optional :: &
    2295              :          fswthru_vdr , & ! vis dir shortwave penetrating to ocean (W/m^2)
    2296              :          fswthru_vdf , & ! vis dif shortwave penetrating to ocean (W/m^2)
    2297              :          fswthru_idr , & ! nir dir shortwave penetrating to ocean (W/m^2)
    2298              :          fswthru_idf , & ! nir dif shortwave penetrating to ocean (W/m^2)
    2299              :          dsnow       , & ! change in snow depth     (m/step-->cm/day)
    2300              :          fsloss          ! rate of snow loss to leads      (kg/m^2/s)
    2301              : 
    2302              :       real (kind=dbl_kind), intent(out), optional :: &
    2303              :          meltsliq        ! mass of snow melt                 (kg/m^2)
    2304              : 
    2305              :       real (kind=dbl_kind), dimension(:), intent(inout), optional :: &
    2306              :          Qa_iso      , & ! isotope specific humidity          (kg/kg)
    2307              :          Qref_iso    , & ! isotope 2m atm ref spec humidity   (kg/kg)
    2308              :          fiso_atm    , & ! isotope deposition rate         (kg/m^2 s)
    2309              :          fiso_ocn    , & ! isotope flux to ocean           (kg/m^2/s)
    2310              :          fiso_evap       ! isotope evaporation             (kg/m^2/s)
    2311              : 
    2312              :       real (kind=dbl_kind), dimension(:), intent(inout), optional :: &
    2313              :          meltsliqn       ! mass of snow melt                 (kg/m^2)
    2314              : 
    2315              :       real (kind=dbl_kind), dimension(:,:), intent(inout), optional :: &
    2316              :          rsnwn       , & ! snow grain radius                (10^-6 m)
    2317              :          smicen      , & ! tracer for mass of ice in snow    (kg/m^3)
    2318              :          smliqn          ! tracer for mass of liq in snow    (kg/m^3)
    2319              : 
    2320              :       real (kind=dbl_kind), intent(in), optional :: &
    2321              :          HDO_ocn     , & ! ocean concentration of HDO         (kg/kg)
    2322              :          H2_16O_ocn  , & ! ocean concentration of H2_16O      (kg/kg)
    2323              :          H2_18O_ocn  , & ! ocean concentration of H2_18O      (kg/kg)
    2324              :          zlvs            ! atm level height for scalars (if different than zlvl) (m)
    2325              : 
    2326              :       real (kind=dbl_kind), dimension(:,:), intent(in), optional :: &
    2327              :          afsdn        ! afsd tracer
    2328              : 
    2329              :       real (kind=dbl_kind), dimension(:), intent(inout) :: &
    2330              :          aicen_init  , & ! fractional area of ice
    2331              :          vicen_init  , & ! volume per unit area of ice            (m)
    2332              :          vsnon_init  , & ! volume per unit area of snow           (m)
    2333              :          aicen       , & ! concentration of ice
    2334              :          vicen       , & ! volume per unit area of ice            (m)
    2335              :          vsnon       , & ! volume per unit area of snow           (m)
    2336              :          Tsfc        , & ! ice/snow surface temperature, Tsfcn
    2337              :          alvl        , & ! level ice area fraction
    2338              :          vlvl        , & ! level ice volume fraction
    2339              :          apnd        , & ! melt pond area fraction tracer
    2340              :          hpnd        , & ! melt pond depth                        (m)
    2341              :          ipnd        , & ! melt pond refrozen lid thickness       (m)
    2342              :          iage        , & ! volume-weighted ice age
    2343              :          FY          , & ! area-weighted first-year ice area
    2344              :          rsiden      , & ! fraction of ice that melts laterally
    2345              :          fsurfn      , & ! net flux to top surface, excluding fcondtop
    2346              :          fcondtopn   , & ! downward cond flux at top surface  (W m-2)
    2347              :          fcondbotn   , & ! downward cond flux at bottom surface (W m-2)
    2348              :          flatn       , & ! latent heat flux                   (W m-2)
    2349              :          fsensn      , & ! sensible heat flux                 (W m-2)
    2350              :          fsurfn_f    , & ! net flux to top surface, excluding fcondtop
    2351              :          fcondtopn_f , & ! downward cond flux at top surface  (W m-2)
    2352              :          flatn_f     , & ! latent heat flux                   (W m-2)
    2353              :          fsensn_f    , & ! sensible heat flux                 (W m-2)
    2354              :          fswsfcn     , & ! SW absorbed at ice/snow surface    (W m-2)
    2355              :          fswintn     , & ! SW absorbed in ice interior, below surface (W m-2)
    2356              :          faero_atm   , & ! aerosol deposition rate         (kg/m^2 s)
    2357              :          faero_ocn   , & ! aerosol flux to ocean           (kg/m^2/s)
    2358              :          dhsn        , & ! depth difference for snow on sea ice and pond ice
    2359              :          ffracn      , & ! fraction of fsurfn used to melt ipond
    2360              :          meltsn      , & ! snow melt                              (m)
    2361              :          melttn      , & ! top ice melt                           (m)
    2362              :          meltbn      , & ! bottom ice melt                        (m)
    2363              :          congeln     , & ! congelation ice growth                 (m)
    2364              :          snoicen         ! snow-ice growth                        (m)
    2365              : 
    2366              :       real (kind=dbl_kind), dimension(:), intent(in) :: &
    2367              :          fswthrun        ! SW through ice to ocean            (W/m^2)
    2368              : 
    2369              :       real (kind=dbl_kind), dimension(:), intent(inout), optional :: &
    2370              :          dsnown          ! change in snow thickness (m/step-->cm/day)
    2371              : 
    2372              :       real (kind=dbl_kind), dimension(:), intent(in), optional :: &
    2373              :          fswthrun_vdr , & ! vis dir SW through ice to ocean   (W/m^2)
    2374              :          fswthrun_vdf , & ! vis dif SW through ice to ocean   (W/m^2)
    2375              :          fswthrun_idr , & ! nir dir SW through ice to ocean   (W/m^2)
    2376              :          fswthrun_idf     ! nir dif SW through ice to ocean   (W/m^2)
    2377              : 
    2378              :       real (kind=dbl_kind), dimension(:,:), intent(inout) :: &
    2379              :          zqsn        , & ! snow layer enthalpy                (J m-3)
    2380              :          zqin        , & ! ice layer enthalpy                 (J m-3)
    2381              :          zSin        , & ! internal ice layer salinities
    2382              :          Sswabsn     , & ! SW radiation absorbed in snow layers (W m-2)
    2383              :          Iswabsn         ! SW radiation absorbed in ice layers  (W m-2)
    2384              : 
    2385              :       real (kind=dbl_kind), dimension(:,:,:), intent(inout) :: &
    2386              :          aerosno    , &  ! snow aerosol tracer               (kg/m^2)
    2387              :          aeroice         ! ice aerosol tracer                (kg/m^2)
    2388              : 
    2389              :       real (kind=dbl_kind), dimension(:,:), intent(inout), optional :: &
    2390              :          isosno     , &  ! snow isotope tracer               (kg/m^2)
    2391              :          isoice          ! ice isotope tracer                (kg/m^2)
    2392              : !autodocument_end
    2393              : 
    2394              :       ! local variables
    2395              : 
    2396              :       integer (kind=int_kind) :: &
    2397              :          k           , & ! layer index
    2398              :          n               ! category index
    2399              : 
    2400              :       real (kind=dbl_kind) :: &
    2401              :          worka       , &   ! temporary variables
    2402              :          workb       , &
    2403              :          workc
    2404              : 
    2405              :       ! 2D coupler variables (computed for each category, then aggregated)
    2406              :       real (kind=dbl_kind) :: &
    2407              :          fswabsn     , & ! shortwave absorbed by ice          (W/m^2)
    2408              :          flwoutn     , & ! upward LW at surface               (W/m^2)
    2409              :          evapn       , & ! flux of vapor, atmos to ice   (kg m-2 s-1)
    2410              :          evapsn      , & ! flux of vapor, atmos to ice over snow (kg m-2 s-1)
    2411              :          evapin      , & ! flux of vapor, atmos to ice over ice  (kg m-2 s-1)
    2412              :          freshn      , & ! flux of water, ice to ocean     (kg/m^2/s)
    2413              :          fsaltn      , & ! flux of salt, ice to ocean      (kg/m^2/s)
    2414              :          fhocnn      , & ! fbot corrected for leftover energy (W/m^2)
    2415              :          strairxn    , & ! air/ice zonal  stress,             (N/m^2)
    2416              :          strairyn    , & ! air/ice meridional stress,         (N/m^2)
    2417              :          Cdn_atm_ratio_n, & ! drag coefficient ratio
    2418              :          Trefn       , & ! air tmp reference level                (K)
    2419              :          Urefn       , & ! air speed reference level            (m/s)
    2420              :          Qrefn       , & ! air sp hum reference level         (kg/kg)
    2421              :          shcoef      , & ! transfer coefficient for sensible heat
    2422              :          lhcoef      , & ! transfer coefficient for latent heat
    2423              :          rfrac           ! water fraction retained for melt ponds
    2424              : 
    2425              :       real (kind=dbl_kind), dimension(nslyr,ncat) :: &
    2426      5258976 :          massicen    , & ! mass of ice in snow               (kg/m^2)
    2427      5258976 :          massliqn        ! mass of liquid in snow            (kg/m^2)
    2428              : 
    2429              :       real (kind=dbl_kind), dimension(n_iso) :: &
    2430      5258976 :          Qrefn_iso   , & ! isotope air sp hum reference level (kg/kg)
    2431      5258976 :          fiso_ocnn   , & ! isotope flux to ocean           (kg/m^2/s)
    2432      5258976 :          fiso_evapn      ! isotope evaporation             (kg/m^2/s)
    2433              : 
    2434              :       real (kind=dbl_kind), dimension(nslyr) :: &
    2435      5258976 :          rsnw        , & ! snow grain radius                (10^-6 m)
    2436      5258976 :          smice       , & ! tracer for mass of ice in snow    (kg/m^3)
    2437      5258976 :          smliq           ! tracer for mass of liquid in snow (kg/m^3)
    2438              : 
    2439              :       real (kind=dbl_kind), dimension(ncat) :: &
    2440      7888464 :          apond       , & ! melt pond area fraction of category
    2441      2629488 :          l_meltsliqn     ! mass of snow melt local           (kg/m^2)
    2442              : 
    2443              :       real (kind=dbl_kind) :: &
    2444              :          l_fswthrun_vdr, & ! vis dir SW local n ice to ocean  (W/m^2)
    2445              :          l_fswthrun_vdf, & ! vis dif SW local n ice to ocean  (W/m^2)
    2446              :          l_fswthrun_idr, & ! nir dir SW local n ice to ocean  (W/m^2)
    2447              :          l_fswthrun_idf, & ! nir dif SW local n ice to ocean  (W/m^2)
    2448              :          l_dsnow,        & ! local snow change
    2449              :          l_dsnown,       & ! local snow change category
    2450              :          l_meltsliq      ! mass of snow melt local           (kg/m^2)
    2451              : 
    2452              :       real (kind=dbl_kind) :: &
    2453              :          pond            ! water retained in ponds                (m)
    2454              : 
    2455              :       logical (kind=log_kind), save :: &
    2456              :          first_call = .true. ! first call flag
    2457              : 
    2458              :       character(len=*),parameter :: subname='(icepack_step_therm1)'
    2459              : 
    2460              :       !-----------------------------------------------------------------
    2461              :       ! check optional arguments
    2462              :       !-----------------------------------------------------------------
    2463              : 
    2464      2629488 :       if (icepack_chkoptargflag(first_call)) then
    2465           83 :          if (tr_iso) then
    2466            2 :             if (.not.(present(isosno)   .and. present(isoice)     .and. &
    2467              :                       present(fiso_atm) .and. present(fiso_ocn)   .and. &
    2468              :                       present(fiso_evap).and.                           &
    2469              :                       present(Qa_iso)   .and. present(Qref_iso)   .and. &
    2470              :                       present(HDO_ocn)  .and. present(H2_16O_ocn) .and. &
    2471              :                       present(H2_18O_ocn))) then
    2472            0 :                call icepack_warnings_add(subname//' error in iso arguments, tr_iso=T')
    2473            0 :                call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    2474            0 :                return
    2475              :             endif
    2476              :          endif
    2477           83 :          if (snwgrain) then
    2478           11 :             if (.not.(present(rsnwn)  .and.                  &
    2479              :                       present(smicen) .and. present(smliqn))) then
    2480            0 :                call icepack_warnings_add(subname//' error in snw arguments, snwgrain=T')
    2481            0 :                call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    2482            0 :                return
    2483              :             endif
    2484              :          endif
    2485              :          if ((present(fswthru_vdr) .and. .not.present(fswthrun_vdr)) .or. &
    2486              :              (present(fswthru_vdf) .and. .not.present(fswthrun_vdf)) .or. &
    2487           83 :              (present(fswthru_idr) .and. .not.present(fswthrun_idr)) .or. &
    2488              :              (present(fswthru_idf) .and. .not.present(fswthrun_idf))) then
    2489            0 :             call icepack_warnings_add(subname//' error in fswthru [iv]d[rf] arguments')
    2490            0 :             call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    2491            0 :             return
    2492              :          endif
    2493           83 :          if ((present(dsnow) .and. .not.present(dsnown)) .or. &
    2494              :              (present(dsnown) .and. .not.present(dsnow))) then
    2495            0 :             call icepack_warnings_add(subname//' error in dsnow arguments')
    2496            0 :             call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    2497            0 :             return
    2498              :          endif
    2499           83 :          if (tr_fsd) then
    2500            4 :             if (.not.present(afsdn)) then
    2501            0 :                call icepack_warnings_add(subname//' error missing afsdn argument, tr_fsd=T')
    2502            0 :                call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    2503            0 :                return
    2504              :             endif
    2505            4 :             if (size(afsdn,dim=1) /= nfsd .or. size(afsdn,dim=2) /= ncat) then
    2506            0 :                call icepack_warnings_add(subname//' error size of afsdn argument, tr_fsd=T')
    2507            0 :                call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    2508            0 :                return
    2509              :             endif
    2510              :          endif
    2511              :       endif
    2512              : 
    2513              :       !-----------------------------------------------------------------
    2514              :       ! allocate local optional arguments
    2515              :       !-----------------------------------------------------------------
    2516              : 
    2517      7002144 :       rsnw (:) = c0
    2518      7002144 :       smice(:) = c0
    2519      7002144 :       smliq(:) = c0
    2520              : 
    2521      2629488 :       l_meltsliq  = c0
    2522     15390816 :       l_meltsliqn = c0
    2523      2629488 :       l_dsnow     = c0
    2524      2629488 :       if (present(dsnow)) l_dsnow = dsnow
    2525              : 
    2526              :       ! solid and liquid components of snow mass
    2527     36867984 :       massicen(:,:) = c0
    2528     36867984 :       massliqn(:,:) = c0
    2529              : 
    2530              :       !-----------------------------------------------------------------
    2531              :       ! Initialize pond area fractions
    2532              :       !-----------------------------------------------------------------
    2533     15390816 :       do n= 1, ncat    
    2534     15390816 :          if (tr_pond_lvl) then
    2535     10909440 :             apond(n) = apnd(n) * alvl(n)
    2536              :          else
    2537      1851888 :             apond(n) = apnd(n)
    2538              :          endif
    2539              :       enddo
    2540              : 
    2541              :       !-----------------------------------------------------------------
    2542              :       ! Initialize rate of snow loss to leads
    2543              :       !-----------------------------------------------------------------
    2544              : 
    2545      2629488 :       if (present(fsloss)) &
    2546      2629488 :          fsloss = fsnow * (c1 - aice)
    2547              : 
    2548              :       !-----------------------------------------------------------------
    2549              :       ! snow redistribution using snwlvlfac:  precip factor
    2550              :       !-----------------------------------------------------------------
    2551              : 
    2552      2629488 :       if (trim(snwredist) == 'bulk') then
    2553        35040 :          worka = c0
    2554        35040 :          if (aice > puny) then
    2555       157644 :             do n = 1, ncat
    2556       157644 :                worka = worka + alvl(n)*aicen(n)
    2557              :             enddo
    2558        26274 :             worka  = worka * (snwlvlfac/(c1+snwlvlfac)) / aice
    2559              :          endif
    2560        35040 :          if (present(fsloss)) &
    2561        35040 :             fsloss = fsloss + fsnow*    worka
    2562        35040 :          fsnow    =           fsnow*(c1-worka)
    2563              :       endif ! snwredist
    2564              : 
    2565              :       !-----------------------------------------------------------------
    2566              :       ! Update the neutral drag coefficients to account for form drag
    2567              :       ! Oceanic and atmospheric drag coefficients
    2568              :       !-----------------------------------------------------------------
    2569              : 
    2570      2629488 :       if (formdrag) then
    2571              :          call neutral_drag_coeffs (apond       , &
    2572              :                                    alvl        , vlvl         , &
    2573              :                                    aice        , vice,          &
    2574              :                                    vsno        , aicen        , &
    2575              :                                    vicen       , &
    2576              :                                    Cdn_ocn     , Cdn_ocn_skin, &
    2577              :                                    Cdn_ocn_floe, Cdn_ocn_keel, &
    2578              :                                    Cdn_atm     , Cdn_atm_skin, &
    2579              :                                    Cdn_atm_floe, Cdn_atm_pond, &
    2580              :                                    Cdn_atm_rdg , hfreebd     , &
    2581              :                                    hdraft      , hridge      , &
    2582              :                                    distrdg     , hkeel       , &
    2583              :                                    dkeel       , lfloe       , &
    2584        96528 :                                    dfloe)
    2585        96528 :          if (icepack_warnings_aborted(subname)) return
    2586              :       endif
    2587              : 
    2588              :       !-----------------------------------------------------------------
    2589              :       ! Use frzmlt to account for ice-ocean heat fluxes since last
    2590              :       !  call to coupler.
    2591              :       ! Compute lateral and bottom heat fluxes.
    2592              :       !-----------------------------------------------------------------
    2593              : 
    2594              :       call frzmlt_bottom_lateral (dt,                   &
    2595              :                                   aice,      frzmlt,    &
    2596              :                                   vicen,     vsnon,     &
    2597              :                                   zqin,      zqsn,      &
    2598              :                                   sst,       Tf,        &
    2599              :                                   ustar_min,            &
    2600              :                                   fbot_xfer_type,       &
    2601              :                                   strocnxT,  strocnyT,  &
    2602              :                                   Tbot,      fbot,      &
    2603              :                                   rsiden,    Cdn_ocn,   &
    2604              :                                   wlat,      aicen,     &
    2605      2629488 :                                   afsdn)
    2606              : 
    2607      2629488 :       if (icepack_warnings_aborted(subname)) return
    2608              : 
    2609     15390816 :       do n = 1, ncat
    2610     12761328 :          meltsn (n) = c0
    2611     12761328 :          melttn (n) = c0
    2612     12761328 :          meltbn (n) = c0
    2613     12761328 :          congeln(n) = c0
    2614     12761328 :          snoicen(n) = c0
    2615     12761328 :          l_dsnown   = c0
    2616              : 
    2617     12761328 :          Trefn  = c0
    2618     12761328 :          Qrefn  = c0
    2619     13683648 :          Qrefn_iso(:) = c0
    2620     13683648 :          fiso_ocnn(:) = c0
    2621     13683648 :          fiso_evapn(:) = c0
    2622     12761328 :          Urefn  = c0
    2623     12761328 :          lhcoef = c0
    2624     12761328 :          shcoef = c0
    2625     12761328 :          worka  = c0
    2626     12761328 :          workb  = c0
    2627              : 
    2628     12761328 :          if (aicen_init(n) > puny) then
    2629              : 
    2630      8777938 :             if (calc_Tsfc .or. calc_strair) then
    2631              : 
    2632              :       !-----------------------------------------------------------------
    2633              :       ! Atmosphere boundary layer calculation; compute coefficients
    2634              :       ! for sensible and latent heat fluxes.
    2635              :       !
    2636              :       ! NOTE: The wind stress is computed here for later use if
    2637              :       !       calc_strair = .true.   Otherwise, the wind stress
    2638              :       !       components are set to the data values.
    2639              :       !-----------------------------------------------------------------
    2640              : 
    2641              :                call icepack_atm_boundary('ice',                  &
    2642              :                                         Tsfc(n),  potT,          &
    2643              :                                         uatm,     vatm,          &
    2644              :                                         wind,     zlvl,          &
    2645              :                                         Qa,       rhoa,          &
    2646              :                                         strairxn, strairyn,      &
    2647              :                                         Trefn,    Qrefn,         &
    2648              :                                         worka,    workb,         &
    2649              :                                         lhcoef,   shcoef,        &
    2650              :                                         Cdn_atm,                 &
    2651              :                                         Cdn_atm_ratio_n,         &
    2652              :                                         Qa_iso=Qa_iso,           &
    2653              :                                         Qref_iso=Qrefn_iso,      &
    2654              :                                         uvel=uvel, vvel=vvel,    &
    2655      8777938 :                                         Uref=Urefn, zlvs=zlvs)
    2656      8777938 :                if (icepack_warnings_aborted(subname)) return
    2657              : 
    2658              :             endif   ! calc_Tsfc or calc_strair
    2659              : 
    2660      8777938 :             if (.not.(calc_strair)) then
    2661              : #ifndef CICE_IN_NEMO
    2662              :                ! Set to data values (on T points)
    2663            0 :                strairxn = strax
    2664            0 :                strairyn = stray
    2665              : #else
    2666              :                ! NEMO wind stress is supplied on u grid, multipied
    2667              :                ! by ice concentration and set directly in evp, so
    2668              :                ! strairxT/yT = 0. Zero u-components here for safety.
    2669              :                strairxn = c0
    2670              :                strairyn = c0
    2671              : #endif
    2672              :             endif
    2673              : 
    2674              :       !-----------------------------------------------------------------
    2675              :       ! Update ice age
    2676              :       ! This is further adjusted for freezing in the thermodynamics.
    2677              :       ! Melting does not alter the ice age.
    2678              :       !-----------------------------------------------------------------
    2679              : 
    2680      8777938 :             if (tr_iage) call increment_age (dt, iage(n))
    2681      8777938 :             if (icepack_warnings_aborted(subname)) return
    2682      8777938 :             if (tr_FY)   call update_FYarea (dt,               &
    2683              :                                              lmask_n, lmask_s, &
    2684       534159 :                                              yday,    FY(n))
    2685      8777938 :             if (icepack_warnings_aborted(subname)) return
    2686              : 
    2687              :       !-----------------------------------------------------------------
    2688              :       ! Vertical thermodynamics: Heat conduction, growth and melting.
    2689              :       !-----------------------------------------------------------------
    2690              : 
    2691      8777938 :             if (.not.(calc_Tsfc)) then
    2692              : 
    2693              :                ! If not calculating surface temperature and fluxes, set
    2694              :                ! surface fluxes (flatn, fsurfn, and fcondtopn) to be used
    2695              :                ! in thickness_changes
    2696              : 
    2697              :                ! hadgem routine sets fluxes to default values in ice-only mode
    2698              :                call set_sfcflux(aicen      (n),                 &
    2699              :                                 flatn_f    (n), fsensn_f   (n), &
    2700              :                                 fcondtopn_f(n),                 &
    2701              :                                 fsurfn_f   (n),                 &
    2702              :                                 flatn      (n), fsensn     (n), &
    2703              :                                 fsurfn     (n),                 &
    2704            0 :                                 fcondtopn  (n))
    2705            0 :                if (icepack_warnings_aborted(subname)) return
    2706              :             endif
    2707              : 
    2708      8777938 :             if (snwgrain) then
    2709      5311734 :                rsnw (:) = rsnwn (:,n)
    2710      5311734 :                smice(:) = smicen(:,n)
    2711      5311734 :                smliq(:) = smliqn(:,n)
    2712              :             endif
    2713              : 
    2714              :             call thermo_vertical(dt=dt,               aicen=aicen         (n), &
    2715              :                                  vicen=vicen     (n), vsnon=vsnon         (n), &
    2716              :                                  Tsf=Tsfc        (n), zSin=zSin         (:,n), &
    2717              :                                  zqin=zqin     (:,n), zqsn=zqsn         (:,n), &
    2718              :                                  apond=apond     (n), hpond=hpnd          (n), &
    2719              :                                  flw=flw,             potT=potT,               &
    2720              :                                  Qa=Qa,               rhoa=rhoa,               &
    2721              :                                  fsnow=fsnow,         fpond=fpond,             &
    2722              :                                  fbot=fbot,           Tbot=Tbot,               &
    2723              :                                  Tsnice=Tsnice,       sss=sss,                 &
    2724              :                                  sst=sst,             rsnw=rsnw,               &
    2725              :                                  lhcoef=lhcoef,       shcoef=shcoef,           &
    2726              :                                  fswsfc=fswsfcn  (n), fswint=fswintn      (n), &
    2727              :                                  Sswabs=Sswabsn(:,n), Iswabs=Iswabsn    (:,n), &
    2728              :                                  fsurfn=fsurfn   (n), fcondtopn=fcondtopn (n), &
    2729              :                                                       fcondbotn=fcondbotn (n), &
    2730              :                                  fsensn=fsensn   (n), flatn=flatn         (n), &
    2731              :                                  flwoutn=flwoutn,     evapn=evapn,             &
    2732              :                                  evapsn=evapsn,       evapin=evapin,           &
    2733              :                                  freshn=freshn,       fsaltn=fsaltn,           &
    2734              :                                  fhocnn=fhocnn,       frain=frain,             &
    2735              :                                  meltt=melttn    (n), melts=meltsn        (n), &
    2736              :                                  meltb=meltbn    (n), meltsliq=l_meltsliqn(n), &
    2737              :                                  smice=smice,         massice=massicen  (:,n), &
    2738              :                                  smliq=smliq,         massliq=massliqn  (:,n), &
    2739              :                                  congel=congeln  (n), snoice=snoicen      (n), &
    2740              :                                  mlt_onset=mlt_onset, frz_onset=frz_onset    , &
    2741              :                                  yday=yday,           dsnow=l_dsnown         , &
    2742      8777938 :                                  prescribed_ice=prescribed_ice)
    2743              : 
    2744      8777938 :             if (icepack_warnings_aborted(subname)) then
    2745            0 :                write(warnstr,*) subname, ' ice: Vertical thermo error, cat ', n
    2746            0 :                call icepack_warnings_add(warnstr)
    2747            0 :                return
    2748              :             endif
    2749              : 
    2750              :             ! Translate changes in apond into apnd tracer
    2751      8777938 :             if (tr_pond_lvl) then
    2752      7684989 :                if (alvl(n) > puny) then
    2753      7244507 :                   apnd(n) = max(apond(n) / alvl(n), c1)
    2754              :                else
    2755       440482 :                   apnd(n) = c0
    2756              :                endif
    2757              :             else
    2758      1092949 :                apnd(n) = apond(n)
    2759              :             endif
    2760              : 
    2761      8777938 :             if (snwgrain) then
    2762      5311734 :                rsnwn (:,n) = rsnw (:)
    2763      5311734 :                smicen(:,n) = smice(:)
    2764      5311734 :                smliqn(:,n) = smliq(:)
    2765              :             endif
    2766              : 
    2767              :       !-----------------------------------------------------------------
    2768              :       ! Total absorbed shortwave radiation
    2769              :       !-----------------------------------------------------------------
    2770              : 
    2771      8777938 :             fswabsn = fswsfcn(n) + fswintn(n) + fswthrun(n)
    2772              : 
    2773              :       !-----------------------------------------------------------------
    2774              :       ! Aerosol update
    2775              :       !-----------------------------------------------------------------
    2776              : 
    2777      8777938 :             if (tr_aero) then
    2778              :                call update_aerosol (dt,                             &
    2779              :                                     melttn     (n), meltsn     (n), &
    2780              :                                     meltbn     (n), congeln    (n), &
    2781              :                                     snoicen    (n), fsnow,          &
    2782              :                                     aerosno(:,:,n), aeroice(:,:,n), &
    2783              :                                     aicen_init (n), vicen_init (n), &
    2784              :                                     vsnon_init (n),                 &
    2785              :                                     vicen      (n), vsnon      (n), &
    2786              :                                     aicen      (n),                 &
    2787       351672 :                                     faero_atm     ,  faero_ocn)
    2788       351672 :                if (icepack_warnings_aborted(subname)) return
    2789              :             endif
    2790              : 
    2791      8777938 :             if (tr_iso) then
    2792              :                call update_isotope (dt = dt, &
    2793              :                                     meltt = melttn(n),melts = meltsn(n),   &
    2794              :                                     meltb = meltbn(n),congel=congeln(n),   &
    2795              :                                     snoice=snoicen(n),evap=evapn,          &
    2796              :                                     fsnow=fsnow,      Tsfc=Tsfc(n),        &
    2797              :                                     Qref_iso=Qrefn_iso(:),                 &
    2798              :                                     isosno=isosno(:,n),isoice=isoice(:,n), &
    2799              :                                     aice_old=aicen_init(n),                &
    2800              :                                     vice_old=vicen_init(n),                &
    2801              :                                     vsno_old=vsnon_init(n),                &
    2802              :                                     vicen=vicen(n),                        &
    2803              :                                     vsnon=vsnon(n),                        &
    2804              :                                     aicen=aicen(n),                        &
    2805              :                                     fiso_atm=fiso_atm(:),                  &
    2806              :                                     fiso_evapn=fiso_evapn(:),              &
    2807              :                                     fiso_ocnn=fiso_ocnn(:),                &
    2808              :                                     HDO_ocn=HDO_ocn,                       &
    2809              :                                     H2_16O_ocn=H2_16O_ocn,                 &
    2810       225452 :                                     H2_18O_ocn=H2_18O_ocn)
    2811       225452 :                if (icepack_warnings_aborted(subname)) return
    2812              :             endif
    2813              : 
    2814              :          endif   ! aicen_init
    2815              : 
    2816     12761328 :          if (snwgrain) then
    2817              :             call drain_snow (vsnon = vsnon(n), &
    2818              :                              aicen = aicen(n), &
    2819              :                              massice = massicen(:,n), &
    2820              :                              massliq = massliqn(:,n), &
    2821      1521120 :                              meltsliq = l_meltsliqn(n))
    2822      1521120 :             if (icepack_warnings_aborted(subname)) return
    2823              :          endif
    2824              : 
    2825              :       !-----------------------------------------------------------------
    2826              :       ! Melt ponds
    2827              :       ! If using tr_pond_topo, the rest of the calculation is done after
    2828              :       ! the surface fluxes are merged, below.
    2829              :       !-----------------------------------------------------------------
    2830              : 
    2831              :          !call ice_timer_start(timer_ponds)
    2832     12761328 :          if (tr_pond) then
    2833              : 
    2834     11699520 :             if (tr_pond_lvl) then
    2835     10909440 :                rfrac = rfracmin + (rfracmax-rfracmin) * aicen(n)
    2836              :                call compute_ponds_lvl (dt=dt,            &
    2837              :                                        rfrac=rfrac,      &
    2838              :                                        meltt=melttn (n), &
    2839              :                                        melts=meltsn (n), &
    2840              :                                        frain=frain,      &
    2841              :                                        Tair=Tair,        &
    2842              :                                        fsurfn=fsurfn(n), &
    2843              :                                        dhs=dhsn     (n), &
    2844              :                                        ffrac=ffracn (n), &
    2845              :                                        aicen=aicen  (n), &
    2846              :                                        vicen=vicen  (n), &
    2847              :                                        vsnon=vsnon  (n), &
    2848              :                                        qicen=zqin (:,n), &
    2849              :                                        sicen=zSin (:,n), &
    2850              :                                        Tsfcn=Tsfc   (n), &
    2851              :                                        alvl=alvl    (n), &
    2852              :                                        apnd=apnd    (n), &
    2853              :                                        hpnd=hpnd    (n), &
    2854              :                                        ipnd=ipnd    (n), &
    2855     10909440 :                                        meltsliqn=l_meltsliqn(n))
    2856     10909440 :                if (icepack_warnings_aborted(subname)) return
    2857              : 
    2858       790080 :             elseif (tr_pond_topo) then
    2859       790080 :                if (aicen_init(n) > puny) then
    2860              : 
    2861              :                   ! collect liquid water in ponds
    2862              :                   ! assume salt still runs off
    2863       452058 :                   rfrac = rfracmin + (rfracmax-rfracmin) * aicen(n)
    2864       452058 :                   if (snwgrain .and. use_smliq_pnd) then
    2865              :                      pond = rfrac/rhofresh * (melttn(n)*rhoi &
    2866            0 :                           +                 l_meltsliqn(n))
    2867              :                   else
    2868              :                      pond = rfrac/rhofresh * (melttn(n)*rhoi &
    2869              :                           +                   meltsn(n)*rhos &
    2870       452058 :                           +                   frain *dt)
    2871              :                   endif
    2872              : 
    2873              :                   ! if pond does not exist, create new pond over full ice area
    2874              :                   ! otherwise increase pond depth without changing pond area
    2875       452058 :                   if (apnd(n) < puny) then
    2876       359840 :                      hpnd(n) = c0
    2877       359840 :                      apnd(n) = c1
    2878              :                   endif
    2879       452058 :                   hpnd(n) = (pond + hpnd(n)*apnd(n)) / apnd(n)
    2880       452058 :                   fpond = fpond + pond * aicen(n) ! m
    2881              :                endif ! aicen_init
    2882              :             endif
    2883              : 
    2884              :          endif ! tr_pond
    2885              :          !call ice_timer_stop(timer_ponds)
    2886              : 
    2887              :       !-----------------------------------------------------------------
    2888              :       ! Increment area-weighted fluxes.
    2889              :       !-----------------------------------------------------------------
    2890              : 
    2891     12761328 :          if (aicen_init(n) > puny) then
    2892              : 
    2893      8777938 :             l_fswthrun_vdr = c0
    2894      8777938 :             l_fswthrun_vdf = c0
    2895      8777938 :             l_fswthrun_idr = c0
    2896      8777938 :             l_fswthrun_idf = c0
    2897      8777938 :             if (present(fswthrun_vdr)) l_fswthrun_vdr = fswthrun_vdr(n)
    2898      8777938 :             if (present(fswthrun_vdf)) l_fswthrun_vdf = fswthrun_vdf(n)
    2899      8777938 :             if (present(fswthrun_idr)) l_fswthrun_idr = fswthrun_idr(n)
    2900      8777938 :             if (present(fswthrun_idf)) l_fswthrun_idf = fswthrun_idf(n)
    2901              : 
    2902              :             call merge_fluxes (aicen=aicen_init(n),            &
    2903              :                                flw=flw, &
    2904              :                                strairxn=strairxn, strairyn=strairyn,&
    2905              :                                Cdn_atm_ratio_n=Cdn_atm_ratio_n,     &
    2906              :                                fsurfn=fsurfn(n), fcondtopn=fcondtopn(n),&
    2907              :                                fcondbotn=fcondbotn(n),              &
    2908              :                                fsensn=fsensn(n),  flatn=flatn(n),   &
    2909              :                                fswabsn=fswabsn,   flwoutn=flwoutn,  &
    2910              :                                evapn=evapn,                         &
    2911              :                                evapsn=evapsn,     evapin=evapin,    &
    2912              :                                Trefn=Trefn,       Qrefn=Qrefn,      &
    2913              :                                freshn=freshn,     fsaltn=fsaltn,    &
    2914              :                                fhocnn=fhocnn,                       &
    2915              :                                fswthrun=fswthrun(n),                &
    2916              :                                fswthrun_vdr=l_fswthrun_vdr,         &
    2917              :                                fswthrun_vdf=l_fswthrun_vdf,         &
    2918              :                                fswthrun_idr=l_fswthrun_idr,         &
    2919              :                                fswthrun_idf=l_fswthrun_idf,         &
    2920              :                                strairxT=strairxT, strairyT=strairyT,&
    2921              :                                Cdn_atm_ratio=Cdn_atm_ratio,         &
    2922              :                                fsurf=fsurf,       fcondtop=fcondtop,&
    2923              :                                fcondbot=fcondbot,                   &
    2924              :                                fsens=fsens,       flat=flat,        &
    2925              :                                fswabs=fswabs,     flwout=flwout,    &
    2926              :                                evap=evap,                           &
    2927              :                                evaps=evaps,       evapi=evapi,      &
    2928              :                                Tref=Tref,         Qref=Qref,        &
    2929              :                                fresh=fresh,       fsalt=fsalt,      &
    2930              :                                fhocn=fhocn,                         &
    2931              :                                fswthru=fswthru,                     &
    2932              :                                fswthru_vdr=fswthru_vdr,             &
    2933              :                                fswthru_vdf=fswthru_vdf,             &
    2934              :                                fswthru_idr=fswthru_idr,             &
    2935              :                                fswthru_idf=fswthru_idf,             &
    2936              :                                melttn=melttn (n), meltsn=meltsn(n), &
    2937              :                                meltbn=meltbn (n), congeln=congeln(n),&
    2938              :                                meltt=meltt,       melts=melts,      &
    2939              :                                meltb=meltb,       snoicen=snoicen(n),&
    2940              :                                dsnow=l_dsnow,     dsnown=l_dsnown,  &
    2941              :                                congel=congel,     snoice=snoice,    &
    2942              :                                meltsliq=l_meltsliq,                 &
    2943              :                                meltsliqn=l_meltsliqn(n),            &
    2944              :                                Uref=Uref,         Urefn=Urefn,      &
    2945              :                                Qref_iso=Qref_iso,                   &
    2946              :                                Qrefn_iso=Qrefn_iso,                 &
    2947              :                                fiso_ocn=fiso_ocn,                   &
    2948              :                                fiso_ocnn=fiso_ocnn,                 &
    2949              :                                fiso_evap=fiso_evap,                 &
    2950      8777938 :                                fiso_evapn=fiso_evapn)
    2951              : 
    2952      8777938 :             if (icepack_warnings_aborted(subname)) return
    2953              : 
    2954              :          endif
    2955              : 
    2956     15390816 :          if (present(dsnown      )) dsnown(n)    = l_dsnown
    2957              : 
    2958              :       enddo                  ! ncat
    2959              : 
    2960              :       !-----------------------------------------------------------------
    2961              :       ! reload snow mass tracers
    2962              :       !-----------------------------------------------------------------
    2963              : 
    2964      2629488 :       if (snwgrain) then
    2965      1825344 :          do n = 1, ncat
    2966      1825344 :             if (vsnon(n) > puny) then
    2967       858044 :                workc = real(nslyr, dbl_kind) * aicen(n) / vsnon(n)
    2968      5148264 :                do k = 1, nslyr
    2969      4290220 :                   smicen(k,n) = massicen(k,n) * workc
    2970      5148264 :                   smliqn(k,n) = massliqn(k,n) * workc
    2971              :                enddo
    2972              :             else ! reset to default values
    2973      3978456 :                do k = 1, nslyr
    2974      3315380 :                   smicen(k,n) = rhos
    2975      3978456 :                   smliqn(k,n) = c0
    2976              :                enddo
    2977              :             endif
    2978              :          enddo
    2979              :       endif
    2980              : 
    2981     15390816 :       if (present(meltsliqn   )) meltsliqn    = l_meltsliqn
    2982      2629488 :       if (present(meltsliq    )) meltsliq     = l_meltsliq
    2983      2629488 :       if (present(dsnow       )) dsnow        = l_dsnow
    2984              : 
    2985              :       !-----------------------------------------------------------------
    2986              :       ! Calculate ponds from the topographic scheme
    2987              :       !-----------------------------------------------------------------
    2988              :       !call ice_timer_start(timer_ponds)
    2989      2629488 :       if (tr_pond_topo) then
    2990              :          call compute_ponds_topo(dt,                             &
    2991              :                                  ktherm,                         &
    2992              :                                  aice,     aicen,                &
    2993              :                                  vice,     vicen,                &
    2994              :                                  vsno,     vsnon,                &
    2995              :                                  meltt,                          &
    2996              :                                  fsurf,    fpond,                &
    2997              :                                  Tsfc,     Tf,                   &
    2998              :                                  zqin,     zSin,                 &
    2999       158016 :                                  apnd,     hpnd,      ipnd       )
    3000       158016 :          if (icepack_warnings_aborted(subname)) return
    3001              :       endif
    3002              :       !call ice_timer_stop(timer_ponds)
    3003              : 
    3004      2629488 :       first_call = .false.
    3005              : 
    3006              :       end subroutine icepack_step_therm1
    3007              : 
    3008              : !=======================================================================
    3009              : 
    3010              :       end module icepack_therm_vertical
    3011              : 
    3012              : !=======================================================================
        

Generated by: LCOV version 2.0-1