LCOV - code coverage report
Current view: top level - columnphysics - icepack_therm_mushy.F90 (source / functions) Coverage Total Hit
Test: 250117-002718:9f4b99afd9:4:base,io,travis,quick Lines: 79.19 % 913 723
Test Date: 2025-01-16 18:02:43 Functions: 93.94 % 33 31

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

Generated by: LCOV version 2.0-1