LCOV - code coverage report
Current view: top level - columnphysics - icepack_therm_mushy.F90 (source / functions) Hit Total Coverage
Test: 200804-015008:4c42a82e3d:3:base,travis,quick Lines: 887 1153 76.93 %
Date: 2020-08-03 20:10:57 Functions: 31 33 93.94 %

          Line data    Source code
       1             : !=======================================================================
       2             : 
       3             : module icepack_therm_mushy
       4             : 
       5             :   use icepack_kinds
       6             :   use icepack_parameters, only: c0, c1, c2, c8, c10
       7             :   use icepack_parameters, only: p01, p05, p1, p2, p5, pi, bignum, puny
       8             :   use icepack_parameters, only: viscosity_dyn, rhow, rhoi, rhos, cp_ocn, cp_ice, Lfresh, gravit
       9             :   use icepack_parameters, only: hs_min
      10             :   use icepack_parameters, only: a_rapid_mode, Rac_rapid_mode
      11             :   use icepack_parameters, only: aspect_rapid_mode, dSdt_slow_mode, phi_c_slow_mode
      12             :   use icepack_parameters, only: sw_redist, sw_frac, sw_dtemp
      13             :   use icepack_mushy_physics, only: icepack_mushy_density_brine, enthalpy_brine, enthalpy_snow
      14             :   use icepack_mushy_physics, only: enthalpy_mush_liquid_fraction
      15             :   use icepack_mushy_physics, only: icepack_mushy_temperature_mush, icepack_mushy_liquid_fraction
      16             :   use icepack_mushy_physics, only: temperature_snow, temperature_mush_liquid_fraction
      17             :   use icepack_mushy_physics, only: liquidus_brine_salinity_mush, liquidus_temperature_mush
      18             :   use icepack_mushy_physics, only: conductivity_mush_array, conductivity_snow_array
      19             :   use icepack_tracers, only: tr_pond
      20             :   use icepack_therm_shared, only: surface_heat_flux, dsurface_heat_flux_dTsf
      21             :   use icepack_therm_shared, only: ferrmax
      22             :   use icepack_warnings, only: warnstr, icepack_warnings_add
      23             :   use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted
      24             : 
      25             :   implicit none
      26             : 
      27             :   private
      28             :   public :: &
      29             :        temperature_changes_salinity, &
      30             :        permeability
      31             : 
      32             :   real(kind=dbl_kind), parameter :: &
      33             :        dTemp_errmax = 5.0e-4_dbl_kind ! max allowed change in temperature 
      34             :                                       ! between iterations
      35             : 
      36             : !=======================================================================
      37             : 
      38             : contains
      39             : 
      40             : !=======================================================================
      41             : 
      42     3172532 :   subroutine temperature_changes_salinity(dt,                 &
      43             :                                           nilyr,    nslyr,    &
      44             :                                           rhoa,     flw,      &
      45             :                                           potT,     Qa,       &
      46             :                                           shcoef,   lhcoef,   &
      47             :                                           fswsfc,   fswint,   &
      48     6345064 :                                           Sswabs,   Iswabs,   &
      49             :                                           hilyr,    hslyr,    &
      50             :                                           apond,    hpond,    &
      51     6345064 :                                           zqin,     zTin,     &
      52     6345064 :                                           zqsn,     zTsn,     &
      53     3172532 :                                           zSin,               &
      54             :                                           Tsf,      Tbot,     &
      55             :                                           sss,                &
      56             :                                           fsensn,   flatn,    &
      57             :                                           flwoutn,  fsurfn,   &
      58             :                                           fcondtop, fcondbot, &
      59             :                                           fadvheat, snoice)
      60             : 
      61             :     ! solve the enthalpy and bulk salinity of the ice for a single column
      62             : 
      63             :     integer (kind=int_kind), intent(in) :: &
      64             :          nilyr , & ! number of ice layers
      65             :          nslyr     ! number of snow layers
      66             :     
      67             :     real (kind=dbl_kind), intent(in) :: &
      68             :          dt              ! time step (s)
      69             :     
      70             :     real (kind=dbl_kind), intent(in) :: &
      71             :          rhoa        , & ! air density (kg/m^3)
      72             :          flw         , & ! incoming longwave radiation (W/m^2)
      73             :          potT        , & ! air potential temperature  (K)
      74             :          Qa          , & ! specific humidity (kg/kg)
      75             :          shcoef      , & ! transfer coefficient for sensible heat
      76             :          lhcoef      , & ! transfer coefficient for latent heat
      77             :          Tbot        , & ! ice bottom surfce temperature (deg C)
      78             :          sss             ! sea surface salinity (PSU)
      79             :          
      80             :     real (kind=dbl_kind), intent(inout) :: &
      81             :          fswsfc      , & ! SW absorbed at ice/snow surface (W m-2)
      82             :          fswint          ! SW absorbed in ice interior below surface (W m-2)
      83             :     
      84             :     real (kind=dbl_kind), intent(inout) :: &
      85             :          hilyr       , & ! ice layer thickness (m)
      86             :          hslyr       , & ! snow layer thickness (m)
      87             :          apond       , & ! melt pond area fraction
      88             :          hpond           ! melt pond depth (m)
      89             : 
      90             :     real (kind=dbl_kind), dimension (:), intent(inout) :: &
      91             :          Sswabs      , & ! SW radiation absorbed in snow layers (W m-2)
      92             :          Iswabs          ! SW radiation absorbed in ice layers (W m-2)
      93             :     
      94             :     real (kind=dbl_kind), intent(inout):: &
      95             :          fsurfn      , & ! net flux to top surface, excluding fcondtopn
      96             :          fcondtop    , & ! downward cond flux at top surface (W m-2)
      97             :          fsensn      , & ! surface downward sensible heat (W m-2)
      98             :          flatn       , & ! surface downward latent heat (W m-2)
      99             :          flwoutn         ! upward LW at surface (W m-2)
     100             :     
     101             :     real (kind=dbl_kind), intent(out):: &
     102             :          fcondbot    , & ! downward cond flux at bottom surface (W m-2)
     103             :          fadvheat    , & ! flow of heat to ocean due to advection (W m-2)
     104             :          snoice          ! snow ice formation
     105             : 
     106             :     real (kind=dbl_kind), intent(inout):: &
     107             :          Tsf             ! ice/snow surface temperature (C)
     108             : 
     109             :     real (kind=dbl_kind), dimension (:), intent(inout) :: &
     110             :          zqin        , & ! ice layer enthalpy (J m-3)
     111             :          zTin        , & ! internal ice layer temperatures
     112             :          zSin        , & ! internal ice layer salinities
     113             :          zqsn        , & ! snow layer enthalpy (J m-3)
     114             :          zTsn            ! internal snow layer temperatures
     115             :     
     116             :     ! local variables
     117             :     real(kind=dbl_kind), dimension(1:nilyr) :: &
     118    12730180 :          zqin0       , & ! ice layer enthalpy (J m-3) at start of timestep
     119    12730180 :          zSin0       , & ! internal ice layer salinities (ppt) at start of timestep
     120    12730180 :          phi         , & ! liquid fraction
     121    12730180 :          km          , & ! ice conductivity (W m-1 K-1)
     122    14858552 :          dSdt            ! gravity drainage desalination rate for slow mode (ppt s-1)
     123             : 
     124             :     real(kind=dbl_kind), dimension(1:nilyr+1) :: &
     125    13794366 :          Sbr         , & ! brine salinity (ppt)
     126    13794366 :          qbr             ! brine enthalpy (J m-3)
     127             : 
     128             :     real(kind=dbl_kind), dimension(0:nilyr) :: &
     129    13794366 :          q               ! upward interface vertical Darcy flow (m s-1)
     130             : 
     131             :     real(kind=dbl_kind), dimension(1:nslyr) :: &
     132     6345064 :          zqsn0       , & ! snow layer enthalpy (J m-3) at start of timestep
     133     6365090 :          ks              ! snow conductivity (W m-1 K-1)
     134             : 
     135             :     real(kind=dbl_kind) :: &
     136     1064186 :          Tsf0        , & ! ice/snow surface temperature (C) at start of timestep
     137     1064186 :          hin         , & ! ice thickness (m)
     138     1064186 :          hsn         , & ! snow thickness (m)
     139     1064186 :          hslyr_min   , & ! minimum snow layer thickness (m)
     140     1064186 :          w           , & ! vertical flushing Darcy velocity (m/s)
     141     1064186 :          qocn        , & ! ocean brine enthalpy (J m-3)
     142     1064186 :          qpond       , & ! melt pond brine enthalpy (J m-3)
     143     1064186 :          Spond           ! melt pond salinity (ppt)
     144             : 
     145     2128372 :     real(kind=dbl_kind) :: Tmlt, Iswabs_tmp, dt_rhoi_hlyr, ci, dswabs
     146             : 
     147             :     integer(kind=int_kind) :: &
     148             :          k               ! ice/snow layer index
     149             : 
     150             :     logical(kind=log_kind) :: &
     151             :          lsnow           ! snow presence: T: has snow, F: no snow
     152             : 
     153             :     character(len=*),parameter :: subname='(temperature_changes_salinity)'
     154             : 
     155     3172532 :     fadvheat   = c0
     156     3172532 :     snoice     = c0
     157             : 
     158     3172532 :     Tsf0  = Tsf
     159     6345064 :     zqsn0 = zqsn
     160    25380256 :     zqin0 = zqin
     161    25380256 :     zSin0 = zSin
     162             : 
     163     3172532 :     Spond = c0
     164     3172532 :     qpond = enthalpy_brine(c0)
     165             : 
     166     3172532 :     hslyr_min = hs_min / real(nslyr, dbl_kind)
     167             : 
     168     3172532 :     lsnow = (hslyr > hslyr_min)
     169             : 
     170     3172532 :     hin = hilyr * real(nilyr,dbl_kind)
     171             : 
     172     3172532 :     qocn = enthalpy_brine(Tbot)
     173             : 
     174     3172532 :     if (lsnow) then
     175     2550448 :        hsn = hslyr * real(nslyr,dbl_kind)
     176             :     else
     177      622084 :        hsn = c0
     178             :     endif
     179             : 
     180    25380256 :     do k = 1, nilyr
     181    25380256 :        phi(k) = icepack_mushy_liquid_fraction(icepack_mushy_temperature_mush(zqin(k),zSin(k)),zSin(k))
     182             :     enddo ! k
     183             : 
     184             :     ! calculate vertical bulk darcy flow
     185           0 :     call flushing_velocity(zTin, &
     186           0 :                            phi,    nilyr, &
     187             :                            hin,    hsn,   &
     188             :                            hilyr,         &
     189             :                            hpond,  apond, & 
     190     3172532 :                            dt,     w)
     191     3172532 :     if (icepack_warnings_aborted(subname)) return
     192             : 
     193             :     ! calculate quantities related to drainage
     194           0 :     call explicit_flow_velocities(nilyr,  zSin,   &
     195           0 :                                   zTin,   Tsf,    &
     196             :                                   Tbot,   q,      &
     197           0 :                                   dSdt,   Sbr,    &
     198           0 :                                   qbr,    dt,     &
     199             :                                   sss,    qocn,   &
     200     3172532 :                                   hilyr,  hin)
     201     3172532 :     if (icepack_warnings_aborted(subname)) return
     202             :     
     203             :     ! calculate the conductivities
     204     3172532 :     call conductivity_mush_array(nilyr, zqin0, zSin0, km)
     205     3172532 :     if (icepack_warnings_aborted(subname)) return
     206             : 
     207             :     !-----------------------------------------------------------------
     208             :     ! Check for excessive absorbed solar radiation that may result in
     209             :     ! temperature overshoots. Convergence is particularly difficult
     210             :     ! if the starting temperature is already very close to the melting 
     211             :     ! temperature and extra energy is added.   In that case, or if the
     212             :     ! amount of energy absorbed is greater than the amount needed to
     213             :     ! melt through a given fraction of a layer, we put the extra 
     214             :     ! energy into the surface.
     215             :     ! NOTE: This option is not available if the atmosphere model
     216             :     !       has already computed fsurf.  (Unless we adjust fsurf here)
     217             :     !-----------------------------------------------------------------
     218             : !mclaren: Should there be an if calc_Tsfc statement here then?? 
     219             : 
     220     3172532 :     if (sw_redist) then
     221             : 
     222           0 :     do k = 1, nilyr
     223             : 
     224           0 :        Iswabs_tmp = c0 ! all Iswabs is moved into fswsfc
     225             : 
     226           0 :        Tmlt = liquidus_temperature_mush(zSin(k))
     227             : 
     228           0 :        if (zTin(k) <= Tmlt - sw_dtemp) then
     229           0 :           ci = cp_ice - Lfresh * Tmlt / (zTin(k)**2)
     230           0 :           Iswabs_tmp = min(Iswabs(k), &
     231           0 :                            sw_frac*(Tmlt-zTin(k))*ci/dt_rhoi_hlyr)
     232             :        endif
     233           0 :        if (Iswabs_tmp < puny) Iswabs_tmp = c0
     234             : 
     235           0 :        dswabs = min(Iswabs(k) - Iswabs_tmp, fswint)
     236             : 
     237           0 :        fswsfc   = fswsfc + dswabs
     238           0 :        fswint   = fswint - dswabs
     239           0 :        Iswabs(k) = Iswabs_tmp
     240             : 
     241             :     enddo
     242             : 
     243             :     endif
     244             : 
     245     3172532 :     if (lsnow) then
     246             :        ! case with snow
     247             : 
     248             :        ! calculate the snow conductivities
     249     2550448 :        call conductivity_snow_array(ks)
     250     2550448 :        if (icepack_warnings_aborted(subname)) return
     251             : 
     252             :        ! run the two stage solver
     253             :        call two_stage_solver_snow(nilyr,       nslyr,      &
     254             :                                   Tsf,         Tsf0,       &
     255           0 :                                   zqsn,        zqsn0,      &
     256           0 :                                   zqin,        zqin0,      &
     257           0 :                                   zSin,        zSin0,      &
     258           0 :                                   zTsn, &
     259           0 :                                   zTin, &
     260           0 :                                   phi,         Tbot,       &
     261           0 :                                   km,          ks,         &
     262           0 :                                   q,           dSdt,       &
     263             :                                   w,           dt,         &
     264             :                                   fswint,      fswsfc,     &
     265             :                                   rhoa,        flw,        &
     266             :                                   potT,        Qa,         &
     267             :                                   shcoef,      lhcoef,     &
     268           0 :                                   Iswabs,      Sswabs,     &
     269             :                                   qpond,       qocn,       &
     270             :                                   Spond,       sss,        &
     271             :                                   hilyr,       hslyr,      &
     272             :                                   fcondtop,    fcondbot,   &
     273             :                                   fadvheat,                &
     274             :                                   flwoutn,     fsensn,     &
     275     2550448 :                                   flatn,       fsurfn      )
     276             : 
     277     2550448 :        if (icepack_warnings_aborted(subname)) then
     278           0 :           write(warnstr,*) subname, "temperature_changes_salinity: Picard solver non-convergence (snow)"
     279           0 :           call icepack_warnings_add(warnstr)
     280           0 :           return
     281             :        endif
     282             : 
     283             :        ! given the updated enthalpy and bulk salinity calculate other quantities
     284     5100896 :        do k = 1, nslyr
     285     5100896 :           zTsn(k) = temperature_snow(zqsn(k))
     286             :        enddo ! k
     287             : 
     288    20403584 :        do k = 1, nilyr
     289    17853136 :           zTin(k) = temperature_mush_liquid_fraction(zqin(k), phi(k))
     290    17853136 :           Sbr(k)  = liquidus_brine_salinity_mush(zTin(k)) 
     291    20403584 :           qbr(k)  = enthalpy_brine(zTin(k))
     292             :        enddo ! k
     293             :           
     294             :     else
     295             :        ! case without snow
     296             : 
     297             :        ! run the two stage solver
     298             :        call two_stage_solver_nosnow(nilyr,       nslyr,      &
     299             :                                     Tsf,         Tsf0,       &
     300           0 :                                     zqsn, &
     301           0 :                                     zqin,        zqin0,      &
     302           0 :                                     zSin,        zSin0,      &
     303           0 :                                     zTsn, &
     304           0 :                                     zTin, &
     305           0 :                                     phi,         Tbot,       &
     306           0 :                                     km,          ks,         &
     307           0 :                                     q,           dSdt,       &
     308             :                                     w,           dt,         &
     309             :                                     fswint,      fswsfc,     &
     310             :                                     rhoa,        flw,        &
     311             :                                     potT,        Qa,         &
     312             :                                     shcoef,      lhcoef,     &
     313           0 :                                     Iswabs,      Sswabs,     &
     314             :                                     qpond,       qocn,       &
     315             :                                     Spond,       sss,        &
     316             :                                     hilyr,       hslyr,      &
     317             :                                     fcondtop,    fcondbot,   &
     318             :                                     fadvheat,                &
     319             :                                     flwoutn,     fsensn,     &
     320      622084 :                                     flatn,       fsurfn      )
     321             : 
     322      622084 :        if (icepack_warnings_aborted(subname)) then
     323           0 :           write(warnstr,*) subname, "temperature_changes_salinity: Picard solver non-convergence (no snow)"
     324           0 :           call icepack_warnings_add(warnstr)
     325           0 :           return
     326             :        endif
     327             :           
     328             :        ! given the updated enthalpy and bulk salinity calculate other quantities
     329     4976672 :        do k = 1, nilyr
     330     4354588 :           zTin(k) = temperature_mush_liquid_fraction(zqin(k), phi(k))
     331     4354588 :           Sbr(k)  = liquidus_brine_salinity_mush(zTin(k)) 
     332     4976672 :           qbr(k)  = enthalpy_brine(zTin(k))
     333             :        enddo ! k
     334             :        
     335             :     endif
     336             : 
     337             :     ! drain ponds from flushing 
     338     3172532 :     call flush_pond(w, hpond, apond, dt)
     339     3172532 :     if (icepack_warnings_aborted(subname)) return
     340             : 
     341             :     ! flood snow ice
     342             :     call flood_ice(hsn,        hin,      &
     343             :                    nslyr,      nilyr,    & 
     344             :                    hslyr,      hilyr,    & 
     345           0 :                    zqsn,       zqin,     &
     346           0 :                    phi,        dt,       &
     347           0 :                    zSin,       Sbr,      &
     348             :                    sss,        qocn,     &
     349     3172532 :                    snoice,     fadvheat)
     350     3172532 :     if (icepack_warnings_aborted(subname)) return
     351             : 
     352             :   end subroutine temperature_changes_salinity
     353             : 
     354             : !=======================================================================
     355             : 
     356     2550448 :   subroutine two_stage_solver_snow(nilyr,       nslyr,      &
     357             :                                    Tsf,         Tsf0,       &
     358     5100896 :                                    zqsn,        zqsn0,      &
     359     5100896 :                                    zqin,        zqin0,      &
     360     5100896 :                                    zSin,        zSin0,      &
     361     2550448 :                                    zTsn, &
     362     2550448 :                                    zTin, &
     363     2550448 :                                    phi,         Tbot,       &
     364     2550448 :                                    km,          ks,         &
     365     2550448 :                                    q,           dSdt,       &
     366             :                                    w,           dt,         &
     367             :                                    fswint,      fswsfc,     &
     368             :                                    rhoa,        flw,        &
     369             :                                    potT,        Qa,         &
     370             :                                    shcoef,      lhcoef,     &
     371     2550448 :                                    Iswabs,      Sswabs,     &
     372             :                                    qpond,       qocn,       &
     373             :                                    Spond,       sss,        &
     374             :                                    hilyr,       hslyr,      &
     375             :                                    fcondtop,    fcondbot,   &
     376             :                                    fadvheat,                &
     377             :                                    flwoutn,     fsensn,     &
     378             :                                    flatn,       fsurfn      )
     379             : 
     380             :     ! solve the vertical temperature and salt change for case with snow
     381             :     ! 1) determine what type of surface condition existed previously - cold or melting
     382             :     ! 2) solve the system assuming this condition persists
     383             :     ! 3) check the consistency of the surface condition of the solution
     384             :     ! 4) If the surface condition is inconsistent resolve for the other surface condition
     385             :     ! 5) If neither solution is consistent the resolve the inconsistency
     386             : 
     387             :     integer (kind=int_kind), intent(in) :: &
     388             :          nilyr      , &  ! number of ice layers
     389             :          nslyr           ! number of snow layers
     390             : 
     391             :     real(kind=dbl_kind), intent(inout) :: &
     392             :          Tsf             ! snow surface temperature (C)
     393             : 
     394             :     real(kind=dbl_kind), intent(out) :: &
     395             :          fcondtop    , & ! downward cond flux at top surface (W m-2)
     396             :          fcondbot    , & ! downward cond flux at bottom surface (W m-2)
     397             :          flwoutn     , & ! upward LW at surface (W m-2)
     398             :          fsensn      , & ! surface downward sensible heat (W m-2)
     399             :          flatn       , & ! surface downward latent heat (W m-2)
     400             :          fsurfn      , & ! net flux to top surface, excluding fcondtop
     401             :          fadvheat        ! flow of heat to ocean due to advection (W m-2)
     402             : 
     403             :     real(kind=dbl_kind), intent(in) :: &
     404             :          Tsf0            ! snow surface temperature (C) at beginning of timestep
     405             : 
     406             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
     407             :          zqsn        , & ! snow layer enthalpy (J m-3)
     408             :          zTsn            ! snow layer temperature (C)
     409             : 
     410             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
     411             :          zqsn0       , & ! snow layer enthalpy (J m-3) at beginning of timestep
     412             :          ks          , & ! snow conductivity (W m-1 K-1)
     413             :          Sswabs          ! SW radiation absorbed in snow layers (W m-2)
     414             : 
     415             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
     416             :          zqin        , & ! ice layer enthalpy (J m-3) 
     417             :          zSin        , & ! ice layer bulk salinity (ppt)
     418             :          zTin        , & ! ice layer temperature (C)
     419             :          phi             ! ice layer liquid fraction
     420             : 
     421             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
     422             :          zqin0       , & ! ice layer enthalpy (J m-3) at beginning of timestep
     423             :          zSin0       , & ! ice layer bulk salinity (ppt) at beginning of timestep
     424             :          km          , & ! ice conductivity (W m-1 K-1)
     425             :          Iswabs      , & ! SW radiation absorbed in ice layers (W m-2)
     426             :          dSdt            ! gravity drainage desalination rate for slow mode (ppt s-1)
     427             : 
     428             :     real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
     429             :          q               ! upward interface vertical Darcy flow (m s-1)
     430             : 
     431             :     real(kind=dbl_kind), intent(in) :: &
     432             :          dt          , & ! time step (s)
     433             :          Tbot        , & ! ice bottom surfce temperature (deg C)
     434             :          hilyr       , & ! ice layer thickness (m)
     435             :          hslyr       , & ! snow layer thickness (m)
     436             :          fswint      , & ! SW absorbed in ice interior below surface (W m-2)
     437             :          fswsfc      , & ! SW absorbed at ice/snow surface (W m-2)
     438             :          rhoa        , & ! air density (kg/m^3)
     439             :          flw         , & ! incoming longwave radiation (W/m^2)
     440             :          potT        , & ! air potential temperature (K)
     441             :          Qa          , & ! specific humidity (kg/kg)
     442             :          shcoef      , & ! transfer coefficient for sensible heat
     443             :          lhcoef      , & ! transfer coefficient for latent heat
     444             :          w           , & ! vertical flushing Darcy velocity (m/s)
     445             :          qpond       , & ! melt pond brine enthalpy (J m-3)
     446             :          qocn        , & ! ocean brine enthalpy (J m-3)
     447             :          Spond       , & ! melt pond salinity (ppt)
     448             :          sss             ! sea surface salinity (PSU)
     449             : 
     450             :     real(kind=dbl_kind) :: &
     451      818127 :          fcondtop1   , & ! first stage downward cond flux at top surface (W m-2)
     452      818127 :          fsurfn1     , & ! first stage net flux to top surface, excluding fcondtop
     453      818127 :          Tsf1            ! first stage ice surface temperature (C)
     454             : 
     455             :     character(len=*),parameter :: subname='(two_stage_solver_snow)'
     456             : 
     457             : 
     458             :     ! determine if surface is initially cold or melting
     459     2550448 :     if (Tsf < c0) then
     460             : 
     461             :        ! initially cold
     462             : 
     463             :        ! solve the system for cold and snow
     464             :        call picard_solver(nilyr,   nslyr,     &
     465             :                           .true.,  .true.,    &
     466           0 :                           Tsf,      zqsn,     &
     467           0 :                           zqin,     zSin,     &
     468           0 :                           zTin,     zTsn,     &
     469           0 :                           phi,      dt,       &
     470             :                           hilyr,    hslyr,    &
     471           0 :                           km,       ks,       &
     472           0 :                           Iswabs,   Sswabs,   &
     473             :                           Tbot,               &
     474             :                           fswint,   fswsfc,   &
     475             :                           rhoa,     flw,      &
     476             :                           potT,     Qa,       &
     477             :                           shcoef,   lhcoef,   &
     478             :                           fcondtop, fcondbot, &
     479             :                           fadvheat,           &
     480             :                           flwoutn,  fsensn,   &
     481             :                           flatn,    fsurfn,   &
     482             :                           qpond,    qocn,     &
     483             :                           Spond,    sss,      &
     484           0 :                           q,        dSdt,     &
     485     2541747 :                           w                   )
     486     5092195 :        if (icepack_warnings_aborted(subname)) return
     487             : 
     488             :        ! halt if solver failed
     489     2541747 :        if (icepack_warnings_aborted(subname)) return
     490             : 
     491             :        ! check if solution is consistent - surface should still be cold
     492     2541747 :        if (Tsf < dTemp_errmax) then
     493             : 
     494             :           ! solution is consistent - have solution so finish
     495     2511874 :           return
     496             : 
     497             :        else
     498             :           
     499             :           ! solution is inconsistent - surface is warmer than melting 
     500             :           ! resolve assuming surface is melting
     501       29873 :           Tsf1 = Tsf
     502             : 
     503             :           ! reset the solution to initial values
     504       29873 :           Tsf  = c0
     505       59746 :           zqsn = zqsn0
     506      238984 :           zqin = zqin0
     507      238984 :           zSin = zSin0
     508             : 
     509             :           ! solve the system for melting and snow             
     510             :           call picard_solver(nilyr,    nslyr,    &
     511             :                              .true.,   .false.,  &
     512           0 :                              Tsf,      zqsn,     &
     513           0 :                              zqin,     zSin,     &
     514           0 :                              zTin,     zTsn,     &
     515           0 :                              phi,      dt,       &
     516             :                              hilyr,    hslyr,    &
     517           0 :                              km,       ks,       &
     518           0 :                              Iswabs,   Sswabs,   &
     519             :                              Tbot,               &
     520             :                              fswint,   fswsfc,   &
     521             :                              rhoa,     flw,      &
     522             :                              potT,     Qa,       &
     523             :                              shcoef,   lhcoef,   &
     524             :                              fcondtop, fcondbot, &
     525             :                              fadvheat,           &
     526             :                              flwoutn,  fsensn,   &
     527             :                              flatn,    fsurfn,   &
     528             :                              qpond,    qocn,     &
     529             :                              Spond,    sss,      &
     530           0 :                              q,        dSdt,     &
     531       29873 :                              w                   )
     532       29873 :           if (icepack_warnings_aborted(subname)) return
     533             : 
     534             :           ! halt if solver failed
     535       29873 :           if (icepack_warnings_aborted(subname)) return
     536             : 
     537             :           ! check if solution is consistent 
     538             :           ! surface conductive heat flux should be less than 
     539             :           ! incoming surface heat flux
     540       29873 :           if (fcondtop - fsurfn < ferrmax) then
     541             : 
     542             :              ! solution is consistent - have solution so finish
     543       29873 :              return
     544             : 
     545             :           else
     546             : 
     547             :              ! solution is inconsistent
     548           0 :              call two_stage_inconsistency(1, Tsf1, c0, fcondtop, fsurfn)
     549           0 :              if (icepack_warnings_aborted(subname)) return
     550           0 :              call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
     551           0 :              call icepack_warnings_add(subname//" two_stage_solver_snow: two_stage_inconsistency: cold" ) 
     552           0 :              return
     553             : 
     554             :           endif ! surface flux consistency
     555             : 
     556             :        endif ! surface temperature consistency
     557             : 
     558             :     else
     559             : 
     560             :        ! initially melting
     561        8701 :        Tsf = c0
     562             : 
     563             :        ! solve the system for melting and snow
     564             :        call picard_solver(nilyr,    nslyr,    &
     565             :                           .true.,   .false.,  &
     566           0 :                           Tsf,      zqsn,     &
     567           0 :                           zqin,     zSin,     &
     568           0 :                           zTin,     zTsn,     &
     569           0 :                           phi,      dt,       &
     570             :                           hilyr,    hslyr,    &
     571           0 :                           km,       ks,       &
     572           0 :                           Iswabs,   Sswabs,   &
     573             :                           Tbot,               &
     574             :                           fswint,   fswsfc,   &
     575             :                           rhoa,     flw,      &
     576             :                           potT,     Qa,       &
     577             :                           shcoef,   lhcoef,   &
     578             :                           fcondtop, fcondbot, &
     579             :                           fadvheat,           &
     580             :                           flwoutn,  fsensn,   &
     581             :                           flatn,    fsurfn,   &
     582             :                           qpond,    qocn,     &
     583             :                           Spond,    sss,      &
     584           0 :                           q,        dSdt,     &
     585        8701 :                           w                   )
     586             : 
     587        8701 :        if (icepack_warnings_aborted(subname)) return
     588             : 
     589             :        ! halt if solver failed
     590        8701 :        if (icepack_warnings_aborted(subname)) return
     591             :        
     592             :        ! check if solution is consistent 
     593             :        ! surface conductive heat flux should be less than 
     594             :        ! incoming surface heat flux
     595        8701 :        if (fcondtop - fsurfn < ferrmax) then
     596             : 
     597             :           ! solution is consistent - have solution so finish
     598        7558 :           return
     599             : 
     600             :        else
     601             : 
     602             :           ! solution is inconsistent - resolve assuming other surface condition
     603             :           ! assume surface is cold
     604        1143 :           fcondtop1 = fcondtop
     605        1143 :           fsurfn1   = fsurfn
     606             : 
     607             :           ! reset the solution to initial values
     608        1143 :           Tsf  = Tsf0
     609        2286 :           zqsn = zqsn0
     610        9144 :           zqin = zqin0
     611        9144 :           zSin = zSin0
     612             : 
     613             :           ! solve the system for cold and snow      
     614             :           call picard_solver(nilyr,    nslyr,    &
     615             :                              .true.,   .true.,   &       
     616           0 :                              Tsf,      zqsn,     &
     617           0 :                              zqin,     zSin,     &
     618           0 :                              zTin,     zTsn,     &
     619           0 :                              phi,      dt,       &
     620             :                              hilyr,    hslyr,    & 
     621           0 :                              km,       ks,       &
     622           0 :                              Iswabs,   Sswabs,   &
     623             :                              Tbot,               &
     624             :                              fswint,   fswsfc,   &
     625             :                              rhoa,     flw,      &
     626             :                              potT,     Qa,       &
     627             :                              shcoef,   lhcoef,   &
     628             :                              fcondtop, fcondbot, &
     629             :                              fadvheat,           &
     630             :                              flwoutn,  fsensn,   &
     631             :                              flatn,    fsurfn,   &
     632             :                              qpond,    qocn,     &
     633             :                              Spond,    sss,      &
     634           0 :                              q,        dSdt,     &
     635        1143 :                              w                   )
     636        1143 :           if (icepack_warnings_aborted(subname)) return
     637             : 
     638             :           ! halt if solver failed
     639        1143 :           if (icepack_warnings_aborted(subname)) return
     640             : 
     641             :           ! check if solution is consistent - surface should be cold
     642        1143 :           if (Tsf < dTemp_errmax) then
     643             : 
     644             :              ! solution is consistent - have solution so finish
     645        1143 :              return
     646             : 
     647             :           else
     648             : 
     649             :              ! solution is inconsistent
     650             :              ! failed to find a solution so need to refine solutions until consistency found
     651           0 :              call two_stage_inconsistency(2, Tsf, c0, fcondtop1, fsurfn1)
     652           0 :              if (icepack_warnings_aborted(subname)) return
     653           0 :              call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
     654           0 :              call icepack_warnings_add(subname//" two_stage_solver_snow: two_stage_inconsistency: melting" ) 
     655           0 :              return
     656             :  
     657             :           endif ! surface temperature consistency
     658             :           
     659             :        endif ! surface flux consistency
     660             : 
     661             :     endif
     662             : 
     663             :   end subroutine two_stage_solver_snow
     664             : 
     665             : !=======================================================================
     666             : 
     667      622084 :   subroutine two_stage_solver_nosnow(nilyr,       nslyr,      &
     668             :                                      Tsf,         Tsf0,       &
     669      622084 :                                      zqsn, &
     670     1244168 :                                      zqin,        zqin0,      &
     671     1244168 :                                      zSin,        zSin0,      &
     672      622084 :                                      zTsn, &
     673      622084 :                                      zTin, &
     674      622084 :                                      phi,         Tbot,       &
     675      622084 :                                      km,          ks,         &
     676      622084 :                                      q,           dSdt,       &
     677             :                                      w,           dt,         &
     678             :                                      fswint,      fswsfc,     &
     679             :                                      rhoa,        flw,        &
     680             :                                      potT,        Qa,         &
     681             :                                      shcoef,      lhcoef,     &
     682      622084 :                                      Iswabs,      Sswabs,     &
     683             :                                      qpond,       qocn,       &
     684             :                                      Spond,       sss,        &
     685             :                                      hilyr,       hslyr,      &
     686             :                                      fcondtop,    fcondbot,   &
     687             :                                      fadvheat,                &
     688             :                                      flwoutn,     fsensn,     &
     689             :                                      flatn,       fsurfn      )
     690             :     
     691             :     ! solve the vertical temperature and salt change for case with no snow
     692             :     ! 1) determine what type of surface condition existed previously - cold or melting
     693             :     ! 2) solve the system assuming this condition persists
     694             :     ! 3) check the consistency of the surface condition of the solution
     695             :     ! 4) If the surface condition is inconsistent resolve for the other surface condition
     696             :     ! 5) If neither solution is consistent the resolve the inconsistency
     697             : 
     698             :     integer (kind=int_kind), intent(in) :: &
     699             :          nilyr      , &  ! number of ice layers
     700             :          nslyr           ! number of snow layers
     701             : 
     702             :     real(kind=dbl_kind), intent(inout) :: &
     703             :          Tsf             ! ice surface temperature (C)
     704             : 
     705             :     real(kind=dbl_kind), intent(out) :: &
     706             :          fcondtop    , & ! downward cond flux at top surface (W m-2)
     707             :          fcondbot    , & ! downward cond flux at bottom surface (W m-2)
     708             :          flwoutn     , & ! upward LW at surface (W m-2)
     709             :          fsensn      , & ! surface downward sensible heat (W m-2)
     710             :          flatn       , & ! surface downward latent heat (W m-2)
     711             :          fsurfn      , & ! net flux to top surface, excluding fcondtop
     712             :          fadvheat        ! flow of heat to ocean due to advection (W m-2)
     713             : 
     714             :     real(kind=dbl_kind), intent(in) :: &
     715             :          Tsf0            ! ice surface temperature (C) at beginning of timestep
     716             : 
     717             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
     718             :          zqsn        , & ! snow layer enthalpy (J m-3)
     719             :          zTsn            ! snow layer temperature (C)
     720             : 
     721             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
     722             :          ks          , & ! snow conductivity (W m-1 K-1)
     723             :          Sswabs          ! SW radiation absorbed in snow layers (W m-2)
     724             : 
     725             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
     726             :          zqin        , & ! ice layer enthalpy (J m-3) 
     727             :          zSin        , & ! ice layer bulk salinity (ppt)
     728             :          zTin        , & ! ice layer temperature (C)
     729             :          phi             ! ice layer liquid fraction
     730             : 
     731             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
     732             :          zqin0       , & ! ice layer enthalpy (J m-3) at beginning of timestep
     733             :          zSin0       , & ! ice layer bulk salinity (ppt) at beginning of timestep
     734             :          km          , & ! ice conductivity (W m-1 K-1)
     735             :          Iswabs      , & ! SW radiation absorbed in ice layers (W m-2)
     736             :          dSdt            ! gravity drainage desalination rate for slow mode (ppt s-1)
     737             : 
     738             :     real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
     739             :          q               ! upward interface vertical Darcy flow (m s-1)
     740             : 
     741             :     real(kind=dbl_kind), intent(in) :: &
     742             :          dt          , & ! time step (s)
     743             :          hilyr       , & ! ice layer thickness (m)
     744             :          hslyr       , & ! snow layer thickness (m)
     745             :          Tbot        , & ! ice bottom surfce temperature (deg C)
     746             :          fswint      , & ! SW absorbed in ice interior below surface (W m-2)
     747             :          fswsfc      , & ! SW absorbed at ice/snow surface (W m-2)
     748             :          rhoa        , & ! air density (kg/m^3)
     749             :          flw         , & ! incoming longwave radiation (W/m^2)
     750             :          potT        , & ! air potential temperature (K)
     751             :          Qa          , & ! specific humidity (kg/kg)
     752             :          shcoef      , & ! transfer coefficient for sensible heat
     753             :          lhcoef      , & ! transfer coefficient for latent heat
     754             :          w           , & ! vertical flushing Darcy velocity (m/s)
     755             :          qpond       , & ! melt pond brine enthalpy (J m-3)
     756             :          qocn        , & ! ocean brine enthalpy (J m-3)
     757             :          Spond       , & ! melt pond salinity (ppt)
     758             :          sss             ! sea surface salinity (PSU)
     759             : 
     760             :     real(kind=dbl_kind) :: &
     761      246059 :          Tmlt        , & ! upper ice layer melting temperature (C)
     762      246059 :          fcondtop1   , & ! first stage downward cond flux at top surface (W m-2)
     763      246059 :          fsurfn1     , & ! first stage net flux to top surface, excluding fcondtop
     764      246059 :          Tsf1            ! first stage ice surface temperature (C)
     765             : 
     766             :     character(len=*),parameter :: subname='(two_stage_solver_nosnow)'
     767             : 
     768             :     ! initial surface melting temperature
     769      622084 :     Tmlt = liquidus_temperature_mush(zSin0(1))
     770             : 
     771             :     ! determine if surface is initially cold or melting
     772      622084 :     if (Tsf < Tmlt) then
     773             : 
     774             :        ! initially cold
     775             : 
     776             :        ! solve the system for cold and no snow          
     777             :        call picard_solver(nilyr,    nslyr,    &
     778             :                           .false.,  .true.,   &
     779           0 :                           Tsf,      zqsn,     &
     780           0 :                           zqin,     zSin,     &
     781           0 :                           zTin,     zTsn,     &
     782           0 :                           phi,      dt,       &
     783             :                           hilyr,    hslyr,    &
     784           0 :                           km,       ks,       &
     785           0 :                           Iswabs,   Sswabs,   &
     786             :                           Tbot,               &
     787             :                           fswint,   fswsfc,   &
     788             :                           rhoa,     flw,      &
     789             :                           potT,     Qa,       &
     790             :                           shcoef,   lhcoef,   &
     791             :                           fcondtop, fcondbot, &
     792             :                           fadvheat,           &
     793             :                           flwoutn,  fsensn,   &
     794             :                           flatn,    fsurfn,   &
     795             :                           qpond,    qocn,     &
     796             :                           Spond,    sss,      &
     797           0 :                           q,        dSdt,     &
     798      582076 :                           w                   )
     799     1204160 :        if (icepack_warnings_aborted(subname)) return
     800             : 
     801             :        ! halt if solver failed
     802      582076 :        if (icepack_warnings_aborted(subname)) return
     803             : 
     804             :        ! check if solution is consistent - surface should still be cold
     805      582076 :        if (Tsf < Tmlt + dTemp_errmax) then
     806             : 
     807             :           ! solution is consistent - have solution so finish
     808      425483 :           return
     809             : 
     810             :        else
     811             :           ! solution is inconsistent - surface is warmer than melting 
     812             :           ! resolve assuming surface is melting
     813      156593 :           Tsf1 = Tsf
     814             : 
     815             :           ! reset the solution to initial values
     816      156593 :           Tsf  = liquidus_temperature_mush(zSin0(1))
     817     1252744 :           zqin = zqin0
     818     1252744 :           zSin = zSin0
     819             : 
     820             :           ! solve the system for melt and no snow
     821             :           call picard_solver(nilyr,    nslyr,    &
     822             :                              .false.,  .false.,  &
     823           0 :                              Tsf,      zqsn,     &
     824           0 :                              zqin,     zSin,     &
     825           0 :                              zTin,     zTsn,     &
     826           0 :                              phi,      dt,       &
     827             :                              hilyr,    hslyr,    &
     828           0 :                              km,       ks,       &
     829           0 :                              Iswabs,   Sswabs,   &
     830             :                              Tbot,               &
     831             :                              fswint,   fswsfc,   &
     832             :                              rhoa,     flw,      & 
     833             :                              potT,     Qa,       &
     834             :                              shcoef,   lhcoef,   &
     835             :                              fcondtop, fcondbot, &
     836             :                              fadvheat,           &
     837             :                              flwoutn,  fsensn,   &
     838             :                              flatn,    fsurfn,   &
     839             :                              qpond,    qocn,     &
     840             :                              Spond,    sss,      &
     841           0 :                              q,        dSdt,     &
     842      156593 :                              w                   )
     843      156593 :           if (icepack_warnings_aborted(subname)) return
     844             : 
     845             :           ! halt if solver failed
     846      156593 :           if (icepack_warnings_aborted(subname)) return
     847             : 
     848             :           ! check if solution is consistent 
     849             :           ! surface conductive heat flux should be less than 
     850             :           ! incoming surface heat flux
     851      156593 :           if (fcondtop - fsurfn < ferrmax) then
     852             : 
     853             :              ! solution is consistent - have solution so finish
     854      156593 :              return
     855             : 
     856             :           else
     857             : 
     858             :              ! solution is inconsistent
     859           0 :              call two_stage_inconsistency(3, Tsf1, Tmlt, fcondtop, fsurfn)
     860           0 :              if (icepack_warnings_aborted(subname)) return
     861           0 :              call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
     862           0 :              call icepack_warnings_add(subname//" two_stage_solver_nosnow: two_stage_inconsistency: cold" ) 
     863           0 :              return
     864             : 
     865             :           endif
     866             : 
     867             :        endif
     868             : 
     869             :     else
     870             :        ! initially melting
     871             : 
     872             :        ! solve the system for melt and no snow
     873       40008 :        Tsf = Tmlt       
     874             : 
     875             :        call picard_solver(nilyr,    nslyr,    &
     876             :                           .false.,  .false.,  &
     877           0 :                           Tsf,      zqsn,     &
     878           0 :                           zqin,     zSin,     &
     879           0 :                           zTin,     zTsn,     &
     880           0 :                           phi,      dt,       &
     881             :                           hilyr,    hslyr,    &
     882           0 :                           km,       ks,       &
     883           0 :                           Iswabs,   Sswabs,   &
     884             :                           Tbot,               &
     885             :                           fswint,   fswsfc,   &
     886             :                           rhoa,     flw,      &
     887             :                           potT,     Qa,       &
     888             :                           shcoef,   lhcoef,   &
     889             :                           fcondtop, fcondbot, &
     890             :                           fadvheat,           &
     891             :                           flwoutn,  fsensn,   &
     892             :                           flatn,    fsurfn,   &
     893             :                           qpond,    qocn,     &
     894             :                           Spond,    sss,      &
     895           0 :                           q,        dSdt,     &
     896       40008 :                           w                   )
     897       40008 :        if (icepack_warnings_aborted(subname)) return
     898             : 
     899             :        ! halt if solver failed
     900       40008 :        if (icepack_warnings_aborted(subname)) return
     901             : 
     902             :        ! check if solution is consistent 
     903             :        ! surface conductive heat flux should be less than 
     904             :        ! incoming surface heat flux
     905       40008 :        if (fcondtop - fsurfn < ferrmax) then
     906             : 
     907             :           ! solution is consistent - have solution so finish
     908       39949 :           return
     909             : 
     910             :        else
     911             : 
     912             :           ! solution is inconsistent - resolve assuming other surface condition
     913             :           ! assume surface is cold
     914          59 :           fcondtop1 = fcondtop
     915          59 :           fsurfn1   = fsurfn
     916             : 
     917             :           ! reset the solution to initial values
     918          59 :           Tsf  = Tsf0
     919         472 :           zqin = zqin0
     920         472 :           zSin = zSin0
     921             : 
     922             :           ! solve the system for cold and no snow
     923             :           call picard_solver(nilyr,    nslyr,    &
     924             :                              .false.,  .true.,   &
     925           0 :                              Tsf,      zqsn,     &
     926           0 :                              zqin,     zSin,     &
     927           0 :                              zTin,     zTsn,     &
     928           0 :                              phi,      dt,       &
     929             :                              hilyr,    hslyr,    &
     930           0 :                              km,       ks,       &
     931           0 :                              Iswabs,   Sswabs,   &
     932             :                              Tbot,               &
     933             :                              fswint,   fswsfc,   &
     934             :                              rhoa,     flw,      &
     935             :                              potT,     Qa,       &
     936             :                              shcoef,   lhcoef,   &
     937             :                              fcondtop, fcondbot, &
     938             :                              fadvheat,           &
     939             :                              flwoutn,  fsensn,   &
     940             :                              flatn,    fsurfn,   &
     941             :                              qpond,    qocn,     &
     942             :                              Spond,    sss,      &
     943           0 :                              q,        dSdt,     &
     944          59 :                              w                   )
     945          59 :           if (icepack_warnings_aborted(subname)) return
     946             : 
     947             :           ! halt if solver failed
     948          59 :           if (icepack_warnings_aborted(subname)) return
     949             : 
     950             :           ! check if solution is consistent - surface should be cold
     951          59 :           if (Tsf < Tmlt + dTemp_errmax) then
     952             : 
     953             :              ! solution is consistent - have solution so finish
     954          59 :              return
     955             : 
     956             :           else
     957             : 
     958             :              ! solution is inconsistent
     959           0 :              call two_stage_inconsistency(4, Tsf, Tmlt, fcondtop1, fsurfn1)
     960           0 :              if (icepack_warnings_aborted(subname)) return
     961           0 :              call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
     962           0 :              call icepack_warnings_add(subname//" two_stage_solver_nosnow: two_stage_inconsistency: melting" ) 
     963           0 :              return
     964             : 
     965             :           endif
     966             :           
     967             :        endif
     968             : 
     969             :     endif
     970             : 
     971             :   end subroutine two_stage_solver_nosnow
     972             : 
     973             : !=======================================================================
     974             : 
     975           0 :   subroutine two_stage_inconsistency(type, Tsf, Tmlt, fcondtop, fsurfn)
     976             : 
     977             :     integer (kind=int_kind), intent(in) :: &
     978             :          type
     979             : 
     980             :     real(kind=dbl_kind), intent(in) :: &
     981             :          Tsf, &
     982             :          Tmlt, &
     983             :          fcondtop, &
     984             :          fsurfn
     985             : 
     986             :     character(len=*),parameter :: subname='(two_stage_inconsistency)'
     987             : 
     988           0 :     write(warnstr,*) subname, "icepack_therm_mushy: two stage inconsistency"
     989           0 :     call icepack_warnings_add(warnstr)
     990           0 :     write(warnstr,*) subname, "type:", type
     991           0 :     call icepack_warnings_add(warnstr)
     992             : 
     993           0 :     if (type == 1) then
     994             : 
     995           0 :        write(warnstr,*) subname, "First stage  : Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax"
     996           0 :        call icepack_warnings_add(warnstr)
     997           0 :        write(warnstr,*) subname, "             :", Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax
     998           0 :        call icepack_warnings_add(warnstr)
     999           0 :        write(warnstr,*) subname, "Second stage : fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax"
    1000           0 :        call icepack_warnings_add(warnstr)
    1001           0 :        write(warnstr,*) subname, "             :", fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax
    1002           0 :        call icepack_warnings_add(warnstr)
    1003             : 
    1004           0 :     else if (type == 2) then
    1005             : 
    1006           0 :        write(warnstr,*) subname, "First stage  : Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax"
    1007           0 :        call icepack_warnings_add(warnstr)
    1008           0 :        write(warnstr,*) subname, "             :", Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax
    1009           0 :        call icepack_warnings_add(warnstr)
    1010           0 :        write(warnstr,*) subname, "Second stage : fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax"
    1011           0 :        call icepack_warnings_add(warnstr)
    1012           0 :        write(warnstr,*) subname, "             :", fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax
    1013           0 :        call icepack_warnings_add(warnstr)
    1014             : 
    1015           0 :     else if (type == 3) then
    1016             : 
    1017           0 :        write(warnstr,*) subname, "First stage  : Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax"
    1018           0 :        call icepack_warnings_add(warnstr)
    1019           0 :        write(warnstr,*) subname, "             :", Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax
    1020           0 :        call icepack_warnings_add(warnstr)
    1021           0 :        write(warnstr,*) subname, "Second stage : fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax"
    1022           0 :        call icepack_warnings_add(warnstr)
    1023           0 :        write(warnstr,*) subname, "             :", fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax
    1024           0 :        call icepack_warnings_add(warnstr)
    1025             : 
    1026           0 :     else if (type == 4) then
    1027             :        
    1028           0 :        write(warnstr,*) subname, "First stage  : fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax"
    1029           0 :        call icepack_warnings_add(warnstr)
    1030           0 :        write(warnstr,*) subname, "             :", fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax
    1031           0 :        call icepack_warnings_add(warnstr)
    1032           0 :        write(warnstr,*) subname, "Second stage : Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax"
    1033           0 :        call icepack_warnings_add(warnstr)
    1034           0 :        write(warnstr,*) subname, "             :", Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax
    1035           0 :        call icepack_warnings_add(warnstr)
    1036             : 
    1037             :     endif
    1038             : 
    1039           0 :   end subroutine two_stage_inconsistency
    1040             : 
    1041             : !=======================================================================
    1042             : ! Picard/TDMA based solver
    1043             : !=======================================================================
    1044             : 
    1045     3360200 :   subroutine prep_picard(nilyr, nslyr,  &
    1046     3360200 :                          lsnow, zqsn,   &
    1047     3360200 :                          zqin,  zSin,   &
    1048             :                          hilyr, hslyr,  &
    1049     3360200 :                          km,    ks,     &
    1050     6720400 :                          zTin,  zTsn,   &
    1051     3360200 :                          Sbr,   phi,    &
    1052     6720400 :                          dxp,   kcstar, &
    1053             :                          einit)
    1054             : 
    1055             :     integer (kind=int_kind), intent(in) :: &
    1056             :          nilyr , & ! number of ice layers
    1057             :          nslyr     ! number of snow layers
    1058             : 
    1059             :     logical, intent(in) :: &
    1060             :          lsnow      ! snow presence: T: has snow, F: no snow
    1061             : 
    1062             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1063             :          zqin   , & ! ice layer enthalpy (J m-3)
    1064             :          zSin   , & ! ice layer bulk salinity (ppt)
    1065             :          km     , & ! ice conductivity (W m-1 K-1)
    1066             :          zqsn   , & ! snow layer enthalpy (J m-3)
    1067             :          ks         ! snow conductivity (W m-1 K-1)
    1068             : 
    1069             :     real(kind=dbl_kind), intent(in) :: &
    1070             :          hilyr  , & ! ice layer thickness (m)
    1071             :          hslyr      ! snow layer thickness (m)
    1072             : 
    1073             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    1074             :          zTin   , & ! ice layer temperature (C)
    1075             :          Sbr    , & ! ice layer brine salinity (ppt)
    1076             :          phi    , & ! ice layer liquid fraction
    1077             :          zTsn   , & ! snow layer temperature (C)
    1078             :          dxp    , & ! distances between grid points (m)
    1079             :          kcstar     ! interface conductivities  (W m-1 K-1)
    1080             : 
    1081             :     real(kind=dbl_kind), intent(out) :: &
    1082             :          einit      ! initial total energy (J)
    1083             : 
    1084             :     integer(kind=int_kind) :: k
    1085             : 
    1086             :     character(len=*),parameter :: subname='(prep_picard)'
    1087             : 
    1088             :     ! calculate initial ice temperatures
    1089    26881600 :     do k = 1, nilyr
    1090    23521400 :        zTin(k) = icepack_mushy_temperature_mush(zqin(k), zSin(k))
    1091    23521400 :        Sbr(k)  = liquidus_brine_salinity_mush(zTin(k))
    1092    26881600 :        phi(k)  = icepack_mushy_liquid_fraction(zTin(k), zSin(k))
    1093             :     enddo ! k
    1094             : 
    1095     3360200 :     if (lsnow) then
    1096             : 
    1097     5162928 :        do k = 1, nslyr
    1098     5162928 :           zTsn(k) = temperature_snow(zqsn(k))
    1099             :        enddo ! k
    1100             : 
    1101             :     endif ! lsnow
    1102             : 
    1103             :     ! interface distances
    1104     3360200 :     call calc_intercell_thickness(nilyr, nslyr, lsnow, hilyr, hslyr, dxp)
    1105     3360200 :     if (icepack_warnings_aborted(subname)) return
    1106             : 
    1107             :     ! interface conductivities
    1108             :     call calc_intercell_conductivity(lsnow, nilyr, nslyr, &
    1109     3360200 :                                      km, ks, hilyr, hslyr, kcstar)
    1110     3360200 :     if (icepack_warnings_aborted(subname)) return
    1111             : 
    1112             :     ! total energy content
    1113             :     call total_energy_content(lsnow,        &
    1114             :                               nilyr, nslyr, &
    1115           0 :                               zqin,  zqsn,  &
    1116             :                               hilyr, hslyr, &
    1117     3360200 :                               einit)
    1118     3360200 :     if (icepack_warnings_aborted(subname)) return
    1119             : 
    1120             :   end subroutine prep_picard
    1121             : 
    1122             : !=======================================================================
    1123             : 
    1124     3360200 :   subroutine picard_solver(nilyr,    nslyr,    &
    1125             :                            lsnow,    lcold,    &
    1126     3360200 :                            Tsf,      zqsn,     &
    1127     3360200 :                            zqin,     zSin,     &
    1128     3360200 :                            zTin,     zTsn,     &
    1129     3360200 :                            phi,      dt,       &
    1130             :                            hilyr,    hslyr,    &
    1131     3360200 :                            km,       ks,       &
    1132     3360200 :                            Iswabs,   Sswabs,   &
    1133             :                            Tbot,               &
    1134             :                            fswint,   fswsfc,   &
    1135             :                            rhoa,     flw,      &
    1136             :                            potT,     Qa,       &
    1137             :                            shcoef,   lhcoef,   &
    1138             :                            fcondtop, fcondbot, &
    1139             :                            fadvheat,           &
    1140             :                            flwoutn,  fsensn,   &
    1141             :                            flatn,    fsurfn,   &
    1142             :                            qpond,    qocn,     &
    1143             :                            Spond,    sss,      &
    1144     6720400 :                            q,        dSdt,     &
    1145             :                            w                   )
    1146             : 
    1147             :     integer (kind=int_kind), intent(in) :: &
    1148             :          nilyr , & ! number of ice layers
    1149             :          nslyr     ! number of snow layers
    1150             : 
    1151             :     logical, intent(in) :: &
    1152             :          lsnow         , & ! snow presence: T: has snow, F: no snow
    1153             :          lcold             ! surface cold: T: surface is cold, F: surface is melting
    1154             : 
    1155             :     real(kind=dbl_kind), intent(inout) :: &
    1156             :          Tsf               ! snow surface temperature (C)
    1157             : 
    1158             :     real(kind=dbl_kind), intent(out) :: &
    1159             :          fcondtop      , & ! downward cond flux at top surface (W m-2)
    1160             :          fcondbot      , & ! downward cond flux at bottom surface (W m-2)
    1161             :          fadvheat          ! flow of heat to ocean due to advection (W m-2)
    1162             : 
    1163             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    1164             :          zqin          , & ! ice layer enthalpy (J m-3)
    1165             :          zSin          , & ! ice layer bulk salinity (ppt)
    1166             :          zTin          , & ! ice layer temperature (C)
    1167             :          phi           , & ! ice layer liquid fraction
    1168             :          zqsn          , & ! snow layer enthalpy (J m-3)
    1169             :          zTsn              ! snow layer temperature (C)
    1170             : 
    1171             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1172             :          km            , & ! ice conductivity (W m-1 K-1)
    1173             :          Iswabs        , & ! SW radiation absorbed in ice layers (W m-2)
    1174             :          dSdt              ! gravity drainage desalination rate for slow mode (ppt s-1)
    1175             : 
    1176             :     real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
    1177             :          q                 ! upward interface vertical Darcy flow (m s-1)
    1178             : 
    1179             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1180             :          ks            , & ! snow conductivity (W m-1 K-1)
    1181             :          Sswabs            ! SW radiation absorbed in snow layers (W m-2)
    1182             : 
    1183             :     real(kind=dbl_kind), intent(out) :: &
    1184             :          flwoutn       , & ! upward LW at surface (W m-2)
    1185             :          fsensn        , & ! surface downward sensible heat (W m-2)
    1186             :          flatn         , & ! surface downward latent heat (W m-2)
    1187             :          fsurfn            ! net flux to top surface, excluding fcondtop
    1188             : 
    1189             :     real(kind=dbl_kind), intent(in) :: &
    1190             :          dt            , & ! time step (s)
    1191             :          hilyr         , & ! ice layer thickness (m)
    1192             :          hslyr         , & ! snow layer thickness (m)
    1193             :          Tbot          , & ! ice bottom surfce temperature (deg C)
    1194             :          fswint        , & ! SW absorbed in ice interior below surface (W m-2)
    1195             :          fswsfc        , & ! SW absorbed at ice/snow surface (W m-2)
    1196             :          rhoa          , & ! air density (kg/m^3)
    1197             :          flw           , & ! incoming longwave radiation (W/m^2)
    1198             :          potT          , & ! air potential temperature (K)
    1199             :          Qa            , & ! specific humidity (kg/kg)
    1200             :          shcoef        , & ! transfer coefficient for sensible heat
    1201             :          lhcoef        , & ! transfer coefficient for latent heat
    1202             :          qpond         , & ! melt pond brine enthalpy (J m-3)
    1203             :          qocn          , & ! ocean brine enthalpy (J m-3)
    1204             :          Spond         , & ! melt pond salinity (ppt)
    1205             :          sss           , & ! sea surface salinity (ppt)
    1206             :          w                 ! vertical flushing Darcy velocity (m/s)
    1207             :       
    1208             :     real(kind=dbl_kind), dimension(nilyr) :: &
    1209    13552372 :          Sbr           , & ! ice layer brine salinity (ppt)
    1210    13552372 :          qbr           , & ! ice layer brine enthalpy (J m-3)
    1211    13552372 :          zTin0         , & ! ice layer temperature (C) at start of timestep
    1212    13552372 :          zqin0         , & ! ice layer enthalpy (J m-3) at start of timestep
    1213    13552372 :          zSin0         , & ! ice layer bulk salinity (ppt) at start of timestep
    1214    13552372 :          zTin_prev         ! ice layer temperature at previous iteration
    1215             :     
    1216             :     real(kind=dbl_kind), dimension(nslyr) :: &
    1217     6720400 :          zqsn0         , & ! snow layer enthalpy (J m-3) at start of timestep
    1218     6720400 :          zTsn0         , & ! snow layer temperature (C) at start of timestep
    1219     6720400 :          zTsn_prev         ! snow layer temperature at previous iteration
    1220             : 
    1221             :     real(kind=dbl_kind), dimension(nslyr+nilyr+1) :: &
    1222    18107020 :          dxp           , & ! distances between grid points (m)
    1223    15885482 :          kcstar            ! interface conductivities (W m-1 K-1)
    1224             : 
    1225             :     real(kind=dbl_kind) :: &
    1226     1138662 :          Tsf0          , & ! snow surface temperature (C) at start of timestep
    1227     1138662 :          dfsurfn_dTsf  , & ! derivative of net flux to top surface, excluding fcondtopn
    1228     1138662 :          dflwoutn_dTsf , & ! derivative of longwave flux wrt surface temperature
    1229     1138662 :          dfsensn_dTsf  , & ! derivative of sensible heat flux wrt surface temperature
    1230     1138662 :          dflatn_dTsf   , & ! derivative of latent heat flux wrt surface temperature
    1231     1138662 :          Tsf_prev      , & ! snow surface temperature at previous iteration
    1232     1138662 :          einit         , & ! initial total energy (J)
    1233     1138662 :          fadvheat_nit      ! heat to ocean due to advection (W m-2) during iteration
    1234             : 
    1235             :     logical :: &
    1236             :          lconverged        ! has Picard solver converged?
    1237             : 
    1238             :     integer :: &
    1239             :          nit               ! Picard iteration count
    1240             : 
    1241             :     integer, parameter :: &
    1242             :          nit_max = 100     ! maximum number of Picard iterations
    1243             : 
    1244             :     character(len=*),parameter :: subname='(picard_solver)'
    1245             : 
    1246     3360200 :     lconverged = .false.
    1247             : 
    1248             :     ! prepare quantities for picard iteration
    1249             :     call prep_picard(nilyr, nslyr,  &
    1250           0 :                      lsnow, zqsn,   &
    1251           0 :                      zqin,  zSin,   &
    1252             :                      hilyr, hslyr,  &
    1253           0 :                      km,    ks,     &
    1254           0 :                      zTin,  zTsn,   &
    1255           0 :                      Sbr,   phi,    &
    1256           0 :                      dxp,   kcstar, &
    1257     3360200 :                      einit)
    1258     3360200 :     if (icepack_warnings_aborted(subname)) return
    1259             : 
    1260     3360200 :     Tsf0  = Tsf
    1261    26881600 :     zqin0 = zqin
    1262     6720400 :     zqsn0 = zqsn
    1263    26881600 :     zTin0 = zTin
    1264     6720400 :     zTsn0 = zTsn
    1265    26881600 :     zSin0 = zSin
    1266             : 
    1267             :     ! set prev variables
    1268     3360200 :     Tsf_prev  = Tsf
    1269     6720400 :     zTsn_prev = zTsn
    1270    26881600 :     zTin_prev = zTin
    1271             : 
    1272             :     ! picard iteration
    1273     6961823 :     picard: do nit = 1, nit_max
    1274             : 
    1275             :        ! surface heat flux
    1276             :        call surface_heat_flux(Tsf,     fswsfc, &
    1277             :                               rhoa,    flw,    &
    1278             :                               potT,    Qa,     &
    1279             :                               shcoef,  lhcoef, &
    1280             :                               flwoutn, fsensn, &
    1281     6961823 :                               flatn,   fsurfn)
    1282     6961823 :        if (icepack_warnings_aborted(subname)) return
    1283             : 
    1284             :        ! derivative of heat flux with respect to surface temperature
    1285             :        call dsurface_heat_flux_dTsf(Tsf,          rhoa,          &
    1286             :                                     shcoef,       lhcoef,        &
    1287             :                                     dfsurfn_dTsf, dflwoutn_dTsf, &
    1288     6961823 :                                     dfsensn_dTsf, dflatn_dTsf)
    1289     6961823 :        if (icepack_warnings_aborted(subname)) return
    1290             : 
    1291             :        ! tridiagonal solve of new temperatures
    1292             :        call solve_heat_conduction(lsnow,     lcold,        &
    1293             :                                   nilyr,     nslyr,        &
    1294             :                                   Tsf,       Tbot,         &
    1295           0 :                                   zqin0,     zqsn0,        &
    1296           0 :                                   phi,       dt,           &
    1297             :                                   qpond,     qocn,         &
    1298             :                                   q,         w,            &
    1299             :                                   hilyr,     hslyr,        &
    1300           0 :                                   dxp,       kcstar,       &
    1301           0 :                                   Iswabs,    Sswabs,       &
    1302             :                                   fsurfn,    dfsurfn_dTsf, &
    1303     6961823 :                                   zTin,      zTsn)
    1304     6961823 :        if (icepack_warnings_aborted(subname)) return
    1305             : 
    1306             :        ! update brine enthalpy
    1307     6961823 :        call picard_updates_enthalpy(nilyr, zTin, qbr)
    1308     6961823 :        if (icepack_warnings_aborted(subname)) return
    1309             : 
    1310             :        ! drainage fluxes
    1311             :        call picard_drainage_fluxes(fadvheat_nit, q,    &
    1312           0 :                                    qbr,          qocn, &
    1313     6961823 :                                    nilyr)
    1314     6961823 :        if (icepack_warnings_aborted(subname)) return
    1315             : 
    1316             :        ! flushing fluxes
    1317             :        call picard_flushing_fluxes(nilyr,           &
    1318             :                                    fadvheat_nit, w, &
    1319           0 :                                    qbr,             &
    1320     6961823 :                                    qpond)
    1321     6961823 :        if (icepack_warnings_aborted(subname)) return
    1322             : 
    1323             :        ! perform convergence check
    1324             :        call check_picard_convergence(nilyr,      nslyr,    &
    1325             :                                      lsnow,                &
    1326             :                                      lconverged, & 
    1327             :                                      Tsf,        Tsf_prev, &
    1328           0 :                                      zTin,       zTin_prev,&
    1329           0 :                                      zTsn,       zTsn_prev,&
    1330           0 :                                      phi,        Tbot,     &
    1331           0 :                                      zqin,       zqsn,     &
    1332           0 :                                      km,         ks,       &
    1333             :                                      hilyr,      hslyr,    &
    1334             :                                      fswint,               &
    1335             :                                      einit,      dt,       &
    1336             :                                      fcondtop,   fcondbot, &
    1337     6961823 :                                      fadvheat_nit)
    1338     6961823 :        if (icepack_warnings_aborted(subname)) return
    1339             : 
    1340     6961823 :        if (lconverged) exit
    1341             : 
    1342     3601623 :        Tsf_prev  = Tsf
    1343     7203246 :        zTsn_prev = zTsn
    1344    32173184 :        zTin_prev = zTin
    1345             : 
    1346             :     enddo picard
    1347             : 
    1348     3360200 :     fadvheat = fadvheat_nit
    1349             : 
    1350             :     ! update the picard iterants
    1351           0 :     call picard_updates(nilyr, zTin, &
    1352     3360200 :                         Sbr, qbr)
    1353     3360200 :     if (icepack_warnings_aborted(subname)) return
    1354             :     
    1355             :     ! solve for the salinity
    1356           0 :     call solve_salinity(zSin,  Sbr,   &
    1357             :                         Spond, sss,   &
    1358           0 :                         q,     dSdt,  &
    1359             :                         w,     hilyr, &
    1360     3360200 :                         dt,    nilyr)
    1361     3360200 :     if (icepack_warnings_aborted(subname)) return
    1362             : 
    1363             :     ! final surface heat flux
    1364             :     call surface_heat_flux(Tsf,     fswsfc, &
    1365             :                            rhoa,    flw,    &
    1366             :                            potT,    Qa,     &
    1367             :                            shcoef,  lhcoef, &
    1368             :                            flwoutn, fsensn, &
    1369     3360200 :                            flatn,   fsurfn)
    1370     3360200 :     if (icepack_warnings_aborted(subname)) return
    1371             : 
    1372             :     ! if not converged
    1373     3360200 :     if (.not. lconverged) then
    1374             : 
    1375             :        call picard_nonconvergence(nilyr, nslyr,&
    1376             :                                   Tsf0,  Tsf,  &
    1377           0 :                                   zTsn0, zTsn, &
    1378           0 :                                   zTin0, zTin, &
    1379           0 :                                   zSin0, zSin, &
    1380           0 :                                   zqsn0, zqsn, &
    1381           0 :                                   zqin0, zqin, &
    1382           0 :                                   phi)
    1383           0 :        if (icepack_warnings_aborted(subname)) return
    1384           0 :        call icepack_warnings_add(subname//" picard_solver: Picard solver non-convergence" ) 
    1385           0 :        call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    1386           0 :        if (icepack_warnings_aborted(subname)) return
    1387             : 
    1388             :     endif
    1389             : 
    1390             :   end subroutine picard_solver
    1391             : 
    1392             : !=======================================================================
    1393             : 
    1394           0 :   subroutine picard_nonconvergence(nilyr, nslyr,&
    1395             :                                    Tsf0,  Tsf,  &
    1396           0 :                                    zTsn0, zTsn, &
    1397           0 :                                    zTin0, zTin, &
    1398           0 :                                    zSin0, zSin, &
    1399           0 :                                    zqsn0, zqsn, &
    1400           0 :                                    zqin0, zqin, phi)
    1401             : 
    1402             :     integer (kind=int_kind), intent(in) :: &
    1403             :          nilyr , & ! number of ice layers
    1404             :          nslyr     ! number of snow layers
    1405             : 
    1406             :     real(kind=dbl_kind), intent(in) :: &
    1407             :          Tsf0  , & ! snow surface temperature (C) at beginning of timestep
    1408             :          Tsf       ! snow surface temperature (C)
    1409             : 
    1410             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1411             :          zTsn0 , & ! snow layer temperature (C) at beginning of timestep
    1412             :          zTsn  , & ! snow layer temperature (C)
    1413             :          zqsn0 , &
    1414             :          zqsn  , &
    1415             :          zTin0 , & ! ice layer temperature (C)
    1416             :          zTin  , & ! ice layer temperature (C)
    1417             :          zSin0 , & ! ice layer bulk salinity (ppt)
    1418             :          zSin  , & ! ice layer bulk salinity (ppt)
    1419             :          zqin0 , & 
    1420             :          zqin  , & 
    1421             :          phi       ! ice layer liquid fraction
    1422             : 
    1423             :     integer :: &
    1424             :          k        ! vertical layer index
    1425             : 
    1426             :     character(len=*),parameter :: subname='(picard_nonconvergence)'
    1427             : 
    1428           0 :     write(warnstr,*) subname, "-------------------------------------"
    1429           0 :     call icepack_warnings_add(warnstr)
    1430             : 
    1431           0 :     write(warnstr,*) subname, "picard convergence failed!"
    1432           0 :     call icepack_warnings_add(warnstr)
    1433           0 :     write(warnstr,*) subname, 0, Tsf0, Tsf
    1434           0 :     call icepack_warnings_add(warnstr)
    1435             :     
    1436           0 :     do k = 1, nslyr
    1437           0 :        write(warnstr,*) subname, k, zTsn0(k), zTsn(k), zqsn(k), zqsn0(k)
    1438           0 :        call icepack_warnings_add(warnstr)
    1439             :     enddo ! k          
    1440             :     
    1441           0 :     do k = 1, nilyr
    1442           0 :        write(warnstr,*) subname, k, zTin0(k), zTin(k), zSin0(k), zSin(k), phi(k), zqin(k), zqin0(k)
    1443           0 :        call icepack_warnings_add(warnstr)
    1444             :     enddo ! k
    1445             : 
    1446           0 :     write(warnstr,*) subname, "-------------------------------------"
    1447           0 :     call icepack_warnings_add(warnstr)
    1448             : 
    1449           0 :   end subroutine picard_nonconvergence
    1450             : 
    1451             : !=======================================================================
    1452             :   
    1453     6961823 :   subroutine check_picard_convergence(nilyr,      nslyr,    &
    1454             :                                       lsnow,                &
    1455             :                                       lconverged, & 
    1456             :                                       Tsf,        Tsf_prev, &
    1457    13923646 :                                       zTin,       zTin_prev,&
    1458    13923646 :                                       zTsn,       zTsn_prev,&
    1459     6961823 :                                       phi,        Tbot,     &
    1460     6961823 :                                       zqin,       zqsn,     &
    1461     6961823 :                                       km,         ks,       &
    1462             :                                       hilyr,      hslyr,    &
    1463             :                                       fswint,               &
    1464             :                                       einit,      dt,       &
    1465             :                                       fcondtop,   fcondbot, &
    1466             :                                       fadvheat)
    1467             : 
    1468             :     integer (kind=int_kind), intent(in) :: &
    1469             :          nilyr , & ! number of ice layers
    1470             :          nslyr     ! number of snow layers
    1471             : 
    1472             :     logical, intent(inout) :: &
    1473             :          lconverged   ! has Picard solver converged?
    1474             : 
    1475             :     logical, intent(in) :: &
    1476             :          lsnow        ! snow presence: T: has snow, F: no snow
    1477             : 
    1478             :     real(kind=dbl_kind), intent(in) :: &
    1479             :          dt       , & ! time step (s)
    1480             :          Tsf      , & ! snow surface temperature (C)
    1481             :          Tsf_prev , & ! snow surface temperature at previous iteration
    1482             :          hilyr    , & ! ice layer thickness (m)
    1483             :          hslyr    , & ! snow layer thickness (m)
    1484             :          fswint   , & ! SW absorbed in ice interior below surface (W m-2)
    1485             :          einit    , & ! initial total energy (J)
    1486             :          Tbot     , & ! ice bottom surfce temperature (deg C)
    1487             :          fadvheat     ! flow of heat to ocean due to advection (W m-2)
    1488             : 
    1489             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1490             :          zTin     , & ! ice layer temperature (C)
    1491             :          zTin_prev, & ! ice layer temperature at previous iteration
    1492             :          phi      , & ! ice layer liquid fraction
    1493             :          km           ! ice conductivity (W m-1 K-1)
    1494             : 
    1495             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    1496             :          zqin         ! ice layer enthalpy (J m-3)
    1497             : 
    1498             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1499             :          zTsn     , & ! snow layer temperature (C)
    1500             :          zTsn_prev, & ! snow layer temperature at previous iteration
    1501             :          ks           ! snow conductivity (W m-1 K-1)
    1502             : 
    1503             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    1504             :          zqsn         ! snow layer enthalpy (J m-3)
    1505             : 
    1506             :     real(kind=dbl_kind), intent(out) :: &    
    1507             :          fcondtop , & ! downward cond flux at top surface (W m-2)
    1508             :          fcondbot     ! downward cond flux at bottom surface (W m-2)
    1509             : 
    1510             :     real(kind=dbl_kind) :: &
    1511     2360783 :          ferr     , & ! energy flux error
    1512     2360783 :          efinal   , & ! initial total energy (J) at iteration
    1513     2360783 :          dzTsn    , & ! change in snow temperature (C) between iterations
    1514     2360783 :          dzTin    , & ! change in ice temperature (C) between iterations
    1515     2360783 :          dTsf         ! change in surface temperature (C) between iterations
    1516             : 
    1517             :     character(len=*),parameter :: subname='(check_picard_convergence)'
    1518             : 
    1519             :     call picard_final(lsnow,        &
    1520             :                       nilyr, nslyr, &
    1521           0 :                       zqin,  zqsn,  &
    1522           0 :                       zTin,  zTsn,  &
    1523     6961823 :                       phi)
    1524     6961823 :     if (icepack_warnings_aborted(subname)) return
    1525             : 
    1526             :     call total_energy_content(lsnow,         &
    1527             :                               nilyr,  nslyr, &
    1528           0 :                               zqin,   zqsn,  &
    1529             :                               hilyr,  hslyr, &
    1530     6961823 :                               efinal)
    1531     6961823 :     if (icepack_warnings_aborted(subname)) return
    1532             : 
    1533             :     call maximum_variables_changes(lsnow,                  &
    1534             :                                    Tsf,  Tsf_prev,  dTsf,  &
    1535           0 :                                    zTsn, zTsn_prev, dzTsn, & 
    1536     6961823 :                                    zTin, zTin_prev, dzTin)
    1537     6961823 :     if (icepack_warnings_aborted(subname)) return
    1538             : 
    1539     6961823 :     fcondbot = c2 * km(nilyr) * ((zTin(nilyr) - Tbot) / hilyr)
    1540             : 
    1541     6961823 :     if (lsnow) then
    1542     5271794 :        fcondtop = c2 * ks(1) * ((Tsf - zTsn(1)) / hslyr)
    1543             :     else
    1544     1690029 :        fcondtop = c2 * km(1) * ((Tsf - zTin(1)) / hilyr)
    1545             :     endif
    1546             : 
    1547     6961823 :     ferr = (efinal - einit) / dt - (fcondtop - fcondbot + fswint - fadvheat)
    1548             : 
    1549             :     lconverged = (dTsf  < dTemp_errmax .and. &
    1550             :                   dzTsn < dTemp_errmax .and. &
    1551             :                   dzTin < dTemp_errmax .and. &
    1552     6961823 :                   abs(ferr) < 0.9_dbl_kind*ferrmax)
    1553             : 
    1554             :   end subroutine check_picard_convergence
    1555             : 
    1556             : !=======================================================================
    1557             : 
    1558     6961823 :   subroutine picard_drainage_fluxes(fadvheat, q,    &
    1559     6961823 :                                     qbr,      qocn, &
    1560             :                                     nilyr)
    1561             : 
    1562             :     integer (kind=int_kind), intent(in) :: &
    1563             :          nilyr        ! number of ice layers
    1564             : 
    1565             :     real(kind=dbl_kind), intent(out) :: &
    1566             :          fadvheat ! flow of heat to ocean due to advection (W m-2)
    1567             : 
    1568             :     real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &    
    1569             :          q        ! upward interface vertical Darcy flow (m s-1)
    1570             : 
    1571             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1572             :          qbr      ! ice layer brine enthalpy (J m-3)
    1573             : 
    1574             :     real(kind=dbl_kind), intent(in) :: &
    1575             :          qocn     ! ocean brine enthalpy (J m-3)
    1576             : 
    1577             :     integer :: &
    1578             :          k        ! vertical layer index
    1579             : 
    1580             :     character(len=*),parameter :: subname='(picard_drainage_fluxes)'
    1581             : 
    1582     6961823 :     fadvheat = c0
    1583             : 
    1584             :     ! calculate fluxes from base upwards
    1585    48732761 :     do k = 1, nilyr-1
    1586             : 
    1587    48732761 :        fadvheat = fadvheat - q(k) * (qbr(k+1) - qbr(k))
    1588             : 
    1589             :     enddo ! k
    1590             : 
    1591     6961823 :     k = nilyr
    1592             : 
    1593     6961823 :     fadvheat = fadvheat - q(k) * (qocn - qbr(k))
    1594             : 
    1595     6961823 :   end subroutine picard_drainage_fluxes
    1596             : 
    1597             : !=======================================================================
    1598             : 
    1599     6961823 :   subroutine picard_flushing_fluxes(nilyr,         &
    1600             :                                     fadvheat, w,   &
    1601     6961823 :                                     qbr,           &
    1602             :                                     qpond)
    1603             : 
    1604             :     integer (kind=int_kind), intent(in) :: &
    1605             :          nilyr        ! number of ice layers
    1606             : 
    1607             :     real(kind=dbl_kind), intent(inout) :: &
    1608             :          fadvheat  ! flow of heat to ocean due to advection (W m-2)
    1609             : 
    1610             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1611             :          qbr       ! ice layer brine enthalpy (J m-3)
    1612             : 
    1613             :     real(kind=dbl_kind), intent(in) :: &
    1614             :          w     , & ! vertical flushing Darcy velocity (m/s)
    1615             :          qpond     ! melt pond brine enthalpy (J m-3)
    1616             : 
    1617             :     character(len=*),parameter :: subname='(picard_flushing_fluxes)'
    1618             : 
    1619     6961823 :     fadvheat = fadvheat + w * (qbr(nilyr) - qpond)
    1620             : 
    1621     6961823 :   end subroutine picard_flushing_fluxes
    1622             : 
    1623             : !=======================================================================
    1624             : 
    1625     6961823 :   subroutine maximum_variables_changes(lsnow,                  &
    1626             :                                        Tsf,  Tsf_prev,  dTsf,  &
    1627     6961823 :                                        zTsn, zTsn_prev, dzTsn, & 
    1628     6961823 :                                        zTin, zTin_prev, dzTin)
    1629             : 
    1630             :     logical, intent(in) :: &
    1631             :          lsnow        ! snow presence: T: has snow, F: no snow
    1632             : 
    1633             :     real(kind=dbl_kind), intent(in) :: &
    1634             :          Tsf      , & ! snow surface temperature (C)
    1635             :          Tsf_prev     ! snow surface temperature at previous iteration
    1636             : 
    1637             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1638             :          zTsn     , & ! snow layer temperature (C)
    1639             :          zTsn_prev, & ! snow layer temperature at previous iteration
    1640             :          zTin     , & ! ice layer temperature (C)
    1641             :          zTin_prev    ! ice layer temperature at previous iteration
    1642             : 
    1643             :     real(kind=dbl_kind), intent(out) :: &
    1644             :          dTsf     , & ! change in surface temperature (C) between iterations
    1645             :          dzTsn    , & ! change in snow temperature (C) between iterations
    1646             :          dzTin        ! change in surface temperature (C) between iterations
    1647             : 
    1648             :     character(len=*),parameter :: subname='(maximum_variables_changes)'
    1649             : 
    1650     6961823 :     dTsf = abs(Tsf - Tsf_prev)
    1651             : 
    1652     6961823 :     if (lsnow) then
    1653    10543588 :        dzTsn = maxval(abs(zTsn - zTsn_prev))
    1654             :     else ! lsnow
    1655     1690029 :        dzTsn = c0 
    1656             :     endif ! lsnow
    1657             : 
    1658    55694584 :     dzTin = maxval(abs(zTin - zTin_prev))
    1659             : 
    1660     6961823 :   end subroutine maximum_variables_changes
    1661             : 
    1662             : !=======================================================================
    1663             : 
    1664    10322023 :   subroutine total_energy_content(lsnow,         &
    1665             :                                   nilyr,  nslyr, &
    1666    10322023 :                                   zqin,   zqsn,  &
    1667             :                                   hilyr,  hslyr, &
    1668             :                                   energy)
    1669             : 
    1670             :     logical, intent(in) :: &
    1671             :          lsnow     ! snow presence: T: has snow, F: no snow
    1672             : 
    1673             :       integer (kind=int_kind), intent(in) :: &
    1674             :          nilyr , & ! number of ice layers
    1675             :          nslyr     ! number of snow layers
    1676             : 
    1677             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1678             :          zqin  , & ! ice layer enthalpy (J m-3)
    1679             :          zqsn      ! snow layer enthalpy (J m-3)
    1680             : 
    1681             :     real(kind=dbl_kind), intent(in) :: &
    1682             :          hilyr , & ! ice layer thickness (m)
    1683             :          hslyr     ! snow layer thickness (m)
    1684             : 
    1685             :     real(kind=dbl_kind), intent(out) :: &    
    1686             :          energy    ! total energy of ice and snow
    1687             : 
    1688             :     integer :: &
    1689             :          k         ! vertical layer index
    1690             : 
    1691             :     character(len=*),parameter :: subname='(total_energy_content)'
    1692             : 
    1693    10322023 :     energy = c0
    1694             :     
    1695    10322023 :     if (lsnow) then
    1696             :        
    1697    15706516 :        do k = 1, nslyr
    1698             : 
    1699    15706516 :           energy = energy + hslyr * zqsn(k)
    1700             : 
    1701             :        enddo ! k
    1702             : 
    1703             :     endif ! lsnow
    1704             : 
    1705    82576184 :     do k = 1, nilyr
    1706             : 
    1707    82576184 :        energy = energy + hilyr * zqin(k)
    1708             : 
    1709             :     enddo ! k
    1710             : 
    1711    10322023 :   end subroutine total_energy_content
    1712             : 
    1713             : !=======================================================================
    1714             : 
    1715     3360200 :   subroutine picard_updates(nilyr, zTin, &
    1716     6720400 :                             Sbr,   qbr)
    1717             : 
    1718             :     ! update brine salinity and liquid fraction based on new temperatures
    1719             : 
    1720             :     integer (kind=int_kind), intent(in) :: &
    1721             :          nilyr   ! number of ice layers
    1722             : 
    1723             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1724             :          zTin    ! ice layer temperature (C)
    1725             : 
    1726             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    1727             :          Sbr , & ! ice layer brine salinity (ppt)
    1728             :          qbr     ! ice layer brine enthalpy (J m-3)
    1729             : 
    1730             :     integer :: &
    1731             :          k       ! vertical layer index
    1732             : 
    1733             :     character(len=*),parameter :: subname='(picard_updates)'
    1734             : 
    1735    26881600 :     do k = 1, nilyr
    1736             : 
    1737    23521400 :        Sbr(k) = liquidus_brine_salinity_mush(zTin(k))
    1738    26881600 :        qbr(k) = enthalpy_brine(zTin(k))
    1739             : 
    1740             :     enddo ! k
    1741             : 
    1742     3360200 :   end subroutine picard_updates
    1743             : 
    1744             : !=======================================================================
    1745             : 
    1746     6961823 :   subroutine picard_updates_enthalpy(nilyr, zTin, qbr)
    1747             : 
    1748             :     ! update brine salinity and liquid fraction based on new temperatures
    1749             : 
    1750             :     integer (kind=int_kind), intent(in) :: &
    1751             :          nilyr   ! number of ice layers
    1752             : 
    1753             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1754             :          zTin ! ice layer temperature (C)
    1755             : 
    1756             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    1757             :          qbr  ! ice layer brine enthalpy (J m-3)
    1758             : 
    1759             :     integer :: &
    1760             :          k    ! vertical layer index
    1761             : 
    1762             :     character(len=*),parameter :: subname='(picard_updates_enthalpy)'
    1763             : 
    1764    55694584 :     do k = 1, nilyr
    1765             : 
    1766    55694584 :        qbr(k) = enthalpy_brine(zTin(k))
    1767             : 
    1768             :     enddo ! k
    1769             : 
    1770     6961823 :   end subroutine picard_updates_enthalpy
    1771             : 
    1772             : !=======================================================================
    1773             : 
    1774     6961823 :   subroutine picard_final(lsnow,        &
    1775             :                           nilyr, nslyr, &
    1776    13923646 :                           zqin,  zqsn,  &
    1777    13923646 :                           zTin,  zTsn,  &
    1778     6961823 :                           phi)
    1779             : 
    1780             :     integer (kind=int_kind), intent(in) :: &
    1781             :          nilyr, & ! number of ice layers
    1782             :          nslyr    ! number of snow layers
    1783             : 
    1784             :     logical, intent(in) :: &
    1785             :          lsnow   ! snow presence: T: has snow, F: no snow
    1786             : 
    1787             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    1788             :          zqin, & ! ice layer enthalpy (J m-3)
    1789             :          zqsn    ! snow layer enthalpy (J m-3)
    1790             : 
    1791             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1792             :          zTin, & ! ice layer temperature (C)
    1793             :          phi , & ! ice layer liquid fraction
    1794             :          zTsn    ! snow layer temperature (C)
    1795             : 
    1796             :     integer :: &
    1797             :          k       ! vertical layer index
    1798             : 
    1799             :     character(len=*),parameter :: subname='(picard_final)'
    1800             : 
    1801    55694584 :     do k = 1, nilyr
    1802    55694584 :        zqin(k) = enthalpy_mush_liquid_fraction(zTin(k), phi(k))
    1803             :     enddo ! k
    1804             : 
    1805     6961823 :     if (lsnow) then
    1806             : 
    1807    10543588 :        do k = 1, nslyr
    1808    10543588 :           zqsn(k) = enthalpy_snow(zTsn(k))
    1809             :        enddo ! k
    1810             : 
    1811             :     endif ! lsnow
    1812             : 
    1813     6961823 :   end subroutine picard_final
    1814             : 
    1815             : !=======================================================================
    1816             : 
    1817     3360200 :   subroutine calc_intercell_thickness(nilyr, nslyr, lsnow, hilyr, hslyr, dxp)
    1818             : 
    1819             :     integer (kind=int_kind), intent(in) :: &
    1820             :          nilyr, & ! number of ice layers
    1821             :          nslyr    ! number of snow layers
    1822             : 
    1823             :     logical, intent(in) :: &
    1824             :          lsnow     ! snow presence: T: has snow, F: no snow
    1825             : 
    1826             :     real(kind=dbl_kind), intent(in) :: &
    1827             :          hilyr , & ! ice layer thickness (m)
    1828             :          hslyr     ! snow layer thickness (m)
    1829             : 
    1830             :     real(kind=dbl_kind), dimension(:), intent(out) :: &
    1831             :          dxp       ! distances between grid points (m)
    1832             : 
    1833             :     integer :: &
    1834             :          l         ! vertical index
    1835             : 
    1836             :     character(len=*),parameter :: subname='(calc_intercell_thickness)'
    1837             : 
    1838     3360200 :     if (lsnow) then
    1839             : 
    1840     2581464 :        dxp(1) = hslyr / c2
    1841             :        
    1842     2581464 :        do l = 2, nslyr
    1843             : 
    1844     2581464 :           dxp(l) = hslyr
    1845             : 
    1846             :        enddo ! l
    1847             : 
    1848     2581464 :        dxp(nslyr+1) = (hilyr + hslyr) / c2
    1849             : 
    1850    18070248 :        do l = nslyr+2, nilyr+nslyr
    1851             : 
    1852    18070248 :           dxp(l) = hilyr
    1853             : 
    1854             :        enddo ! l
    1855             : 
    1856     2581464 :        dxp(nilyr+nslyr+1) = hilyr / c2
    1857             : 
    1858             :     else ! lsnow
    1859             : 
    1860      778736 :        dxp(1) = hilyr / c2
    1861             : 
    1862     5451152 :        do l = 2, nilyr
    1863             : 
    1864     5451152 :           dxp(l) = hilyr
    1865             : 
    1866             :        enddo ! l
    1867             : 
    1868      778736 :        dxp(nilyr+1) = hilyr / c2
    1869             : 
    1870     1557472 :        do l = nilyr+2, nilyr+nslyr+1
    1871             : 
    1872     1557472 :           dxp(l) = c0
    1873             : 
    1874             :        enddo ! l
    1875             : 
    1876             :     endif ! lsnow
    1877             : 
    1878     3360200 :   end subroutine calc_intercell_thickness
    1879             : 
    1880             : !=======================================================================
    1881             : 
    1882     3360200 :   subroutine calc_intercell_conductivity(lsnow,        &
    1883             :                                          nilyr, nslyr, &
    1884     3360200 :                                          km,    ks,    &
    1885             :                                          hilyr, hslyr, &
    1886     3360200 :                                          kcstar)
    1887             : 
    1888             :     integer (kind=int_kind), intent(in) :: &
    1889             :          nilyr, & ! number of ice layers
    1890             :          nslyr    ! number of snow layers
    1891             : 
    1892             :     logical, intent(in) :: &
    1893             :          lsnow      ! snow presence: T: has snow, F: no snow
    1894             : 
    1895             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1896             :          km     , & ! ice conductivity (W m-1 K-1)
    1897             :          ks         ! snow conductivity (W m-1 K-1)
    1898             : 
    1899             :     real(kind=dbl_kind), intent(in) :: &
    1900             :          hilyr  , & ! ice layer thickness (m)
    1901             :          hslyr      ! snow layer thickness (m)
    1902             : 
    1903             :     real(kind=dbl_kind), dimension(:), intent(out) :: &
    1904             :          kcstar     ! interface conductivities (W m-1 K-1)
    1905             : 
    1906             :     real(kind=dbl_kind) :: &
    1907     1138662 :          fe         ! distance fraction at interface
    1908             : 
    1909             :     integer :: &
    1910             :          k, &       ! vertical layer index
    1911             :          l          ! vertical index
    1912             : 
    1913             :     character(len=*),parameter :: subname='(calc_intercell_conductivity)'
    1914             : 
    1915     3360200 :     if (lsnow) then
    1916             : 
    1917     2581464 :        kcstar(1) = ks(1)
    1918             :        
    1919     2581464 :        do l = 2, nslyr
    1920             : 
    1921           0 :           k = l
    1922     2581464 :           kcstar(l) = (c2 * ks(k) * ks(k-1)) / (ks(k) + ks(k-1))
    1923             : 
    1924             :        enddo ! l
    1925             : 
    1926     2581464 :        fe = hilyr / (hilyr + hslyr)
    1927     2581464 :        kcstar(nslyr+1) = c1 / ((c1 - fe) / ks(nslyr) + fe / km(1))
    1928             : 
    1929    18070248 :        do k = 2, nilyr
    1930             : 
    1931    15488784 :           l = k + nslyr
    1932    18070248 :           kcstar(l) = (c2 * km(k) * km(k-1)) / (km(k) + km(k-1))
    1933             : 
    1934             :        enddo ! k
    1935             : 
    1936     2581464 :        kcstar(nilyr+nslyr+1) = km(nilyr)
    1937             : 
    1938             :     else ! lsnow
    1939             : 
    1940      778736 :        kcstar(1) = km(1)
    1941             : 
    1942     5451152 :        do k = 2, nilyr
    1943             :           
    1944     4672416 :           l = k
    1945     5451152 :           kcstar(l) = (c2 * km(k) * km(k-1)) / (km(k) + km(k-1))
    1946             : 
    1947             :        enddo ! k
    1948             : 
    1949      778736 :        kcstar(nilyr+1) = km(nilyr)
    1950             : 
    1951     1557472 :        do l = nilyr+2, nilyr+nslyr+1
    1952             : 
    1953     1557472 :           kcstar(l) = c0
    1954             : 
    1955             :        enddo ! l
    1956             : 
    1957             :     endif ! lsnow
    1958             : 
    1959     3360200 :   end subroutine calc_intercell_conductivity
    1960             : 
    1961             : !=======================================================================
    1962             :   
    1963     6961823 :   subroutine solve_heat_conduction(lsnow,  lcold,        &
    1964             :                                    nilyr,  nslyr,        &
    1965             :                                    Tsf,    Tbot,         &
    1966     6961823 :                                    zqin0,  zqsn0,        &
    1967     6961823 :                                    phi,    dt,           &
    1968             :                                    qpond,  qocn,         &
    1969     6961823 :                                    q,      w,            &
    1970             :                                    hilyr,  hslyr,        &
    1971     6961823 :                                    dxp,    kcstar,       &
    1972     6961823 :                                    Iswabs, Sswabs,       &
    1973             :                                    fsurfn, dfsurfn_dTsf, &
    1974     6961823 :                                    zTin,   zTsn)
    1975             : 
    1976             :     logical, intent(in) :: &
    1977             :          lsnow        , & ! snow presence: T: has snow, F: no snow
    1978             :          lcold            ! surface cold: T: surface is cold, F: surface is melting
    1979             : 
    1980             :     integer (kind=int_kind), intent(in) :: &
    1981             :          nilyr, & ! number of ice layers
    1982             :          nslyr    ! number of snow layers
    1983             : 
    1984             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    1985             :          zqin0        , & ! ice layer enthalpy (J m-3) at beggining of timestep
    1986             :          Iswabs       , & ! SW radiation absorbed in ice layers (W m-2)
    1987             :          phi          , & ! ice layer liquid fraction
    1988             :          zqsn0        , & ! snow layer enthalpy (J m-3) at start of timestep
    1989             :          Sswabs           ! SW radiation absorbed in snow layers (W m-2)
    1990             :     
    1991             :     real(kind=dbl_kind), intent(inout) :: &
    1992             :          Tsf              ! snow surface temperature (C)
    1993             : 
    1994             :     real(kind=dbl_kind), intent(in) :: &
    1995             :          dt           , & ! timestep (s)
    1996             :          hilyr        , & ! ice layer thickness (m)
    1997             :          hslyr        , & ! snow layer thickness (m)
    1998             :          Tbot         , & ! ice bottom surfce temperature (deg C)
    1999             :          qpond        , & ! melt pond brine enthalpy (J m-3)
    2000             :          qocn         , & ! ocean brine enthalpy (J m-3)
    2001             :          w            , & ! vertical flushing Darcy velocity (m/s)
    2002             :          fsurfn       , & ! net flux to top surface, excluding fcondtop
    2003             :          dfsurfn_dTsf     ! derivative of net flux to top surface, excluding fcondtopn
    2004             : 
    2005             :     real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &    
    2006             :          q                ! upward interface vertical Darcy flow (m s-1)
    2007             : 
    2008             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    2009             :          dxp          , & ! distances between grid points (m)
    2010             :          kcstar           ! interface conductivities (W m-1 K-1)
    2011             : 
    2012             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    2013             :          zTin             ! ice layer temperature (C)
    2014             : 
    2015             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    2016             :          zTsn             ! snow layer temperature (C)
    2017             : 
    2018             :     real(kind=dbl_kind), dimension(nilyr+nslyr+1) :: &
    2019    32809910 :          Ap           , & ! diagonal of tridiagonal matrix
    2020    32809910 :          As           , & ! lower off-diagonal of tridiagonal matrix
    2021    37531476 :          An           , & ! upper off-diagonal of tridiagonal matrix
    2022    32809910 :          b            , & ! right hand side of matrix solve
    2023    30569653 :          T                ! ice and snow temperatures
    2024             : 
    2025             :     integer :: &
    2026             :          nyn              ! matrix size
    2027             : 
    2028             :     character(len=*),parameter :: subname='(solve_heat_conduction)'
    2029             : 
    2030             :     ! set up matrix and right hand side - snow
    2031     6961823 :     if (lsnow) then
    2032             : 
    2033     5271794 :        if (lcold) then
    2034             : 
    2035           0 :           call matrix_elements_snow_cold(Ap, As, An, b, nyn,   &
    2036             :                                          nilyr,  nslyr,        &
    2037             :                                          Tsf,    Tbot,         &
    2038           0 :                                          zqin0,  zqsn0,        &
    2039             :                                          qpond,  qocn,         &
    2040           0 :                                          phi,    q,            &
    2041             :                                          w,                    &
    2042             :                                          hilyr,  hslyr,        &
    2043           0 :                                          dxp,    kcstar,       &
    2044           0 :                                          Iswabs, Sswabs,       &
    2045             :                                          fsurfn, dfsurfn_dTsf, &
    2046     5194646 :                                          dt)
    2047     5194646 :           if (icepack_warnings_aborted(subname)) return
    2048             : 
    2049             :        else ! lcold
    2050             : 
    2051           0 :           call matrix_elements_snow_melt(Ap, As, An, b, nyn,   &
    2052             :                                          nilyr,  nslyr,        &
    2053             :                                          Tsf,    Tbot,         &
    2054           0 :                                          zqin0,  zqsn0,        &
    2055             :                                          qpond,  qocn,         &
    2056           0 :                                          phi,    q,            &
    2057             :                                          w,                    &
    2058             :                                          hilyr,  hslyr,        &
    2059           0 :                                          dxp,    kcstar,       &
    2060           0 :                                          Iswabs, Sswabs,       &
    2061       77148 :                                          dt)
    2062       77148 :           if (icepack_warnings_aborted(subname)) return
    2063             : 
    2064             :        endif ! lcold
    2065             : 
    2066             :     else ! lsnow
    2067             : 
    2068     1690029 :        if (lcold) then
    2069             : 
    2070           0 :           call matrix_elements_nosnow_cold(Ap, As, An, b, nyn,   &
    2071             :                                            nilyr, &
    2072             :                                            Tsf,    Tbot,         &
    2073           0 :                                            zqin0,                &
    2074             :                                            qpond,  qocn,         &
    2075           0 :                                            phi,    q,            &
    2076             :                                            w,                    &
    2077             :                                            hilyr,                &
    2078           0 :                                            dxp,    kcstar,       &
    2079           0 :                                            Iswabs,               &
    2080             :                                            fsurfn, dfsurfn_dTsf, &
    2081     1296827 :                                            dt)
    2082     1296827 :           if (icepack_warnings_aborted(subname)) return
    2083             : 
    2084             :        else ! lcold
    2085             : 
    2086           0 :           call matrix_elements_nosnow_melt(Ap, As, An, b, nyn,   &
    2087             :                                            nilyr,  &
    2088             :                                            Tsf,    Tbot,         &
    2089           0 :                                            zqin0,                &
    2090             :                                            qpond,  qocn,         &
    2091           0 :                                            phi,    q,            &
    2092             :                                            w,                    &
    2093             :                                            hilyr,                &
    2094           0 :                                            dxp,    kcstar,       &
    2095           0 :                                            Iswabs,               &
    2096      393202 :                                            dt)
    2097      393202 :           if (icepack_warnings_aborted(subname)) return
    2098             : 
    2099             :        endif ! lcold
    2100             : 
    2101             :     endif ! lsnow
    2102             : 
    2103             :     ! tridiag to get new temperatures
    2104             :     call tdma_solve_sparse(nilyr, nslyr, &
    2105     6961823 :               An(1:nyn), Ap(1:nyn), As(1:nyn), b(1:nyn), T(1:nyn), nyn)
    2106     6961823 :     if (icepack_warnings_aborted(subname)) return
    2107             : 
    2108             :     call update_temperatures(lsnow, lcold, &
    2109             :                              nilyr, nslyr, &
    2110           0 :                              T,     Tsf,   &
    2111     6961823 :                              zTin,  zTsn)
    2112     6961823 :     if (icepack_warnings_aborted(subname)) return
    2113             : 
    2114             :   end subroutine solve_heat_conduction
    2115             : 
    2116             : !=======================================================================
    2117             : 
    2118     6961823 :   subroutine update_temperatures(lsnow, lcold, &
    2119             :                                  nilyr, nslyr, &
    2120     6961823 :                                  T,     Tsf,   &
    2121     6961823 :                                  zTin,  zTsn)
    2122             : 
    2123             :     logical, intent(in) :: &
    2124             :          lsnow , & ! snow presence: T: has snow, F: no snow
    2125             :          lcold     ! surface cold: T: surface is cold, F: surface is melting
    2126             : 
    2127             :       integer (kind=int_kind), intent(in) :: &
    2128             :          nilyr , & ! number of ice layers
    2129             :          nslyr     ! number of snow layers
    2130             : 
    2131             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    2132             :          T         ! matrix solution vector
    2133             : 
    2134             :     real(kind=dbl_kind), intent(inout) :: &
    2135             :          Tsf       ! snow surface temperature (C)
    2136             : 
    2137             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    2138             :          zTin  , & ! ice layer temperature (C)
    2139             :          zTsn      ! snow layer temperature (C)
    2140             : 
    2141             :     integer :: &
    2142             :          l     , & ! vertical index
    2143             :          k         ! vertical layer index
    2144             : 
    2145             :     character(len=*),parameter :: subname='(update_temperatures)'
    2146             : 
    2147     6961823 :     if (lsnow) then
    2148             :        
    2149     5271794 :        if (lcold) then
    2150             : 
    2151     5194646 :           Tsf = T(1)
    2152             : 
    2153    10389292 :           do k = 1, nslyr
    2154     5194646 :              l = k + 1
    2155    10389292 :              zTsn(k) = T(l)
    2156             :           enddo ! k
    2157             :           
    2158    41557168 :           do k = 1, nilyr
    2159    36362522 :              l = k + nslyr + 1
    2160    41557168 :              zTin(k) = T(l)
    2161             :           enddo ! k
    2162             : 
    2163             :        else ! lcold
    2164             :           
    2165      154296 :           do k = 1, nslyr
    2166       77148 :              l = k
    2167      154296 :              zTsn(k) = T(l)
    2168             :           enddo ! k
    2169             :           
    2170      617184 :           do k = 1, nilyr
    2171      540036 :              l = k + nslyr
    2172      617184 :              zTin(k) = T(l)
    2173             :           enddo ! k
    2174             : 
    2175             :        endif ! lcold
    2176             : 
    2177             :     else ! lsnow
    2178             :        
    2179     1690029 :        if (lcold) then
    2180             : 
    2181     1296827 :           Tsf = T(1)
    2182             :           
    2183    10374616 :           do k = 1, nilyr
    2184     9077789 :              l = k + 1
    2185    10374616 :              zTin(k) = T(l)
    2186             :           enddo ! k
    2187             : 
    2188             :        else ! lcold
    2189             : 
    2190     3145616 :           do k = 1, nilyr
    2191     2752414 :              l = k
    2192     3145616 :              zTin(k) = T(l)
    2193             :           enddo ! k
    2194             : 
    2195             :        endif ! lcold
    2196             : 
    2197             :     endif ! lsnow
    2198             : 
    2199     6961823 :   end subroutine update_temperatures
    2200             : 
    2201             : !=======================================================================
    2202             :   
    2203      786404 :   subroutine matrix_elements_nosnow_melt(Ap, As, An, b, nyn,   &
    2204             :                                          nilyr, &
    2205             :                                          Tsf,    Tbot,         &
    2206      393202 :                                          zqin0,                &
    2207             :                                          qpond,  qocn,         &
    2208      393202 :                                          phi,    q,            &
    2209             :                                          w,                    &
    2210             :                                          hilyr,                &
    2211      393202 :                                          dxp,    kcstar,       &
    2212      393202 :                                          Iswabs,               &
    2213             :                                          dt)
    2214             :      
    2215             :     real(kind=dbl_kind), dimension(:), intent(out) :: &
    2216             :          Ap           , & ! diagonal of tridiagonal matrix
    2217             :          As           , & ! lower off-diagonal of tridiagonal matrix
    2218             :          An           , & ! upper off-diagonal of tridiagonal matrix
    2219             :          b                ! right hand side of matrix solve
    2220             : 
    2221             :     integer, intent(out) :: &
    2222             :          nyn              ! matrix size
    2223             : 
    2224             :     integer (kind=int_kind), intent(in) :: &
    2225             :          nilyr            ! number of ice layers
    2226             : 
    2227             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    2228             :          zqin0        , & ! ice layer enthalpy (J m-3) at beggining of timestep
    2229             :          Iswabs       , & ! SW radiation absorbed in ice layers (W m-2)
    2230             :          phi              ! ice layer liquid fraction
    2231             : 
    2232             :     real(kind=dbl_kind), intent(in) :: &
    2233             :          Tsf          , & ! snow surface temperature (C)
    2234             :          dt           , & ! timestep (s)
    2235             :          hilyr        , & ! ice layer thickness (m)
    2236             :          Tbot         , & ! ice bottom surfce temperature (deg C)
    2237             :          qpond        , & ! melt pond brine enthalpy (J m-3)
    2238             :          qocn         , & ! ocean brine enthalpy (J m-3)
    2239             :          w                ! downwards vertical flushing Darcy velocity (m/s)
    2240             : 
    2241             :     real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &    
    2242             :          q                ! upward interface vertical Darcy flow (m s-1)
    2243             : 
    2244             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    2245             :          dxp          , & ! distances between grid points (m)
    2246             :          kcstar           ! interface conductivities (W m-1 K-1)
    2247             : 
    2248             :     integer :: &
    2249             :          k            , & ! vertical layer index
    2250             :          l                ! vertical index
    2251             :     
    2252             :     character(len=*),parameter :: subname='(matrix_elements_nosnow_melt)'
    2253             : 
    2254             :     ! surface layer
    2255      393202 :     k = 1
    2256      393202 :     l = k
    2257             :     
    2258      157576 :     Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
    2259      315152 :              kcstar(k+1) / dxp(k+1) + &
    2260      157576 :              kcstar(k)   / dxp(k) + &
    2261      157576 :              q(k) * cp_ocn * rhow + &
    2262      550778 :              w    * cp_ocn * rhow
    2263      472728 :     As(l) = -kcstar(k+1) / dxp(k+1) - &
    2264      708354 :              q(k) * cp_ocn * rhow
    2265      393202 :     An(l) = c0
    2266      157576 :     b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
    2267      157576 :             (kcstar(k) / dxp(k)) * Tsf + &
    2268      393202 :              w    * qpond
    2269             : 
    2270             :     ! interior ice layers
    2271     2359212 :     do k = 2, nilyr-1
    2272             :           
    2273     1966010 :        l = k
    2274             :           
    2275      787880 :        Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
    2276     1575760 :                 kcstar(k+1) / dxp(k+1) + &
    2277      787880 :                 kcstar(k)   / dxp(k) + &
    2278      787880 :                 q(k) * cp_ocn * rhow + &
    2279     2753890 :                 w    * cp_ocn * rhow
    2280     2363640 :        As(l) = -kcstar(k+1) / dxp(k+1) - &
    2281     3541770 :                 q(k) * cp_ocn * rhow
    2282      787880 :        An(l) = -kcstar(k)   / dxp(k) - &
    2283     1966010 :                 w    * cp_ocn * rhow
    2284     2359212 :        b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k)
    2285             : 
    2286             :     enddo ! k
    2287             :     
    2288             :     ! bottom layer
    2289      393202 :     k = nilyr
    2290      393202 :     l = k
    2291             :     
    2292      157576 :     Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
    2293      315152 :              kcstar(k+1) / dxp(k+1) + &
    2294      157576 :              kcstar(k)   / dxp(k) + &
    2295      157576 :              q(k) * cp_ocn * rhow + &
    2296      550778 :              w    * cp_ocn * rhow
    2297      393202 :     As(l) = c0
    2298      157576 :     An(l) = -kcstar(k) / dxp(k) - &
    2299      393202 :             w     * cp_ocn * rhow
    2300      157576 :     b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
    2301      315152 :             (kcstar(k+1) * Tbot) / dxp(k+1) + &
    2302      708354 :             q(k)  * qocn
    2303             :     
    2304      393202 :     nyn = nilyr
    2305             : 
    2306      393202 :   end subroutine matrix_elements_nosnow_melt
    2307             : 
    2308             : !=======================================================================
    2309             : 
    2310     2593654 :   subroutine matrix_elements_nosnow_cold(Ap, As, An, b, nyn,   &
    2311             :                                          nilyr, &
    2312             :                                          Tsf,    Tbot,         &
    2313     1296827 :                                          zqin0,                &
    2314             :                                          qpond,  qocn,         &
    2315     1296827 :                                          phi,    q,            &
    2316             :                                          w,                    &
    2317             :                                          hilyr,                &
    2318     1296827 :                                          dxp,    kcstar,       &
    2319     1296827 :                                          Iswabs,               &
    2320             :                                          fsurfn, dfsurfn_dTsf, &
    2321             :                                          dt)
    2322             :      
    2323             :     real(kind=dbl_kind), dimension(:), intent(out) :: &
    2324             :          Ap           , & ! diagonal of tridiagonal matrix
    2325             :          As           , & ! lower off-diagonal of tridiagonal matrix
    2326             :          An           , & ! upper off-diagonal of tridiagonal matrix
    2327             :          b                ! right hand side of matrix solve
    2328             : 
    2329             :     integer, intent(out) :: &
    2330             :          nyn              ! matrix size
    2331             : 
    2332             :     integer (kind=int_kind), intent(in) :: &
    2333             :          nilyr            ! number of ice layers
    2334             : 
    2335             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    2336             :          zqin0        , & ! ice layer enthalpy (J m-3) at beggining of timestep
    2337             :          Iswabs       , & ! SW radiation absorbed in ice layers (W m-2)
    2338             :          phi              ! ice layer liquid fraction
    2339             : 
    2340             :     real(kind=dbl_kind), intent(in) :: &
    2341             :          Tsf          , & ! snow surface temperature (C)
    2342             :          dt           , & ! timestep (s)
    2343             :          hilyr        , & ! ice layer thickness (m)
    2344             :          Tbot         , & ! ice bottom surfce temperature (deg C)
    2345             :          qpond        , & ! melt pond brine enthalpy (J m-3)
    2346             :          qocn         , & ! ocean brine enthalpy (J m-3)
    2347             :          w            , & ! downwards vertical flushing Darcy velocity (m/s)
    2348             :          fsurfn       , & ! net flux to top surface, excluding fcondtop
    2349             :          dfsurfn_dTsf     ! derivative of net flux to top surface, excluding fcondtopn
    2350             : 
    2351             :     real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &    
    2352             :          q                ! upward interface vertical Darcy flow (m s-1)
    2353             : 
    2354             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    2355             :          dxp          , & ! distances between grid points (m)
    2356             :          kcstar           ! interface conductivities (W m-1 K-1)
    2357             : 
    2358             :     integer :: &
    2359             :          k            , & ! vertical layer index
    2360             :          l                ! vertical index
    2361             : 
    2362             :     character(len=*),parameter :: subname='(matrix_elements_nosnow_cold)'
    2363             : 
    2364             :     ! surface temperature
    2365     1296827 :     l = 1
    2366     1296827 :     Ap(l) = dfsurfn_dTsf - kcstar(1) / dxp(1)
    2367     1296827 :     As(l) = kcstar(1) / dxp(1)
    2368     1296827 :     An(l) = c0
    2369     1296827 :     b (l) = dfsurfn_dTsf * Tsf - fsurfn
    2370             : 
    2371             :     ! surface layer
    2372     1296827 :     k = 1
    2373     1296827 :     l = k + 1
    2374             :     
    2375      511646 :     Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
    2376     1023292 :              kcstar(k+1) / dxp(k+1) + &
    2377      511646 :              kcstar(k)   / dxp(k) + &
    2378      511646 :              q(k) * cp_ocn * rhow + &
    2379     1808473 :              w    * cp_ocn * rhow
    2380     1534938 :     As(l) = -kcstar(k+1) / dxp(k+1) - &
    2381     2320119 :              q(k) * cp_ocn * rhow
    2382     1296827 :     An(l) = -kcstar(k)   / dxp(k)
    2383      511646 :     b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
    2384     1296827 :              w    * qpond
    2385             : 
    2386             :     ! interior ice layers
    2387     7780962 :     do k = 2, nilyr-1
    2388             :           
    2389     6484135 :        l = k + 1
    2390             :           
    2391     2558230 :        Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
    2392     5116460 :                 kcstar(k+1) / dxp(k+1) + &
    2393     2558230 :                 kcstar(k)   / dxp(k) + &
    2394     2558230 :                 q(k) * cp_ocn * rhow + &
    2395     9042365 :                 w    * cp_ocn * rhow
    2396     7674690 :        As(l) = -kcstar(k+1) / dxp(k+1) - &
    2397    11600595 :                 q(k) * cp_ocn * rhow
    2398     2558230 :        An(l) = -kcstar(k)   / dxp(k) - &
    2399     6484135 :                 w    * cp_ocn * rhow
    2400     7780962 :        b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k)
    2401             : 
    2402             :     enddo ! k
    2403             :     
    2404             :     ! bottom layer
    2405     1296827 :     k = nilyr
    2406     1296827 :     l = k + 1
    2407             :     
    2408      511646 :     Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
    2409     1023292 :              kcstar(k+1) / dxp(k+1) + &
    2410      511646 :              kcstar(k)   / dxp(k) + &
    2411      511646 :              q(k) * cp_ocn * rhow + &
    2412     1808473 :              w    * cp_ocn * rhow
    2413     1296827 :     As(l) = c0
    2414      511646 :     An(l) = -kcstar(k) / dxp(k) - &
    2415     1296827 :             w     * cp_ocn * rhow
    2416      511646 :     b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
    2417     1023292 :             (kcstar(k+1) * Tbot) / dxp(k+1) + &
    2418     2320119 :             q(k)  * qocn
    2419             :     
    2420     1296827 :     nyn = nilyr + 1
    2421             : 
    2422     1296827 :   end subroutine matrix_elements_nosnow_cold
    2423             : 
    2424             : !=======================================================================
    2425             : 
    2426      154296 :   subroutine matrix_elements_snow_melt(Ap, As, An, b, nyn,   &
    2427             :                                        nilyr,  nslyr,        &
    2428             :                                        Tsf,    Tbot,         &
    2429      154296 :                                        zqin0,  zqsn0,        &
    2430             :                                        qpond,  qocn,         &
    2431       77148 :                                        phi,    q,            &
    2432             :                                        w,                    &
    2433             :                                        hilyr,  hslyr,        &
    2434       77148 :                                        dxp,    kcstar,       &
    2435      154296 :                                        Iswabs, Sswabs,       &
    2436             :                                        dt)
    2437             :      
    2438             :     real(kind=dbl_kind), dimension(:), intent(out) :: &
    2439             :          Ap           , & ! diagonal of tridiagonal matrix
    2440             :          As           , & ! lower off-diagonal of tridiagonal matrix
    2441             :          An           , & ! upper off-diagonal of tridiagonal matrix
    2442             :          b                ! right hand side of matrix solve
    2443             : 
    2444             :     integer, intent(out) :: &
    2445             :          nyn              ! matrix size
    2446             : 
    2447             :     integer (kind=int_kind), intent(in) :: &
    2448             :          nilyr , & ! number of ice layers
    2449             :          nslyr     ! number of snow layers
    2450             : 
    2451             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    2452             :          zqin0        , & ! ice layer enthalpy (J m-3) at beggining of timestep
    2453             :          Iswabs       , & ! SW radiation absorbed in ice layers (W m-2)
    2454             :          phi          , & ! ice layer liquid fraction
    2455             :          zqsn0        , & ! snow layer enthalpy (J m-3) at start of timestep
    2456             :          Sswabs           ! SW radiation absorbed in snow layers (W m-2)
    2457             : 
    2458             :     real(kind=dbl_kind), intent(in) :: &
    2459             :          Tsf          , & ! snow surface temperature (C)
    2460             :          dt           , & ! timestep (s)
    2461             :          hilyr        , & ! ice layer thickness (m)
    2462             :          hslyr        , & ! snow layer thickness (m)
    2463             :          Tbot         , & ! ice bottom surfce temperature (deg C)
    2464             :          qpond        , & ! melt pond brine enthalpy (J m-3)
    2465             :          qocn         , & ! ocean brine enthalpy (J m-3)
    2466             :          w                ! downwards vertical flushing Darcy velocity (m/s)
    2467             : 
    2468             :     real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &    
    2469             :          q                ! upward interface vertical Darcy flow (m s-1)
    2470             : 
    2471             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    2472             :          dxp          , & ! distances between grid points (m)
    2473             :          kcstar           ! interface conductivities (W m-1 K-1)
    2474             : 
    2475             :     integer :: &
    2476             :          k            , & ! vertical layer index
    2477             :          l                ! vertical index
    2478             : 
    2479             :     character(len=*),parameter :: subname='(matrix_elements_snow_melt)'
    2480             : 
    2481             :     ! surface layer
    2482       77148 :     k = 1
    2483       77148 :     l = k
    2484             :     
    2485       29992 :     Ap(l) = ((rhos * cp_ice) / dt) * hslyr + &
    2486       59984 :              kcstar(l+1) / dxp(l+1) + &
    2487      137132 :              kcstar(l)   / dxp(l)
    2488       77148 :     As(l) = -kcstar(l+1) / dxp(l+1)
    2489       77148 :     An(l) = c0
    2490       29992 :     b (l) = ((rhos * Lfresh + zqsn0(k)) / dt) * hslyr + Sswabs(k) + &
    2491       77148 :             (kcstar(l) * Tsf) / dxp(l)
    2492             : 
    2493             :     ! interior snow layers
    2494       77148 :     do k = 2, nslyr
    2495             :        
    2496           0 :        l = k
    2497             : 
    2498           0 :        Ap(l) = ((rhos * cp_ice) / dt) * hslyr + &
    2499           0 :                 kcstar(l+1) / dxp(l+1) + &
    2500           0 :                 kcstar(l)   / dxp(l)
    2501           0 :        As(l) = -kcstar(l+1) / dxp(l+1)
    2502           0 :        An(l) = -kcstar(l)   / dxp(l)
    2503       77148 :        b (l) = ((rhos * Lfresh + zqsn0(k)) / dt) * hslyr + Sswabs(k)
    2504             :           
    2505             :     enddo ! k
    2506             :     
    2507             :     ! top ice layer
    2508       77148 :     k = 1
    2509       77148 :     l = nslyr + k
    2510             :     
    2511       29992 :     Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
    2512       59984 :              kcstar(l+1) / dxp(l+1) + &
    2513       29992 :              kcstar(l)   / dxp(l) + &
    2514       29992 :              q(k) * cp_ocn * rhow + &
    2515      107140 :              w    * cp_ocn * rhow
    2516       89976 :     As(l) = -kcstar(l+1) / dxp(l+1) - &
    2517      137132 :              q(k) * cp_ocn * rhow
    2518       77148 :     An(l) = -kcstar(l)   / dxp(l)
    2519       29992 :     b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
    2520       77148 :              w    * qpond
    2521             : 
    2522             :     ! interior ice layers
    2523      462888 :     do k = 2, nilyr-1
    2524             :           
    2525      385740 :        l = nslyr + k
    2526             :        
    2527      149960 :        Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
    2528      299920 :                 kcstar(l+1) / dxp(l+1) + &
    2529      149960 :                 kcstar(l)   / dxp(l) + &
    2530      149960 :                 q(k) * cp_ocn * rhow + &
    2531      535700 :                 w    * cp_ocn * rhow
    2532      449880 :        As(l) = -kcstar(l+1) / dxp(l+1) - &
    2533      685660 :                 q(k) * cp_ocn * rhow
    2534      149960 :        An(l) = -kcstar(l)   / dxp(l) - &
    2535      385740 :                 w    * cp_ocn * rhow
    2536      462888 :        b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k)
    2537             :           
    2538             :     enddo ! k
    2539             : 
    2540             :     ! bottom layer
    2541       77148 :     k = nilyr
    2542       77148 :     l = nilyr + nslyr
    2543             :     
    2544       29992 :     Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
    2545       59984 :              kcstar(l+1) / dxp(l+1) + &
    2546       29992 :              kcstar(l)   / dxp(l) + &
    2547       29992 :              q(k) * cp_ocn * rhow + &
    2548      107140 :              w    * cp_ocn * rhow
    2549       77148 :     As(l) = c0
    2550       29992 :     An(l) = -kcstar(l)   / dxp(l) - &
    2551       77148 :              w    * cp_ocn * rhow
    2552       29992 :     b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
    2553       59984 :             (kcstar(l+1) * Tbot) / dxp(l+1) + &
    2554      137132 :              q(k) * qocn
    2555             :        
    2556       77148 :     nyn = nilyr + nslyr
    2557             : 
    2558       77148 :   end subroutine matrix_elements_snow_melt
    2559             : 
    2560             : !=======================================================================
    2561             : 
    2562    10389292 :   subroutine matrix_elements_snow_cold(Ap, As, An, b, nyn,   &
    2563             :                                        nilyr,  nslyr,        &
    2564             :                                        Tsf,    Tbot,         &
    2565    10389292 :                                        zqin0,  zqsn0,        &
    2566             :                                        qpond,  qocn,         &
    2567     5194646 :                                        phi,    q,            &
    2568             :                                        w,                    &
    2569             :                                        hilyr,  hslyr,        &
    2570     5194646 :                                        dxp,    kcstar,       &
    2571    10389292 :                                        Iswabs, Sswabs,       &
    2572             :                                        fsurfn, dfsurfn_dTsf, &
    2573             :                                        dt)
    2574             :      
    2575             :     real(kind=dbl_kind), dimension(:), intent(out) :: &
    2576             :          Ap           , & ! diagonal of tridiagonal matrix
    2577             :          As           , & ! lower off-diagonal of tridiagonal matrix
    2578             :          An           , & ! upper off-diagonal of tridiagonal matrix
    2579             :          b                ! right hand side of matrix solve
    2580             : 
    2581             :     integer, intent(out) :: &
    2582             :          nyn              ! matrix size
    2583             : 
    2584             :     integer (kind=int_kind), intent(in) :: &
    2585             :          nilyr , & ! number of ice layers
    2586             :          nslyr     ! number of snow layers
    2587             : 
    2588             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    2589             :          zqin0        , & ! ice layer enthalpy (J m-3) at beggining of timestep
    2590             :          Iswabs       , & ! SW radiation absorbed in ice layers (W m-2)
    2591             :          phi          , & ! ice layer liquid fraction
    2592             :          zqsn0        , & ! snow layer enthalpy (J m-3) at start of timestep
    2593             :          Sswabs           ! SW radiation absorbed in snow layers (W m-2)
    2594             : 
    2595             :     real(kind=dbl_kind), intent(in) :: &
    2596             :          Tsf          , & ! snow surface temperature (C)
    2597             :          dt           , & ! timestep (s)
    2598             :          hilyr        , & ! ice layer thickness (m)
    2599             :          hslyr        , & ! snow layer thickness (m)
    2600             :          Tbot         , & ! ice bottom surfce temperature (deg C)
    2601             :          qpond        , & ! melt pond brine enthalpy (J m-3)
    2602             :          qocn         , & ! ocean brine enthalpy (J m-3)
    2603             :          w            , & ! downwards vertical flushing Darcy velocity (m/s)
    2604             :          fsurfn       , & ! net flux to top surface, excluding fcondtop
    2605             :          dfsurfn_dTsf     ! derivative of net flux to top surface, excluding fcondtopn
    2606             : 
    2607             :     real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &    
    2608             :          q                ! upward interface vertical Darcy flow (m s-1)
    2609             : 
    2610             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    2611             :          dxp          , & ! distances between grid points (m)
    2612             :          kcstar           ! interface conductivities (W m-1 K-1)
    2613             : 
    2614             :     integer :: &
    2615             :          k            , & ! vertical layer index
    2616             :          l            , & ! matrix index
    2617             :          m                ! vertical index
    2618             : 
    2619             :     character(len=*),parameter :: subname='(matrix_elements_snow_cold)'
    2620             : 
    2621             :     ! surface temperature
    2622     5194646 :     l = 1
    2623     5194646 :     Ap(l) = dfsurfn_dTsf - kcstar(1) / dxp(1)
    2624     5194646 :     As(l) = kcstar(1) / dxp(1)
    2625     5194646 :     An(l) = c0
    2626     5194646 :     b (l) = dfsurfn_dTsf * Tsf - fsurfn
    2627             : 
    2628             :     ! surface layer
    2629     5194646 :     k = 1
    2630     5194646 :     l = k + 1
    2631     5194646 :     m = 1
    2632             :     
    2633     1661569 :     Ap(l) = ((rhos * cp_ice) / dt) * hslyr + &
    2634     3323138 :              kcstar(m+1) / dxp(m+1) + &
    2635     8517784 :              kcstar(m)   / dxp(m)
    2636     5194646 :     As(l) = -kcstar(m+1) / dxp(m+1)
    2637     5194646 :     An(l) = -kcstar(m)   / dxp(m)
    2638     5194646 :     b (l) = ((rhos * Lfresh + zqsn0(k)) / dt) * hslyr + Sswabs(k)
    2639             : 
    2640             :     ! interior snow layers
    2641     5194646 :     do k = 2, nslyr
    2642             :        
    2643           0 :        l = k + 1
    2644           0 :        m = k
    2645             : 
    2646           0 :        Ap(l) = ((rhos * cp_ice) / dt) * hslyr + &
    2647           0 :                 kcstar(m+1) / dxp(m+1) + &
    2648           0 :                 kcstar(m)   / dxp(m)
    2649           0 :        As(l) = -kcstar(m+1) / dxp(m+1)
    2650           0 :        An(l) = -kcstar(m)   / dxp(m)
    2651     5194646 :        b (l) = ((rhos * Lfresh + zqsn0(k)) / dt) * hslyr + Sswabs(k)
    2652             : 
    2653             :     enddo ! k
    2654             :     
    2655             :     ! top ice layer
    2656     5194646 :     k = 1
    2657     5194646 :     l = nslyr + k + 1
    2658     5194646 :     m = k + nslyr
    2659             :     
    2660     1661569 :     Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
    2661     3323138 :              kcstar(m+1) / dxp(m+1) + &
    2662     1661569 :              kcstar(m)   / dxp(m) + &
    2663     1661569 :              q(k) * cp_ocn * rhow + &
    2664     6856215 :              w    * cp_ocn * rhow
    2665     4984707 :     As(l) = -kcstar(m+1) / dxp(m+1) - &
    2666     8517784 :              q(k) * cp_ocn * rhow
    2667     5194646 :     An(l) = -kcstar(m)   / dxp(m)
    2668     1661569 :     b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
    2669     5194646 :               w   * qpond
    2670             : 
    2671             :     ! interior ice layers
    2672    31167876 :     do k = 2, nilyr-1
    2673             :           
    2674    25973230 :        l = nslyr + k + 1
    2675    25973230 :        m = k + nslyr
    2676             :        
    2677     8307845 :        Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
    2678    16615690 :                 kcstar(m+1) / dxp(m+1) + &
    2679     8307845 :                 kcstar(m)   / dxp(m) + &
    2680     8307845 :                 q(k) * cp_ocn * rhow + &
    2681    34281075 :                 w    * cp_ocn * rhow
    2682    24923535 :        As(l) = -kcstar(m+1) / dxp(m+1) - &
    2683    42588920 :                 q(k) * cp_ocn * rhow
    2684     8307845 :        An(l) = -kcstar(m)   / dxp(m) - &
    2685    25973230 :                 w    * cp_ocn * rhow
    2686    31167876 :        b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k)
    2687             : 
    2688             :     enddo ! k
    2689             : 
    2690             :     ! bottom layer
    2691     5194646 :     k = nilyr
    2692     5194646 :     l = nilyr + nslyr + 1
    2693     5194646 :     m = k + nslyr
    2694             :     
    2695     1661569 :     Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
    2696     3323138 :              kcstar(m+1) / dxp(m+1) + &
    2697     1661569 :              kcstar(m)   / dxp(m) + &
    2698     1661569 :              q(k) * cp_ocn * rhow + &
    2699     6856215 :              w    * cp_ocn * rhow
    2700     5194646 :     As(l) = c0
    2701     1661569 :     An(l) = -kcstar(m)   / dxp(m) - &
    2702     5194646 :              w    * cp_ocn * rhow
    2703     1661569 :     b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
    2704     3323138 :             (kcstar(m+1) * Tbot) / dxp(m+1) + &
    2705     8517784 :              q(k) * qocn
    2706             : 
    2707     5194646 :     nyn = nilyr + nslyr + 1
    2708             : 
    2709     5194646 :   end subroutine matrix_elements_snow_cold
    2710             : 
    2711             : !=======================================================================
    2712             : 
    2713     6720400 :   subroutine solve_salinity(zSin,   Sbr,   &
    2714             :                             Spond, sss,   &
    2715     6720400 :                             q,     dSdt,  &
    2716             :                             w,     hilyr, &
    2717             :                             dt,    nilyr)
    2718             : 
    2719             :     integer (kind=int_kind), intent(in) :: &
    2720             :          nilyr      ! number of ice layers
    2721             : 
    2722             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    2723             :          zSin       ! ice layer bulk salinity (ppt)
    2724             : 
    2725             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    2726             :          Sbr   , & ! ice layer brine salinity (ppt)
    2727             :          dSdt      ! gravity drainage desalination rate for slow mode (ppt s-1)
    2728             :          
    2729             :     real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
    2730             :          q         ! upward interface vertical Darcy flow (m s-1)
    2731             : 
    2732             :     real(kind=dbl_kind), intent(in) :: &
    2733             :          Spond , & ! melt pond salinity (ppt)
    2734             :          sss   , & ! sea surface salinity (ppt)
    2735             :          w     , & ! vertical flushing Darcy velocity (m/s)
    2736             :          hilyr , & ! ice layer thickness (m)
    2737             :          dt        ! timestep (s)
    2738             : 
    2739             :     integer :: &
    2740             :          k         ! vertical layer index
    2741             : 
    2742             :     real(kind=dbl_kind), parameter :: &
    2743             :          S_min = p01
    2744             :     
    2745             :     real(kind=dbl_kind), dimension(nilyr) :: &
    2746    12469496 :          zSin0
    2747             : 
    2748             :     character(len=*),parameter :: subname='(solve_salinity)'
    2749             : 
    2750    26881600 :     zSin0 = zSin
    2751             : 
    2752     3360200 :     k = 1
    2753     1138662 :     zSin(k) = zSin(k) + max(S_min - zSin(k), &
    2754     2277324 :          ((q(k)  * (Sbr(k+1) - Sbr(k))) / hilyr + &
    2755     1138662 :           dSdt(k)                               + &
    2756     4498862 :           (w * (Spond    - Sbr(k))) / hilyr) * dt)
    2757             : 
    2758    20161200 :     do k = 2, nilyr-1
    2759             : 
    2760     5693310 :        zSin(k) = zSin(k) + max(S_min - zSin(k), &
    2761    11386620 :             ((q(k)  * (Sbr(k+1) - Sbr(k))) / hilyr + &
    2762     5693310 :              dSdt(k)                               + &
    2763    25854510 :              (w * (Sbr(k-1) - Sbr(k))) / hilyr) * dt)
    2764             : 
    2765             :     enddo ! k
    2766             : 
    2767     3360200 :     k = nilyr
    2768     1138662 :     zSin(k) = zSin(k) + max(S_min - zSin(k), &
    2769     1138662 :          ((q(k)  * (sss      - Sbr(k))) / hilyr + &
    2770     1138662 :           dSdt(k)                               + &
    2771     3360200 :           (w * (Sbr(k-1) - Sbr(k))) / hilyr) * dt)
    2772             : 
    2773             : 
    2774    26881600 :     if (minval(zSin) < c0) then
    2775             : 
    2776             : 
    2777           0 :          write(warnstr,*) subname, (q(k)  * (Sbr(k+1) - Sbr(k))) / hilyr, &
    2778           0 :           dSdt(k)                               , &
    2779           0 :           (w * (Spond    - Sbr(k))) / hilyr
    2780           0 :          call icepack_warnings_add(warnstr)
    2781             : 
    2782           0 :        do k = 1, nilyr
    2783             :        
    2784           0 :           write(warnstr,*) subname, k, zSin(k), zSin0(k)
    2785           0 :           call icepack_warnings_add(warnstr)
    2786             : 
    2787             :        enddo
    2788             : 
    2789           0 :        call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    2790           0 :        return
    2791             : 
    2792             :     endif
    2793             : 
    2794             :   end subroutine solve_salinity
    2795             : 
    2796             : !=======================================================================
    2797             : 
    2798     6961823 :   subroutine tdma_solve_sparse(nilyr, nslyr, a, b, c, d, x, n)
    2799             :     
    2800             :     ! perform a tri-diagonal solve with TDMA using a sparse tridiagoinal matrix
    2801             : 
    2802             :     integer (kind=int_kind), intent(in) :: &
    2803             :          nilyr, & ! number of ice layers
    2804             :          nslyr    ! number of snow layers
    2805             : 
    2806             :     integer(kind=int_kind), intent(in) :: &
    2807             :          n      ! matrix size
    2808             :     
    2809             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    2810             :          a  , & ! matrix lower off-diagonal
    2811             :          b  , & ! matrix diagonal
    2812             :          c  , & ! matrix upper off-diagonal
    2813             :          d      ! right hand side vector
    2814             :  
    2815             :     real(kind=dbl_kind), dimension(:), intent(out) :: &
    2816             :          x      ! solution vector
    2817             : 
    2818             :     real(kind=dbl_kind), dimension(nilyr+nslyr+1) :: &
    2819    32809910 :          cp , & ! modified upper off-diagonal vector
    2820    32809910 :          dp     ! modified right hand side vector
    2821             : 
    2822             :     integer(kind=int_kind) :: &
    2823             :          i      ! vector index
    2824             :     
    2825             :     character(len=*),parameter :: subname='(tdma_solve_sparse)'
    2826             : 
    2827             :     ! forward sweep
    2828     6961823 :     cp(1) = c(1) / b(1)
    2829    53534205 :     do i = 2, n-1
    2830    53534205 :        cp(i) = c(i) / (b(i) - cp(i-1)*a(i))
    2831             :     enddo
    2832             :     
    2833     6961823 :     dp(1) = d(1) / b(1)
    2834    60496028 :     do i = 2, n
    2835    60496028 :        dp(i) = (d(i) - dp(i-1)*a(i)) / (b(i) - cp(i-1)*a(i))
    2836             :     enddo
    2837             : 
    2838             :     ! back substitution
    2839     6961823 :     x(n) = dp(n)
    2840    60496028 :     do i = n-1,1,-1
    2841    60496028 :        x(i) = dp(i) - cp(i)*x(i+1)
    2842             :     enddo
    2843             : 
    2844     6961823 :   end subroutine tdma_solve_sparse
    2845             : 
    2846             : !=======================================================================
    2847             : ! Effect of salinity
    2848             : !=======================================================================
    2849             : 
    2850    41893096 :   function permeability(phi) result(perm)
    2851             : 
    2852             :     ! given the liquid fraction calculate the permeability
    2853             :     ! See Golden et al. 2007
    2854             : 
    2855             :     real(kind=dbl_kind), intent(in) :: &
    2856             :          phi                  ! liquid fraction
    2857             : 
    2858             :     real(kind=dbl_kind) :: &
    2859             :          perm                 ! permeability (m2)
    2860             :     
    2861             :     real(kind=dbl_kind), parameter :: &
    2862             :          phic = p05 ! critical liquid fraction for impermeability
    2863             : 
    2864             :     character(len=*),parameter :: subname='(permeability)'
    2865             : 
    2866    41893096 :     perm = 3.0e-8_dbl_kind * max(phi - phic, c0)**3
    2867             : 
    2868    41893096 :   end function permeability
    2869             : 
    2870             : !=======================================================================
    2871             : 
    2872     3172532 :   subroutine explicit_flow_velocities(nilyr, zSin, &
    2873     3172532 :                                       zTin,  Tsf,  &
    2874     3172532 :                                       Tbot,  q,    &
    2875     6345064 :                                       dSdt,  Sbr,  &
    2876     3172532 :                                       qbr,   dt,   &
    2877             :                                       sss,   qocn, &
    2878             :                                       hilyr, hin)
    2879             : 
    2880             :     ! calculate the rapid gravity drainage mode Darcy velocity and the
    2881             :     ! slow mode drainage rate
    2882             : 
    2883             :     integer (kind=int_kind), intent(in) :: &
    2884             :          nilyr     ! number of ice layers
    2885             : 
    2886             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    2887             :          zSin, &   ! ice layer bulk salinity (ppt)
    2888             :          zTin      ! ice layer temperature (C)
    2889             : 
    2890             :     real(kind=dbl_kind), intent(in) :: &
    2891             :          Tsf   , & ! ice/snow surface temperature (C)
    2892             :          Tbot  , & ! ice bottom temperature (C)
    2893             :          dt    , & ! time step (s)
    2894             :          sss   , & ! sea surface salinty (ppt)
    2895             :          qocn  , & ! ocean enthalpy (J m-3)
    2896             :          hilyr , & ! ice layer thickness (m)
    2897             :          hin       ! ice thickness (m)
    2898             : 
    2899             :     real(kind=dbl_kind), dimension(0:nilyr), intent(out) :: &
    2900             :          q         ! rapid mode upward interface vertical Darcy flow (m s-1)
    2901             : 
    2902             :     real(kind=dbl_kind), dimension(:), intent(out) :: &
    2903             :          dSdt      ! slow mode drainage rate (ppt s-1)
    2904             : 
    2905             :     real(kind=dbl_kind), dimension(:), intent(out) :: &
    2906             :          Sbr , &   ! ice layer brine salinity (ppt)
    2907             :          qbr       ! ice layer brine enthalpy (J m-3)
    2908             : 
    2909             :     real(kind=dbl_kind), parameter :: &
    2910             :          kappal        = 8.824e-8_dbl_kind, & ! heat diffusivity of liquid
    2911             :          fracmax       = p2               , & ! limiting advective layer fraction
    2912             :          zSin_min      = p1               , & ! minimum bulk salinity (ppt)
    2913             :          safety_factor = c10                  ! to prevent negative salinities
    2914             : 
    2915             :     real(kind=dbl_kind), dimension(1:nilyr) :: &
    2916    12730180 :          phi           ! ice layer liquid fraction
    2917             : 
    2918             :     real(kind=dbl_kind), dimension(0:nilyr) :: &
    2919    13794366 :          rho           ! ice layer brine density (kg m-3)
    2920             : 
    2921             :     real(kind=dbl_kind) :: &
    2922     1064186 :          rho_ocn   , & ! ocean density (kg m-3)
    2923     1064186 :          perm_min  , & ! minimum permeability from layer to ocean (m2)
    2924     1064186 :          perm_harm , & ! harmonic mean of permeability from layer to ocean (m2)
    2925     1064186 :          rho_sum   , & ! sum of the brine densities from layer to ocean (kg m-3)
    2926     1064186 :          rho_pipe  , & ! density of the brine in the channel (kg m-3)
    2927     1064186 :          z         , & ! distance to layer from top surface (m)
    2928     1064186 :          perm      , & ! ice layer permeability (m2)
    2929     1064186 :          drho      , & ! brine density difference between layer and ocean (kg m-3)
    2930     1064186 :          Ra        , & ! local mush Rayleigh number
    2931     1064186 :          rn        , & ! real value of number of layers considered
    2932     1064186 :          L         , & ! thickness of the layers considered (m)
    2933     1064186 :          dx        , & ! horizontal size of convective flow (m)
    2934     1064186 :          dx2       , & ! square of the horizontal size of convective flow (m2)
    2935     1064186 :          Am        , & ! A parameter for mush
    2936     1064186 :          Bm        , & ! B parameter for mush
    2937     1064186 :          Ap        , & ! A parameter for channel
    2938     1064186 :          Bp        , & ! B parameter for channel
    2939     1064186 :          qlimit    , & ! limit to vertical Darcy flow for numerical stability
    2940     1064186 :          dS_guess  , & ! expected bulk salinity without limits
    2941     1064186 :          alpha     , & ! desalination limiting factor
    2942     1064186 :          ra_constants  ! for Rayleigh number
    2943             : 
    2944             :     integer(kind=int_kind) :: &
    2945             :          k             ! ice layer index
    2946             : 
    2947             :     character(len=*),parameter :: subname='(explicit_flow_velocities)'
    2948             : 
    2949             :     ! initial downward sweep - determine derived physical quantities
    2950    25380256 :     do k = 1, nilyr
    2951             :        
    2952    22207724 :        Sbr(k) = liquidus_brine_salinity_mush(zTin(k))
    2953    22207724 :        phi(k) = icepack_mushy_liquid_fraction(zTin(k), zSin(k))
    2954    22207724 :        qbr(k) = enthalpy_brine(zTin(k))
    2955    25380256 :        rho(k) = icepack_mushy_density_brine(Sbr(k))
    2956             : 
    2957             :     enddo ! k
    2958             : 
    2959     3172532 :     rho(0) = rho(1)
    2960             : 
    2961             :     ! ocean conditions
    2962     3172532 :     Sbr(nilyr+1) = sss
    2963     3172532 :     qbr(nilyr+1) = qocn
    2964     3172532 :     rho_ocn = icepack_mushy_density_brine(sss)
    2965             : 
    2966             :     ! initialize accumulated quantities
    2967     3172532 :     perm_min = bignum
    2968     3172532 :     perm_harm = c0
    2969     3172532 :     rho_sum = c0
    2970             : 
    2971             :     ! limit to q for numerical stability
    2972     3172532 :     qlimit = (fracmax * hilyr) / dt
    2973             : 
    2974             :     ! no flow through ice top surface
    2975     3172532 :     q(0) = c0
    2976             : 
    2977     3172532 :     ra_constants  = gravit / (viscosity_dyn * kappal)
    2978             :     ! first iterate over layers going up
    2979    25380256 :     do k = nilyr, 1, -1
    2980             : 
    2981             :        ! vertical position from ice top surface
    2982    22207724 :        z = ((real(k, dbl_kind) - p5) / real(nilyr, dbl_kind)) * hin
    2983             : 
    2984             :        ! permeabilities
    2985    22207724 :        perm = permeability(phi(k))
    2986    22207724 :        perm_min = min(perm_min,perm)
    2987    22207724 :        perm_harm = perm_harm + (c1 / max(perm,1.0e-30_dbl_kind))
    2988             : 
    2989             :        ! densities
    2990    22207724 :        rho_sum = rho_sum + rho(k)
    2991             :        !rho_pipe = rho(k)
    2992    22207724 :        rho_pipe = p5 * (rho(k) + rho(k-1))
    2993    22207724 :        drho = max(rho(k) - rho_ocn, c0)
    2994             : 
    2995             :        ! mush Rayleigh number 
    2996    22207724 :        Ra = drho * (hin-z) * perm_min * ra_constants
    2997             : 
    2998             :        ! height of mush layer to layer k
    2999    22207724 :        rn = real(nilyr-k+1,dbl_kind)
    3000    22207724 :        L = rn * hilyr
    3001             : 
    3002             :        ! horizontal size of convection
    3003    22207724 :        dx = L * c2 * aspect_rapid_mode
    3004    22207724 :        dx2 = dx**2
    3005             : 
    3006             :        ! determine vertical Darcy flow
    3007    22207724 :        Am = (dx2 * rn) / (viscosity_dyn * perm_harm)
    3008    22207724 :        Bm = (-gravit * rho_sum) / rn
    3009             : 
    3010    22207724 :        Ap = (pi * a_rapid_mode**4) / (c8 * viscosity_dyn)
    3011    22207724 :        Bp = -rho_pipe * gravit
    3012             : 
    3013    22207724 :        q(k) = max((Am / dx2) * ((-Ap*Bp - Am*Bm) / (Am + Ap) + Bm), 1.0e-30_dbl_kind)
    3014             : 
    3015             :        ! modify by Rayleigh number and advection limit
    3016    22207724 :        q(k) = min(q(k) * (max(Ra - Rac_rapid_mode, c0) / (Ra+puny)), qlimit)
    3017             : 
    3018             :        ! late stage drainage
    3019     7449302 :        dSdt(k) = dSdt_slow_mode * (max((zSin(k) - phi_c_slow_mode*Sbr(k)), c0) &
    3020    22207724 :                                 *  max((Tbot - Tsf), c0)) / (hin + 0.001_dbl_kind)
    3021             : 
    3022    22207724 :        dSdt(k) = max(dSdt(k), (-zSin(k) * 0.5_dbl_kind) / dt)
    3023             : 
    3024             :        ! restrict flows to prevent too much salt loss
    3025    22207724 :        dS_guess = (((q(k) * (Sbr(k+1) - Sbr(k))) / hilyr + dSdt(k)) * dt) * safety_factor
    3026             : 
    3027    22207724 :        if (abs(dS_guess) < puny) then
    3028    10112384 :           alpha = c1
    3029             :        else
    3030    12095340 :           alpha = (zSin_min - zSin(k)) / dS_guess
    3031             :        endif
    3032             : 
    3033    22207724 :        if (alpha < c0 .or. alpha > c1) alpha = c1
    3034             : 
    3035    22207724 :        q(k)    = q(k)    * alpha
    3036    25380256 :        dSdt(k) = dSdt(k) * alpha
    3037             : 
    3038             :     enddo ! k
    3039             : 
    3040     3172532 :   end subroutine explicit_flow_velocities
    3041             : 
    3042             : !=======================================================================
    3043             : ! Flushing
    3044             : !=======================================================================
    3045             : 
    3046     3172532 :   subroutine flushing_velocity(zTin, &
    3047     3172532 :                                phi,    nilyr, &
    3048             :                                hin,    hsn,   &
    3049             :                                hilyr,         &
    3050             :                                hpond,  apond, &
    3051             :                                dt,     w)
    3052             :    
    3053             :     ! calculate the vertical flushing Darcy velocity (positive downward)
    3054             : 
    3055             :     integer (kind=int_kind), intent(in) :: &
    3056             :          nilyr         ! number of ice layers
    3057             : 
    3058             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    3059             :          zTin      , & ! ice layer temperature (C)
    3060             :          phi           ! ice layer liquid fraction
    3061             : 
    3062             :     real(kind=dbl_kind), intent(in) :: &
    3063             :          hilyr     , & ! ice layer thickness (m)
    3064             :          hpond     , & ! melt pond thickness (m)
    3065             :          apond     , & ! melt pond area (-)
    3066             :          hsn       , & ! snow thickness (m)
    3067             :          hin       , & ! ice thickness (m)
    3068             :          dt            ! time step (s)
    3069             : 
    3070             :     real(kind=dbl_kind), intent(out) :: &
    3071             :          w             ! vertical flushing Darcy flow rate (m s-1)
    3072             : 
    3073             :     real(kind=dbl_kind), parameter :: &
    3074             :          advection_limit = 0.005_dbl_kind ! limit to fraction of brine in 
    3075             :                                           ! any layer that can be advected 
    3076             : 
    3077             :     real(kind=dbl_kind) :: &
    3078     1064186 :          perm       , & ! ice layer permeability (m2)
    3079     1064186 :          ice_mass   , & ! mass of ice (kg m-2)
    3080     1064186 :          perm_harm  , & ! harmonic mean of ice permeability (m2)
    3081     1064186 :          hocn       , & ! ocean surface height above ice base (m)
    3082     1064186 :          hbrine     , & ! brine surface height above ice base (m)
    3083     1064186 :          w_down_max , & ! maximum downward flushing Darcy flow rate (m s-1) 
    3084     1064186 :          phi_min    , & ! minimum porosity in the mush
    3085     1064186 :          wlimit     , & ! limit to w to avoid advecting all brine in layer
    3086     1064186 :          dhhead         ! hydraulic head (m)
    3087             : 
    3088             :     integer(kind=int_kind) :: &
    3089             :          k              ! ice layer index
    3090             : 
    3091             :     character(len=*),parameter :: subname='(flushing_velocity)'
    3092             : 
    3093             :     ! initialize
    3094     3172532 :     w = c0
    3095             : 
    3096             :     ! only flush if ponds are active
    3097     3172532 :     if (tr_pond) then
    3098             : 
    3099     2812196 :        ice_mass  = c0
    3100     2812196 :        perm_harm = c0
    3101     2812196 :        phi_min   = c1
    3102             : 
    3103    22497568 :        do k = 1, nilyr
    3104             : 
    3105             :           ! liquid fraction
    3106             :           !phi = icepack_mushy_liquid_fraction(zTin(k), zSin(k))
    3107    19685372 :           phi_min = min(phi_min,phi(k))
    3108             : 
    3109             :           ! permeability
    3110    19685372 :           perm = permeability(phi(k))
    3111             : 
    3112             :           ! ice mass
    3113     6535032 :           ice_mass = ice_mass + phi(k)        * icepack_mushy_density_brine(liquidus_brine_salinity_mush(zTin(k))) + &
    3114    19685372 :                (c1 - phi(k)) * rhoi
    3115             : 
    3116             :           ! permeability harmonic mean
    3117    22497568 :           perm_harm = perm_harm + c1 / (perm + 1e-30_dbl_kind)
    3118             : 
    3119             :        enddo ! k
    3120             : 
    3121     2812196 :        ice_mass = ice_mass * hilyr
    3122             : 
    3123     2812196 :        perm_harm = real(nilyr,dbl_kind) / perm_harm 
    3124             : 
    3125             :        ! calculate ocean surface height above bottom of ice
    3126     2812196 :        hocn = (ice_mass + hpond * apond * rhow + hsn * rhos) / rhow
    3127             : 
    3128             :        ! calculate brine height above bottom of ice
    3129     2812196 :        hbrine = hin + hpond
    3130             : 
    3131             :        ! pressure head
    3132     2812196 :        dhhead = max(hbrine - hocn,c0)
    3133             : 
    3134             :        ! darcy flow through ice
    3135     2812196 :        w = (perm_harm * rhow * gravit * (dhhead / hin)) / viscosity_dyn
    3136             : 
    3137             :        ! maximum down flow to drain pond
    3138     2812196 :        w_down_max = (hpond * apond) / dt
    3139             : 
    3140             :        ! limit flow
    3141     2812196 :        w = min(w,w_down_max)
    3142             : 
    3143             :        ! limit amount of brine that can be advected out of any particular layer
    3144     2812196 :        wlimit = (advection_limit * phi_min * hilyr) / dt
    3145             : 
    3146     2812196 :        if (abs(w) > puny) then
    3147      198573 :           w = w * max(min(abs(wlimit/w),c1),c0)
    3148             :        else
    3149     2613623 :           w = c0
    3150             :        endif
    3151             : 
    3152     2812196 :        w = max(w, c0)
    3153             : 
    3154             :     endif
    3155             : 
    3156     3172532 :   end subroutine flushing_velocity
    3157             : 
    3158             : !=======================================================================
    3159             : 
    3160     3172532 :   subroutine flush_pond(w, hpond, apond, dt)
    3161             : 
    3162             :     ! given a flushing velocity drain the meltponds
    3163             : 
    3164             :     real(kind=dbl_kind), intent(in) :: &
    3165             :          w     , & ! vertical flushing Darcy flow rate (m s-1)
    3166             :          apond , & ! melt pond area (-)
    3167             :          dt        ! time step (s)
    3168             : 
    3169             :     real(kind=dbl_kind), intent(inout) :: &
    3170             :          hpond     ! melt pond thickness (m)
    3171             :     
    3172             :     real(kind=dbl_kind), parameter :: &
    3173             :          lambda_pond = c1 / (10.0_dbl_kind * 24.0_dbl_kind * 3600.0_dbl_kind), &
    3174             :          hpond0 = 0.01_dbl_kind
    3175             : 
    3176             :     character(len=*),parameter :: subname='(flush_pond)'
    3177             : 
    3178     3172532 :     if (tr_pond) then
    3179     2812196 :        if (apond > c0 .and. hpond > c0) then
    3180             :           
    3181             :           ! flush pond through mush
    3182     1310816 :           hpond = hpond - w * dt / apond
    3183             :           
    3184     1310816 :           hpond = max(hpond, c0)
    3185             :           
    3186             :           ! exponential decay of pond
    3187     1310816 :           hpond = hpond - lambda_pond * dt * (hpond + hpond0)
    3188             :           
    3189     1310816 :           hpond = max(hpond, c0)
    3190             :           
    3191             :        endif
    3192             :     endif
    3193             : 
    3194     3172532 :   end subroutine flush_pond
    3195             : 
    3196             :  !=======================================================================
    3197             : 
    3198     3172532 :   subroutine flood_ice(hsn,    hin,      &
    3199             :                        nslyr,  nilyr,    & 
    3200             :                        hslyr,  hilyr,    & 
    3201     3172532 :                        zqsn,   zqin,     &
    3202     3172532 :                        phi,    dt,       &
    3203     6345064 :                        zSin,   Sbr,      &
    3204             :                        sss,    qocn,     &
    3205             :                        snoice, fadvheat)
    3206             : 
    3207             :     ! given upwards flushing brine flow calculate amount of snow ice and
    3208             :     ! convert snow to ice with appropriate properties
    3209             : 
    3210             :     integer (kind=int_kind), intent(in) :: &
    3211             :          nilyr , & ! number of ice layers
    3212             :          nslyr     ! number of snow layers
    3213             : 
    3214             :     real(kind=dbl_kind), intent(in) :: &
    3215             :          dt                , & ! time step (s)
    3216             :          hsn               , & ! snow thickness (m)
    3217             :          hin               , & ! ice thickness (m)
    3218             :          sss               , & ! sea surface salinity (ppt)
    3219             :          qocn                  ! ocean brine enthalpy (J m-2)
    3220             : 
    3221             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    3222             :          zqsn              , & ! snow layer enthalpy (J m-2)
    3223             :          zqin              , & ! ice layer enthalpy (J m-2)
    3224             :          zSin              , & ! ice layer bulk salinity (ppt)
    3225             :          phi                   ! ice liquid fraction
    3226             : 
    3227             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    3228             :          Sbr                   ! ice layer brine salinity (ppt)
    3229             : 
    3230             :     real(kind=dbl_kind), intent(inout) :: &
    3231             :          hslyr             , & ! snow layer thickness (m)
    3232             :          hilyr                 ! ice layer thickness (m)
    3233             : 
    3234             :     real(kind=dbl_kind), intent(out) :: &
    3235             :          snoice                ! snow ice formation
    3236             : 
    3237             :    real(kind=dbl_kind), intent(inout) :: &
    3238             :          fadvheat              ! advection heat flux to ocean
    3239             : 
    3240             :     real(kind=dbl_kind) :: &
    3241     1064186 :          hin2              , & ! new ice thickness (m)
    3242     1064186 :          hsn2              , & ! new snow thickness (m)
    3243     1064186 :          hilyr2            , & ! new ice layer thickness (m)
    3244     1064186 :          hslyr2            , & ! new snow layer thickness (m)
    3245     1064186 :          dh                , & ! thickness of snowice formation (m)
    3246     1064186 :          phi_snowice       , & ! liquid fraction of new snow ice
    3247     1064186 :          rho_snowice       , & ! density of snowice (kg m-3)
    3248     1064186 :          zSin_snowice      , & ! bulk salinity of new snowice (ppt)
    3249     1064186 :          zqin_snowice      , & ! ice enthalpy of new snowice (J m-2)
    3250     1064186 :          zqsn_snowice      , & ! snow enthalpy of snow thats becoming snowice (J m-2)
    3251     1064186 :          freeboard_density , & ! negative of ice surface freeboard times the ocean density (kg m-2)
    3252     1064186 :          ice_mass          , & ! mass of the ice (kg m-2)
    3253     1064186 :          rho_ocn           , & ! density of the ocean (kg m-3)
    3254     1064186 :          ice_density       , & ! density of ice layer (kg m-3)
    3255     1064186 :          hadded            , & ! thickness rate of water used from ocean (m/s)
    3256     1064186 :          wadded            , & ! mass rate of water used from ocean (kg/m^2/s)
    3257     1064186 :          eadded                ! energy rate of water used from ocean (W/m^2) 
    3258             : 
    3259             : !   real(kind=dbl_kind) :: &
    3260             : !        sadded                ! salt rate of water used from ocean (kg/m^2/s)
    3261             : 
    3262             :     integer :: &
    3263             :          k                     ! vertical index
    3264             : 
    3265             :     character(len=*),parameter :: subname='(flood_ice)'
    3266             : 
    3267     3172532 :     snoice = c0
    3268             : 
    3269             :     ! check we have snow
    3270     3172532 :     if (hsn > puny) then
    3271             :        
    3272     2550448 :        rho_ocn = icepack_mushy_density_brine(sss)
    3273             : 
    3274             :        ! ice mass
    3275     2550448 :        ice_mass = c0
    3276    20403584 :        do k = 1, nilyr
    3277    17853136 :           ice_density = min(phi(k) * icepack_mushy_density_brine(Sbr(k)) + (c1 - phi(k)) * rhoi,rho_ocn)
    3278    20403584 :           ice_mass = ice_mass + ice_density
    3279             :        enddo ! k
    3280     2550448 :        ice_mass = ice_mass * hilyr
    3281             : 
    3282             :        ! negative freeboard times ocean density
    3283     2550448 :        freeboard_density = max(ice_mass + hsn * rhos - hin * rho_ocn, c0)
    3284             : 
    3285             :        ! check if have flooded ice
    3286     2550448 :        if (freeboard_density > c0) then
    3287             : 
    3288             :           ! sea ice fraction of newly formed snow ice
    3289       47430 :           phi_snowice = (c1 - rhos / rhoi)
    3290             : 
    3291             :           ! density of newly formed snowice
    3292       47430 :           rho_snowice = phi_snowice * rho_ocn + (c1 - phi_snowice) * rhoi
    3293             : 
    3294             :           ! calculate thickness of new ice added
    3295       47430 :           dh = freeboard_density / (rho_ocn - rho_snowice + rhos)
    3296       47430 :           dh = max(min(dh,hsn),c0)
    3297             : 
    3298             :           ! enthalpy of snow that becomes snowice
    3299       47430 :           call enthalpy_snow_snowice(nslyr, dh, hsn, zqsn, zqsn_snowice)
    3300       47430 :           if (icepack_warnings_aborted(subname)) return
    3301             : 
    3302             :           ! change thicknesses
    3303       47430 :           hin2 = hin + dh
    3304       47430 :           hsn2 = hsn - dh
    3305             : 
    3306       47430 :           hilyr2 = hin2 / real(nilyr,dbl_kind)
    3307       47430 :           hslyr2 = hsn2 / real(nslyr,dbl_kind)
    3308             : 
    3309             :           ! properties of new snow ice
    3310       47430 :           zSin_snowice = phi_snowice * sss
    3311       47430 :           zqin_snowice = phi_snowice * qocn + zqsn_snowice
    3312             : 
    3313             :           ! change snow properties
    3314       47430 :           call update_vertical_tracers_snow(nslyr, zqsn, hslyr, hslyr2)
    3315       47430 :           if (icepack_warnings_aborted(subname)) return
    3316             : 
    3317             :           ! change ice properties
    3318           0 :           call update_vertical_tracers_ice(nilyr, zqin, hilyr, hilyr2, &
    3319       47430 :                hin,  hin2,  zqin_snowice)
    3320       47430 :           if (icepack_warnings_aborted(subname)) return
    3321           0 :           call update_vertical_tracers_ice(nilyr, zSin, hilyr, hilyr2, &
    3322       47430 :                hin,  hin2,  zSin_snowice)
    3323       47430 :           if (icepack_warnings_aborted(subname)) return
    3324           0 :           call update_vertical_tracers_ice(nilyr, phi,  hilyr, hilyr2, &
    3325       47430 :                hin,  hin2,  phi_snowice)
    3326       47430 :           if (icepack_warnings_aborted(subname)) return
    3327             : 
    3328             :           ! change thicknesses
    3329       47430 :           hilyr = hilyr2
    3330       47430 :           hslyr = hslyr2
    3331       47430 :           snoice = dh
    3332             : 
    3333       47430 :           hadded = (dh * phi_snowice) / dt
    3334       47430 :           wadded = hadded * rhoi
    3335       47430 :           eadded = hadded * qocn
    3336             : !         sadded = wadded * ice_ref_salinity * p001
    3337             : 
    3338             :           ! conservation
    3339       47430 :           fadvheat = fadvheat - eadded
    3340             : 
    3341             :        endif
    3342             : 
    3343             :     endif
    3344             : 
    3345             :   end subroutine flood_ice
    3346             : 
    3347             : !=======================================================================
    3348             : 
    3349       47430 :   subroutine enthalpy_snow_snowice(nslyr, dh, hsn, zqsn, zqsn_snowice)
    3350             : 
    3351             :     ! determine enthalpy of the snow being converted to snow ice
    3352             :     
    3353             :     integer (kind=int_kind), intent(in) :: &
    3354             :          nslyr        ! number of snow layers
    3355             : 
    3356             :     real(kind=dbl_kind), intent(in) :: &
    3357             :          dh       , & ! thickness of new snowice formation (m)
    3358             :          hsn          ! initial snow thickness
    3359             : 
    3360             :     real(kind=dbl_kind), dimension(:), intent(in) :: &
    3361             :          zqsn         ! snow layer enthalpy (J m-2)
    3362             : 
    3363             :     real(kind=dbl_kind), intent(out) :: &
    3364             :          zqsn_snowice ! enthalpy of snow becoming snowice (J m-2)
    3365             : 
    3366             :     real(kind=dbl_kind) :: &
    3367       14278 :          rnlyr        ! real value of number of snow layers turning to snowice
    3368             : 
    3369             :     integer(kind=int_kind) :: &
    3370             :          nlyr     , & ! no of snow layers completely converted to snowice
    3371             :          k            ! snow layer index
    3372             : 
    3373             :     character(len=*),parameter :: subname='(enthalpy_snow_snowice)'
    3374             : 
    3375       47430 :     zqsn_snowice = c0
    3376             : 
    3377             :     ! snow depth and snow layers affected by snowice formation
    3378       47430 :     if (hsn > puny) then
    3379       47430 :        rnlyr = (dh / hsn) * nslyr
    3380       47430 :        nlyr = min(floor(rnlyr),nslyr-1) ! nlyr=0 if nslyr=1
    3381             : 
    3382             :        ! loop over full snow layers affected
    3383             :        ! not executed if nlyr=0
    3384       47430 :        do k = nslyr, nslyr-nlyr+1, -1
    3385       47430 :           zqsn_snowice = zqsn_snowice + zqsn(k) / rnlyr
    3386             :        enddo ! k
    3387             : 
    3388             :        ! partially converted snow layer
    3389             :        zqsn_snowice = zqsn_snowice + &
    3390       47430 :             ((rnlyr - real(nlyr,dbl_kind)) / rnlyr) * zqsn(nslyr-nlyr)
    3391             :     endif
    3392             : 
    3393       47430 :   end subroutine enthalpy_snow_snowice
    3394             : 
    3395             : !=======================================================================
    3396             :   
    3397       47430 :   subroutine update_vertical_tracers_snow(nslyr, trc, hlyr1, hlyr2)
    3398             : 
    3399             :     ! given some snow ice formation regrid snow layers
    3400             : 
    3401             :     integer (kind=int_kind), intent(in) :: &
    3402             :          nslyr       ! number of snow layers
    3403             :     
    3404             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    3405             :          trc         ! vertical tracer
    3406             : 
    3407             :     real(kind=dbl_kind), intent(in) :: &
    3408             :          hlyr1   , & ! old cell thickness
    3409             :          hlyr2       ! new cell thickness
    3410             : 
    3411             :     real(kind=dbl_kind), dimension(1:nslyr) :: &
    3412       94860 :          trc2        ! temporary array for updated tracer
    3413             :     
    3414             :     ! vertical indexes for old and new grid
    3415             :     integer(kind=int_kind) :: &
    3416             :          k1      , & ! vertical index for old grid
    3417             :          k2          ! vertical index for new grid
    3418             :     
    3419             :     real(kind=dbl_kind) :: &
    3420       14278 :          z1a     , & ! lower boundary of old cell
    3421       14278 :          z1b     , & ! upper boundary of old cell
    3422       14278 :          z2a     , & ! lower boundary of new cell
    3423       14278 :          z2b     , & ! upper boundary of new cell
    3424       14278 :          overlap     ! overlap between old and new cell
    3425             :     
    3426             :     character(len=*),parameter :: subname='(update_vertical_tracers_snow)'
    3427             : 
    3428             :     ! loop over new grid cells
    3429       94860 :     do k2 = 1, nslyr
    3430             :        
    3431             :        ! initialize new tracer
    3432       47430 :        trc2(k2) = c0
    3433             :        
    3434             :        ! calculate upper and lower boundary of new cell
    3435       47430 :        z2a = (k2 - 1) * hlyr2
    3436       47430 :        z2b = k2       * hlyr2
    3437             :        
    3438             :        ! loop over old grid cells
    3439       94860 :        do k1 = 1, nslyr
    3440             :           
    3441             :           ! calculate upper and lower boundary of old cell
    3442       47430 :           z1a = (k1 - 1) * hlyr1
    3443       47430 :           z1b = k1       * hlyr1
    3444             :           
    3445             :           ! calculate overlap between old and new cell
    3446       47430 :           overlap = max(min(z1b, z2b) - max(z1a, z2a), c0)
    3447             :           
    3448             :           ! aggregate old grid cell contribution to new cell
    3449       94860 :           trc2(k2) = trc2(k2) + overlap * trc(k1)
    3450             :           
    3451             :        enddo ! k1
    3452             : 
    3453             :        ! renormalize new grid cell
    3454       94860 :        trc2(k2) = trc2(k2) / hlyr2
    3455             :        
    3456             :     enddo ! k2
    3457             :     
    3458             :     ! update vertical tracer array with the adjusted tracer
    3459       94860 :     trc = trc2
    3460             : 
    3461       47430 :   end subroutine update_vertical_tracers_snow
    3462             : 
    3463             : !=======================================================================
    3464             :   
    3465      142290 :   subroutine update_vertical_tracers_ice(nilyr, trc, hlyr1, hlyr2, &
    3466             :                                          h1, h2, trc0)
    3467             : 
    3468             :     ! given some snow ice formation regrid ice layers
    3469             : 
    3470             :     integer (kind=int_kind), intent(in) :: &
    3471             :          nilyr       ! number of ice layers
    3472             : 
    3473             :     real(kind=dbl_kind), dimension(:), intent(inout) :: &
    3474             :          trc         ! vertical tracer
    3475             :     
    3476             :     real(kind=dbl_kind), intent(in) :: &
    3477             :          hlyr1 , &   ! old cell thickness
    3478             :          hlyr2 , &   ! new cell thickness
    3479             :          h1    , &   ! old total thickness
    3480             :          h2    , &   ! new total thickness
    3481             :          trc0        ! tracer value of added snow ice on ice top
    3482             :     
    3483             :     real(kind=dbl_kind), dimension(1:nilyr) :: &
    3484      541584 :          trc2        ! temporary array for updated tracer
    3485             :     
    3486             :     integer(kind=int_kind) :: &
    3487             :          k1 , &      ! vertical indexes for old grid
    3488             :          k2          ! vertical indexes for new grid
    3489             :     
    3490             :     real(kind=dbl_kind) :: &
    3491       42834 :          z1a     , & ! lower boundary of old cell
    3492       42834 :          z1b     , & ! upper boundary of old cell
    3493       42834 :          z2a     , & ! lower boundary of new cell
    3494       42834 :          z2b     , & ! upper boundary of new cell
    3495       42834 :          overlap     ! overlap between old and new cell
    3496             :     
    3497             :     character(len=*),parameter :: subname='(update_vertical_tracers_ice)'
    3498             : 
    3499             :     ! loop over new grid cells
    3500     1138320 :     do k2 = 1, nilyr
    3501             :        
    3502             :        ! initialize new tracer
    3503      996030 :        trc2(k2) = c0
    3504             :        
    3505             :        ! calculate upper and lower boundary of new cell
    3506      996030 :        z2a = (k2 - 1) * hlyr2
    3507      996030 :        z2b = k2       * hlyr2
    3508             : 
    3509             :        ! calculate upper and lower boundary of added snow ice at top
    3510      996030 :        z1a = c0
    3511      996030 :        z1b = h2 - h1
    3512             :        
    3513             :        ! calculate overlap between added ice and new cell
    3514      996030 :        overlap = max(min(z1b, z2b) - max(z1a, z2a), c0)
    3515             :        
    3516             :        ! aggregate added ice contribution to new cell
    3517      996030 :        trc2(k2) = trc2(k2) + overlap * trc0
    3518             : 
    3519             :        ! loop over old grid cells
    3520     7968240 :        do k1 = 1, nilyr
    3521             :           
    3522             :           ! calculate upper and lower boundary of old cell
    3523     6972210 :           z1a = (k1 - 1) * hlyr1 + h2 - h1
    3524     6972210 :           z1b = k1       * hlyr1 + h2 - h1
    3525             :           
    3526             :           ! calculate overlap between old and new cell
    3527     6972210 :           overlap = max(min(z1b, z2b) - max(z1a, z2a), c0)
    3528             :           
    3529             :           ! aggregate old grid cell contribution to new cell
    3530     7968240 :           trc2(k2) = trc2(k2) + overlap * trc(k1)
    3531             :           
    3532             :        enddo ! k1
    3533             : 
    3534             :        ! renormalize new grid cell
    3535     1138320 :        trc2(k2) = trc2(k2) / hlyr2
    3536             :        
    3537             :     enddo ! k2
    3538             :     
    3539             :     ! update vertical tracer array with the adjusted tracer
    3540     1138320 :     trc = trc2
    3541             : 
    3542      142290 :   end subroutine update_vertical_tracers_ice
    3543             : 
    3544             : !=======================================================================
    3545             : 
    3546             : end module icepack_therm_mushy
    3547             : 
    3548             : !=======================================================================

Generated by: LCOV version 1.14-6-g40580cd