LCOV - code coverage report
Current view: top level - icepack/columnphysics - icepack_therm_itd.F90 (source / functions) Hit Total Coverage
Test: 231018-211459:8916b9ff2c:1:quick Lines: 384 682 56.30 %
Date: 2023-10-18 15:30:36 Functions: 6 6 100.00 %

          Line data    Source code
       1             : !=======================================================================
       2             : !
       3             : ! Thermo calculations after call to coupler, related to ITD:
       4             : ! ice thickness redistribution, lateral growth and melting.
       5             : !
       6             : ! NOTE: The thermodynamic calculation is split in two for load balancing.
       7             : !       First icepack_therm_vertical computes vertical growth rates and coupler
       8             : !       fluxes.  Then icepack_therm_itd does thermodynamic calculations not
       9             : !       needed for coupling.
      10             : !
      11             : ! authors William H. Lipscomb, LANL
      12             : !         C. M. Bitz, UW
      13             : !         Elizabeth C. Hunke, LANL
      14             : !
      15             : ! 2003: Vectorized by Clifford Chen (Fujitsu) and William Lipscomb
      16             : ! 2004: Block structure added by William Lipscomb
      17             : ! 2006: Streamlined for efficiency by Elizabeth Hunke
      18             : ! 2014: Column package created by Elizabeth Hunke
      19             : !
      20             :       module icepack_therm_itd
      21             : 
      22             :       use icepack_kinds
      23             :       use icepack_parameters, only: c0, c1, c2, c3, c4, c6, c10
      24             :       use icepack_parameters, only: p001, p1, p333, p5, p666, puny, bignum
      25             :       use icepack_parameters, only: rhos, rhoi, Lfresh, ice_ref_salinity
      26             :       use icepack_parameters, only: phi_init, dsin0_frazil, hs_ssl, salt_loss
      27             :       use icepack_parameters, only: Tliquidus_max
      28             :       use icepack_parameters, only: rhosi, conserv_check, rhosmin, snwredist
      29             :       use icepack_parameters, only: kitd, ktherm
      30             :       use icepack_parameters, only: z_tracers, hfrazilmin, hi_min
      31             :       use icepack_parameters, only: cpl_frazil, update_ocn_f, saltflux_option
      32             :       use icepack_parameters, only: icepack_chkoptargflag
      33             : 
      34             :       use icepack_tracers, only: ntrcr, nbtrcr
      35             :       use icepack_tracers, only: nt_qice, nt_qsno, nt_fbri, nt_sice
      36             :       use icepack_tracers, only: nt_apnd, nt_hpnd, nt_aero, nt_isosno, nt_isoice
      37             :       use icepack_tracers, only: nt_Tsfc, nt_iage, nt_FY, nt_fsd, nt_rhos, nt_sice
      38             :       use icepack_tracers, only: nt_alvl, nt_vlvl
      39             :       use icepack_tracers, only: tr_pond_lvl, tr_pond_topo
      40             :       use icepack_tracers, only: tr_iage, tr_FY, tr_lvl, tr_aero, tr_iso, tr_brine, tr_fsd
      41             :       use icepack_tracers, only: n_aero, n_iso
      42             :       use icepack_tracers, only: bio_index
      43             : 
      44             :       use icepack_warnings, only: warnstr, icepack_warnings_add
      45             :       use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted
      46             : 
      47             :       use icepack_fsd, only: fsd_weld_thermo, icepack_cleanup_fsd,  get_subdt_fsd
      48             :       use icepack_itd, only: reduce_area, cleanup_itd
      49             :       use icepack_itd, only: aggregate_area, shift_ice
      50             :       use icepack_itd, only: column_sum, column_conservation_check
      51             :       use icepack_isotope, only: isoice_alpha, isotope_frac_method
      52             :       use icepack_mushy_physics, only: liquidus_temperature_mush, icepack_enthalpy_mush
      53             :       use icepack_zbgc, only: add_new_ice_bgc
      54             :       use icepack_zbgc, only: lateral_melt_bgc
      55             : 
      56             :       implicit none
      57             : 
      58             :       private
      59             :       public :: icepack_step_therm2
      60             : 
      61             : !=======================================================================
      62             : 
      63             :       contains
      64             : 
      65             : !=======================================================================
      66             : !
      67             : ! ITD scheme that shifts ice among categories
      68             : !
      69             : ! See Lipscomb, W. H.  Remapping the thickness distribution in sea
      70             : !     ice models. 2001, J. Geophys. Res., Vol 106, 13989--14000.
      71             : !
      72             : ! Using the thermodynamic "velocities", interpolate to find the
      73             : ! velocities in thickness space at the category boundaries, and
      74             : ! compute the new locations of the boundaries.  Then for each
      75             : ! category, compute the thickness distribution function,  g(h),
      76             : ! between hL and hR, the left and right boundaries of the category.
      77             : ! Assume g(h) is a linear polynomial that satisfies two conditions:
      78             : !
      79             : ! (1) The ice area implied by g(h) equals aicen(n).
      80             : ! (2) The ice volume implied by g(h) equals aicen(n)*hicen(n).
      81             : !
      82             : ! Given g(h), at each boundary compute the ice area and volume lying
      83             : ! between the original and new boundary locations.  Transfer area
      84             : ! and volume across each boundary in the appropriate direction, thus
      85             : ! restoring the original boundaries.
      86             : !
      87             : ! authors: William H. Lipscomb, LANL
      88             : !          Elizabeth C. Hunke, LANL
      89             : 
      90    13632946 :       subroutine linear_itd (ncat,        hin_max,     &
      91             :                              nilyr,       nslyr,       &   ! LCOV_EXCL_LINE
      92             :                              ntrcr,       trcr_depend, &   ! LCOV_EXCL_LINE
      93             :                              trcr_base,   n_trcr_strata,&   ! LCOV_EXCL_LINE
      94             :                              nt_strata,                &   ! LCOV_EXCL_LINE
      95             :                              aicen_init,  vicen_init,  &    ! LCOV_EXCL_LINE
      96             :                              aicen,       trcrn,       &    ! LCOV_EXCL_LINE
      97             :                              vicen,       vsnon,       &    ! LCOV_EXCL_LINE
      98             :                              aice,        aice0,       &    ! LCOV_EXCL_LINE
      99             :                              fpond,       Tf           )
     100             : 
     101             :       integer (kind=int_kind), intent(in) :: &
     102             :          ncat    , & ! number of thickness categories   ! LCOV_EXCL_LINE
     103             :          nilyr   , & ! number of ice layers   ! LCOV_EXCL_LINE
     104             :          nslyr   , & ! number of snow layers   ! LCOV_EXCL_LINE
     105             :          ntrcr       ! number of tracers in use
     106             : 
     107             :       real (kind=dbl_kind), dimension(0:ncat), intent(in) :: &
     108             :          hin_max      ! category boundaries (m)
     109             : 
     110             :       integer (kind=int_kind), dimension (:), intent(in) :: &
     111             :          trcr_depend, & ! = 0 for aicen tracers, 1 for vicen, 2 for vsnon   ! LCOV_EXCL_LINE
     112             :          n_trcr_strata  ! number of underlying tracer layers
     113             : 
     114             :       real (kind=dbl_kind), dimension (:,:), intent(in) :: &
     115             :          trcr_base      ! = 0 or 1 depending on tracer dependency
     116             :                         ! argument 2:  (1) aice, (2) vice, (3) vsno
     117             : 
     118             :       integer (kind=int_kind), dimension (:,:), intent(in) :: &
     119             :          nt_strata      ! indices of underlying tracer layers
     120             : 
     121             :       real (kind=dbl_kind), intent(in) :: &
     122             :          Tf             ! freezing temperature
     123             : 
     124             :       real (kind=dbl_kind), dimension(:), intent(in) :: &
     125             :          aicen_init, & ! initial ice concentration (before vertical thermo)   ! LCOV_EXCL_LINE
     126             :          vicen_init    ! initial ice volume               (m)
     127             : 
     128             :       real (kind=dbl_kind), dimension (:), intent(inout) :: &
     129             :          aicen  , & ! ice concentration   ! LCOV_EXCL_LINE
     130             :          vicen  , & ! volume per unit area of ice      (m)   ! LCOV_EXCL_LINE
     131             :          vsnon      ! volume per unit area of snow     (m)
     132             : 
     133             :       real (kind=dbl_kind), dimension (:,:), intent(inout) :: &
     134             :          trcrn     ! ice tracers
     135             : 
     136             :       real (kind=dbl_kind), intent(inout) :: &
     137             :          aice  , & ! concentration of ice   ! LCOV_EXCL_LINE
     138             :          aice0 , & ! concentration of open water   ! LCOV_EXCL_LINE
     139             :          fpond     ! fresh water flux to ponds (kg/m^2/s)
     140             : 
     141             :       ! local variables
     142             : 
     143             :       integer (kind=int_kind) :: &
     144             :          n, nd        , & ! category indices   ! LCOV_EXCL_LINE
     145             :          k                ! ice layer index
     146             : 
     147             :       real (kind=dbl_kind) :: &
     148             :          slope        , & ! rate of change of dhice with hice   ! LCOV_EXCL_LINE
     149             :          dh0          , & ! change in ice thickness at h = 0   ! LCOV_EXCL_LINE
     150             :          da0          , & ! area melting from category 1   ! LCOV_EXCL_LINE
     151             :          damax        , & ! max allowed reduction in category 1 area   ! LCOV_EXCL_LINE
     152             :          etamin, etamax,& ! left and right limits of integration   ! LCOV_EXCL_LINE
     153             :          x1           , & ! etamax - etamin   ! LCOV_EXCL_LINE
     154             :          x2           , & ! (etamax^2 - etamin^2) / 2   ! LCOV_EXCL_LINE
     155             :          x3           , & ! (etamax^3 - etamin^3) / 3   ! LCOV_EXCL_LINE
     156      630473 :          wk1, wk2         ! temporary variables
     157             : 
     158             :       real (kind=dbl_kind), dimension(0:ncat) :: &
     159    16785311 :          hbnew            ! new boundary locations
     160             : 
     161             :       real (kind=dbl_kind), dimension(ncat) :: &
     162             :          g0           , & ! constant coefficient in g(h)   ! LCOV_EXCL_LINE
     163             :          g1           , & ! linear coefficient in g(h)   ! LCOV_EXCL_LINE
     164             :          hL           , & ! left end of range over which g(h) > 0   ! LCOV_EXCL_LINE
     165    16154838 :          hR               ! right end of range over which g(h) > 0
     166             : 
     167             :       real (kind=dbl_kind), dimension(ncat) :: &
     168             :          hicen        , & ! ice thickness for each cat     (m)   ! LCOV_EXCL_LINE
     169             :          hicen_init   , & ! initial ice thickness for each cat (pre-thermo)   ! LCOV_EXCL_LINE
     170             :          dhicen       , & ! thickness change for remapping (m)   ! LCOV_EXCL_LINE
     171             :          daice        , & ! ice area transferred across boundary   ! LCOV_EXCL_LINE
     172    16154838 :          dvice            ! ice volume transferred across boundary
     173             : 
     174             :       real (kind=dbl_kind), dimension (ncat) :: &
     175             :          eicen, &     ! energy of melting for each ice layer (J/m^2)   ! LCOV_EXCL_LINE
     176             :          esnon, &     ! energy of melting for each snow layer (J/m^2)   ! LCOV_EXCL_LINE
     177             :          vbrin, &     ! ice volume defined by brine height (m)   ! LCOV_EXCL_LINE
     178    16154838 :          sicen        ! Bulk salt in h ice (ppt*m)
     179             : 
     180             :       real (kind=dbl_kind) :: &
     181             :          vice_init, vice_final, & ! ice volume summed over categories   ! LCOV_EXCL_LINE
     182             :          vsno_init, vsno_final, & ! snow volume summed over categories   ! LCOV_EXCL_LINE
     183             :          eice_init, eice_final, & ! ice energy summed over categories   ! LCOV_EXCL_LINE
     184             :          esno_init, esno_final, & ! snow energy summed over categories   ! LCOV_EXCL_LINE
     185             :          sice_init, sice_final, & ! ice bulk salinity summed over categories   ! LCOV_EXCL_LINE
     186      630473 :          vbri_init, vbri_final    ! briny ice volume summed over categories
     187             : 
     188             :       ! NOTE: Third index of donor, daice, dvice should be ncat-1,
     189             :       !       except that compilers would have trouble when ncat = 1
     190             :       integer (kind=int_kind), dimension(ncat) :: &
     191     7446946 :          donor            ! donor category index
     192             : 
     193             :       logical (kind=log_kind) :: &
     194             :          remap_flag       ! remap ITD if remap_flag is true
     195             : 
     196             :       character (len=char_len) :: &
     197             :          fieldid           ! field identifier
     198             : 
     199             :       logical (kind=log_kind), parameter :: &
     200             :          print_diags = .false.    ! if true, prints when remap_flag=F
     201             : 
     202             :       character(len=*),parameter :: subname='(linear_itd)'
     203             : 
     204             :       !-----------------------------------------------------------------
     205             :       ! Initialize
     206             :       !-----------------------------------------------------------------
     207             : 
     208    40898838 :       do n = 1, ncat
     209    34082365 :          donor(n) = 0
     210    34082365 :          daice(n) = c0
     211    40898838 :          dvice(n) = c0
     212             :       enddo
     213             : 
     214             :       !-----------------------------------------------------------------
     215             :       ! Compute volume and energy sums that linear remapping should
     216             :       !  conserve.
     217             :       !-----------------------------------------------------------------
     218             : 
     219     6816473 :       if (conserv_check) then
     220             : 
     221           0 :       do n = 1, ncat
     222             : 
     223           0 :          eicen(n) = c0
     224           0 :          esnon(n) = c0
     225           0 :          vbrin(n) = c0
     226           0 :          sicen(n) = c0
     227             : 
     228           0 :          do k = 1, nilyr
     229           0 :             eicen(n) = eicen(n) + trcrn(nt_qice+k-1,n) &
     230           0 :                      * vicen(n)/real(nilyr,kind=dbl_kind)
     231             :          enddo
     232           0 :          do k = 1, nslyr
     233           0 :             esnon(n) = esnon(n) + trcrn(nt_qsno+k-1,n) &
     234           0 :                      * vsnon(n)/real(nslyr,kind=dbl_kind)
     235             :          enddo
     236             : 
     237           0 :          if (tr_brine) then
     238           0 :             vbrin(n) = vbrin(n) + trcrn(nt_fbri,n) &
     239           0 :                      * vicen(n)
     240             :          endif
     241             : 
     242           0 :          do k = 1, nilyr
     243           0 :             sicen(n) = sicen(n) + trcrn(nt_sice+k-1,n) &
     244           0 :                      * vicen(n)/real(nilyr,kind=dbl_kind)
     245             :          enddo
     246             : 
     247             :       enddo ! n
     248             : 
     249           0 :       call column_sum (ncat, vicen, vice_init)
     250           0 :       if (icepack_warnings_aborted(subname)) return
     251           0 :       call column_sum (ncat, vsnon, vsno_init)
     252           0 :       if (icepack_warnings_aborted(subname)) return
     253           0 :       call column_sum (ncat, eicen, eice_init)
     254           0 :       if (icepack_warnings_aborted(subname)) return
     255           0 :       call column_sum (ncat, esnon, esno_init)
     256           0 :       if (icepack_warnings_aborted(subname)) return
     257           0 :       call column_sum (ncat, sicen, sice_init)
     258           0 :       if (icepack_warnings_aborted(subname)) return
     259           0 :       call column_sum (ncat, vbrin, vbri_init)
     260           0 :       if (icepack_warnings_aborted(subname)) return
     261             : 
     262             :       endif ! conserv_check
     263             : 
     264             :       !-----------------------------------------------------------------
     265             :       ! Initialize remapping flag.
     266             :       ! Remapping is done wherever remap_flag = .true.
     267             :       ! In rare cases the category boundaries may shift too far for the
     268             :       !  remapping algorithm to work, and remap_flag is set to .false.
     269             :       ! In these cases the simpler 'rebin' subroutine will shift ice
     270             :       !  between categories if needed.
     271             :       !-----------------------------------------------------------------
     272             : 
     273     6816473 :       remap_flag = .true.
     274             : 
     275             :       !-----------------------------------------------------------------
     276             :       ! Compute thickness change in each category.
     277             :       !-----------------------------------------------------------------
     278             : 
     279    40898838 :       do n = 1, ncat
     280             : 
     281    34082365 :          if (aicen_init(n) > puny) then
     282    33851990 :              hicen_init(n) = vicen_init(n) / aicen_init(n)
     283             :          else
     284      230375 :              hicen_init(n) = c0
     285             :          endif               ! aicen_init > puny
     286             : 
     287    40898838 :          if (aicen (n) > puny) then
     288    33851451 :              hicen (n) = vicen(n) / aicen(n)
     289    33851451 :              dhicen(n) = hicen(n) - hicen_init(n)
     290             :          else
     291      230914 :              hicen (n) = c0
     292      230914 :              dhicen(n) = c0
     293             :          endif               ! aicen > puny
     294             : 
     295             :       enddo                     ! n
     296             : 
     297             :       !-----------------------------------------------------------------
     298             :       ! Compute new category boundaries, hbnew, based on changes in
     299             :       ! ice thickness from vertical thermodynamics.
     300             :       !-----------------------------------------------------------------
     301             : 
     302     6816473 :       hbnew(0) = hin_max(0)
     303             : 
     304    34082365 :       do n = 1, ncat-1
     305             : 
     306    27265892 :          if (hicen_init(n)   > puny .and. &
     307             :              hicen_init(n+1) > puny) then
     308             : 
     309    27033421 :             if ((hicen_init(n+1) - hicen_init(n))>0) then
     310             : 
     311             :               ! interpolate between adjacent category growth rates
     312     2455592 :               slope = (dhicen(n+1) - dhicen(n)) / &
     313    29489013 :                  (hicen_init(n+1) - hicen_init(n))
     314     2455592 :               hbnew(n) = hin_max(n) + dhicen(n) &
     315    27033421 :                       + slope * (hin_max(n) - hicen_init(n))
     316             : 
     317             :             else
     318             : 
     319           0 :               write(warnstr,*) subname, &
     320           0 :                  'ITD Thermodynamics: hicen_init(n+1) <= hicen_init(n)'
     321           0 :               call icepack_warnings_setabort(.true.)
     322           0 :               call icepack_warnings_add(warnstr)
     323             : 
     324             :             endif
     325             : 
     326      232471 :          elseif (hicen_init(n) > puny) then ! hicen_init(n+1)=0
     327       91170 :              hbnew(n) = hin_max(n) + dhicen(n)
     328      141301 :          elseif (hicen_init(n+1) > puny) then ! hicen_init(n)=0
     329       38122 :              hbnew(n) = hin_max(n) + dhicen(n+1)
     330             :          else
     331      103179 :              hbnew(n) = hin_max(n)
     332             :          endif
     333             : 
     334             :       !-----------------------------------------------------------------
     335             :       ! Check that each boundary lies between adjacent values of hicen.
     336             :       ! If not, set remap_flag = .false.
     337             :       ! Write diagnosis outputs if remap_flag was changed to false
     338             :       !-----------------------------------------------------------------
     339             : 
     340    27265892 :          if (aicen(n) > puny .and. hicen(n) >= hbnew(n)) then
     341           0 :             remap_flag = .false.
     342             : 
     343             :             if (print_diags) then
     344             :                write(warnstr,*) subname, 'ITD: hicen(n) > hbnew(n)'
     345             :                call icepack_warnings_add(warnstr)
     346             :                write(warnstr,*) subname, 'cat ',n
     347             :                call icepack_warnings_add(warnstr)
     348             :                write(warnstr,*) subname, 'hicen(n) =', hicen(n)
     349             :                call icepack_warnings_add(warnstr)
     350             :                write(warnstr,*) subname, 'hbnew(n) =', hbnew(n)
     351             :                call icepack_warnings_add(warnstr)
     352             :             endif
     353             : 
     354    27265892 :          elseif (aicen(n+1) > puny .and. hicen(n+1) <= hbnew(n)) then
     355           0 :             remap_flag = .false.
     356             : 
     357             :             if (print_diags) then
     358             :                write(warnstr,*) subname, 'ITD: hicen(n+1) < hbnew(n)'
     359             :                call icepack_warnings_add(warnstr)
     360             :                write(warnstr,*) subname, 'cat ',n
     361             :                call icepack_warnings_add(warnstr)
     362             :                write(warnstr,*) subname, 'hicen(n+1) =', hicen(n+1)
     363             :                call icepack_warnings_add(warnstr)
     364             :                write(warnstr,*) subname, 'hbnew(n) =', hbnew(n)
     365             :                call icepack_warnings_add(warnstr)
     366             :             endif
     367             :          endif
     368             : 
     369             :       !-----------------------------------------------------------------
     370             :       ! Check that hbnew(n) lies between hin_max(n-1) and hin_max(n+1).
     371             :       ! If not, set remap_flag = .false.
     372             :       ! (In principle we could allow this, but it would make the code
     373             :       ! more complicated.)
     374             :       ! Write diagnosis outputs if remap_flag was changed to false
     375             :       !-----------------------------------------------------------------
     376             : 
     377    27265892 :          if (hbnew(n) > hin_max(n+1)) then
     378           0 :             remap_flag = .false.
     379             : 
     380             :             if (print_diags) then
     381             :                write(warnstr,*) subname, 'ITD hbnew(n) > hin_max(n+1)'
     382             :                call icepack_warnings_add(warnstr)
     383             :                write(warnstr,*) subname, 'cat ',n
     384             :                call icepack_warnings_add(warnstr)
     385             :                write(warnstr,*) subname, 'hbnew(n) =', hbnew(n)
     386             :                call icepack_warnings_add(warnstr)
     387             :                write(warnstr,*) subname, 'hin_max(n+1) =', hin_max(n+1)
     388             :                call icepack_warnings_add(warnstr)
     389             :             endif
     390             :          endif
     391             : 
     392    34082365 :          if (hbnew(n) < hin_max(n-1)) then
     393           0 :             remap_flag = .false.
     394             : 
     395             :             if (print_diags) then
     396             :                write(warnstr,*) subname, 'ITD: hbnew(n) < hin_max(n-1)'
     397             :                call icepack_warnings_add(warnstr)
     398             :                write(warnstr,*) subname, 'cat ',n
     399             :                call icepack_warnings_add(warnstr)
     400             :                write(warnstr,*) subname, 'hbnew(n) =', hbnew(n)
     401             :                call icepack_warnings_add(warnstr)
     402             :                write(warnstr,*) subname, 'hin_max(n-1) =', hin_max(n-1)
     403             :                call icepack_warnings_add(warnstr)
     404             :             endif
     405             :          endif
     406             : 
     407             :       enddo                     ! boundaries, 1 to ncat-1
     408             : 
     409             :       !-----------------------------------------------------------------
     410             :       ! Compute hbnew(ncat)
     411             :       !-----------------------------------------------------------------
     412             : 
     413     6816473 :       if (aicen(ncat) > puny) then
     414     6727399 :          hbnew(ncat) = c3*hicen(ncat) - c2*hbnew(ncat-1)
     415             :       else
     416       89074 :          hbnew(ncat) = hin_max(ncat)
     417             :       endif
     418     6816473 :       hbnew(ncat) = max(hbnew(ncat),hin_max(ncat-1))
     419             : 
     420             :       !-----------------------------------------------------------------
     421             :       ! Identify cells where the ITD is to be remapped
     422             :       !-----------------------------------------------------------------
     423             : 
     424     6816473 :       if (remap_flag) then
     425             : 
     426             :       !-----------------------------------------------------------------
     427             :       ! Compute g(h) for category 1 at start of time step
     428             :       ! (hicen = hicen_init)
     429             :       !-----------------------------------------------------------------
     430             : 
     431      630473 :          call fit_line(aicen(1),   hicen_init(1), &
     432             :                        hbnew(0),   hin_max   (1), &   ! LCOV_EXCL_LINE
     433             :                        g0   (1),   g1        (1), &   ! LCOV_EXCL_LINE
     434     6816473 :                        hL   (1),   hR        (1))
     435     6816473 :          if (icepack_warnings_aborted(subname)) return
     436             : 
     437             :       !-----------------------------------------------------------------
     438             :       ! Find area lost due to melting of thin (category 1) ice
     439             :       !-----------------------------------------------------------------
     440             : 
     441     6816473 :          if (aicen(1) > puny) then
     442             : 
     443     6779908 :             dh0 = dhicen(1)
     444     6779908 :             if (dh0 < c0) then   ! remove area from category 1
     445      739306 :                dh0 = min(-dh0,hin_max(1))   ! dh0 --> |dh0|
     446             : 
     447             :       !-----------------------------------------------------------------
     448             :       ! Integrate g(1) from 0 to dh0 to estimate area melted
     449             :       !-----------------------------------------------------------------
     450             : 
     451             :                ! right integration limit (left limit = 0)
     452      739306 :                etamax = min(dh0,hR(1)) - hL(1)
     453             : 
     454      739306 :                if (etamax > c0) then
     455      625852 :                   x1 = etamax
     456      625852 :                   x2 = p5 * etamax*etamax
     457      625852 :                   da0 = g1(1)*x2 + g0(1)*x1 ! ice area removed
     458             : 
     459             :                ! constrain new thickness <= hicen_init
     460      625852 :                   damax = aicen(1) * (c1-hicen(1)/hicen_init(1)) ! damax > 0
     461      625852 :                   da0 = min (da0, damax)
     462             : 
     463             :                ! remove area, conserving volume
     464      625852 :                   hicen(1) = hicen(1) * aicen(1) / (aicen(1)-da0)
     465      625852 :                   aicen(1) = aicen(1) - da0
     466             : 
     467      625852 :                   if (tr_pond_topo) &
     468             :                      fpond = fpond - (da0 * trcrn(nt_apnd,1) &   ! LCOV_EXCL_LINE
     469           0 :                                           * trcrn(nt_hpnd,1))
     470             : 
     471             :                endif            ! etamax > 0
     472             : 
     473             :             else                ! dh0 >= 0
     474     6040602 :                hbnew(0) = min(dh0,hin_max(1))  ! shift hbnew(0) to right
     475             :             endif
     476             : 
     477             :          endif                  ! aicen(1) > puny
     478             : 
     479             :       !-----------------------------------------------------------------
     480             :       ! Compute g(h) for each ice thickness category.
     481             :       !-----------------------------------------------------------------
     482             : 
     483    40898838 :          do n = 1, ncat
     484             : 
     485     3152365 :             call fit_line(aicen(n),   hicen(n), &
     486             :                           hbnew(n-1), hbnew(n), &   ! LCOV_EXCL_LINE
     487             :                           g0   (n),   g1   (n), &   ! LCOV_EXCL_LINE
     488    37234730 :                           hL   (n),   hR   (n))
     489    34082365 :             if (icepack_warnings_aborted(subname)) return
     490             : 
     491             :       !-----------------------------------------------------------------
     492             :       ! Compute area and volume to be shifted across each boundary.
     493             :       !-----------------------------------------------------------------
     494             : 
     495    34082365 :             donor(n) = 0
     496    34082365 :             daice(n) = c0
     497    44051203 :             dvice(n) = c0
     498             :          enddo
     499             : 
     500    34082365 :          do n = 1, ncat-1
     501             : 
     502    27265892 :             if (hbnew(n) > hin_max(n)) then ! transfer from n to n+1
     503             : 
     504             :                ! left and right integration limits in eta space
     505    23321315 :                etamin = max(hin_max(n), hL(n)) - hL(n)
     506    23321315 :                etamax = min(hbnew(n),   hR(n)) - hL(n)
     507    23321315 :                donor(n) = n
     508             : 
     509             :             else             ! hbnew(n) <= hin_max(n); transfer from n+1 to n
     510             : 
     511             :                ! left and right integration limits in eta space
     512     3944577 :                etamin = c0
     513     3944577 :                etamax = min(hin_max(n), hR(n+1)) - hL(n+1)
     514     3944577 :                donor(n) = n+1
     515             : 
     516             :             endif            ! hbnew(n) > hin_max(n)
     517             : 
     518    27265892 :             if (etamax > etamin) then
     519    15657100 :                x1  = etamax - etamin
     520    15657100 :                wk1 = etamin*etamin
     521    15657100 :                wk2 = etamax*etamax
     522    15657100 :                x2  = p5 * (wk2 - wk1)
     523    15657100 :                wk1 = wk1*etamin
     524    15657100 :                wk2 = wk2*etamax
     525    15657100 :                x3  = p333 * (wk2 - wk1)
     526    15657100 :                nd  = donor(n)
     527    15657100 :                daice(n) = g1(nd)*x2 + g0(nd)*x1
     528    15657100 :                dvice(n) = g1(nd)*x3 + g0(nd)*x2 + daice(n)*hL(nd)
     529             :             endif               ! etamax > etamin
     530             : 
     531             :             ! If daice or dvice is very small, shift no ice.
     532             : 
     533    27265892 :             nd = donor(n)
     534             : 
     535    27265892 :             if (daice(n) < aicen(nd)*puny) then
     536    11417317 :                daice(n) = c0
     537    11417317 :                dvice(n) = c0
     538    11417317 :                donor(n) = 0
     539             :             endif
     540             : 
     541    27265892 :             if (dvice(n) < vicen(nd)*puny) then
     542    11417317 :                daice(n) = c0
     543    11417317 :                dvice(n) = c0
     544    11417317 :                donor(n) = 0
     545             :             endif
     546             : 
     547             :             ! If daice is close to aicen or dvice is close to vicen,
     548             :             ! shift entire category
     549             : 
     550    27265892 :             if (daice(n) > aicen(nd)*(c1-puny)) then
     551         244 :                daice(n) = aicen(nd)
     552         244 :                dvice(n) = vicen(nd)
     553             :             endif
     554             : 
     555    34082365 :             if (dvice(n) > vicen(nd)*(c1-puny)) then
     556         244 :                daice(n) = aicen(nd)
     557         244 :                dvice(n) = vicen(nd)
     558             :             endif
     559             : 
     560             :          enddo                     ! boundaries, 1 to ncat-1
     561             : 
     562             :       !-----------------------------------------------------------------
     563             :       ! Shift ice between categories as necessary
     564             :       !-----------------------------------------------------------------
     565             : 
     566             :          ! maintain qsno negative definiteness
     567    40898838 :          do n = 1, ncat
     568    74981203 :             do k = nt_qsno, nt_qsno+nslyr-1
     569    68164730 :                trcrn(k,n) = trcrn(k,n) + rhos*Lfresh
     570             :             enddo
     571             :          enddo
     572             :          ! maintain rhos_cmp positive definiteness
     573     6816473 :          if (snwredist(1:3) == 'ITD') then
     574           0 :             do n = 1, ncat
     575           0 :                do k = nt_rhos, nt_rhos+nslyr-1
     576           0 :                   trcrn(k,n) = max(trcrn(k,n)-rhosmin, c0)
     577             : !                  trcrn(k,n) = trcrn(k,n) - rhosmin
     578             :                enddo
     579             :             enddo
     580             :          endif
     581             : 
     582             :          call shift_ice (ntrcr,    ncat,        &
     583             :                          trcr_depend,           &   ! LCOV_EXCL_LINE
     584             :                          trcr_base,             &   ! LCOV_EXCL_LINE
     585             :                          n_trcr_strata,         &   ! LCOV_EXCL_LINE
     586             :                          nt_strata,             &   ! LCOV_EXCL_LINE
     587             :                          aicen,    trcrn,       &   ! LCOV_EXCL_LINE
     588             :                          vicen,    vsnon,       &   ! LCOV_EXCL_LINE
     589             :                          hicen,    donor,       &   ! LCOV_EXCL_LINE
     590     6816473 :                          daice,    dvice, Tf    )
     591     6816473 :          if (icepack_warnings_aborted(subname)) return
     592             : 
     593             :          ! maintain qsno negative definiteness
     594    40898838 :          do n = 1, ncat
     595    74981203 :             do k = nt_qsno, nt_qsno+nslyr-1
     596    68164730 :                trcrn(k,n) = trcrn(k,n) - rhos*Lfresh
     597             :             enddo
     598             :          enddo
     599             :          ! maintain rhos_cmp positive definiteness
     600     6816473 :          if (snwredist(1:3) == 'ITD') then
     601           0 :             do n = 1, ncat
     602           0 :                do k = nt_rhos, nt_rhos+nslyr-1
     603           0 :                   trcrn(k,n) = trcrn(k,n) + rhosmin
     604             :                enddo
     605             :             enddo
     606             :          endif
     607             : 
     608             :       !-----------------------------------------------------------------
     609             :       ! Make sure hice(1) >= minimum ice thickness hi_min.
     610             :       !-----------------------------------------------------------------
     611             : 
     612     6816473 :          if (hi_min > c0 .and. aicen(1) > puny .and. hicen(1) < hi_min) then
     613             : 
     614        2666 :             da0 = aicen(1) * (c1 - hicen(1)/hi_min)
     615        2666 :             aicen(1) = aicen(1) - da0
     616        2666 :             hicen(1) = hi_min
     617             : 
     618        2666 :             if (tr_pond_topo) &
     619             :                fpond = fpond - (da0 * trcrn(nt_apnd,1) &   ! LCOV_EXCL_LINE
     620           0 :                                     * trcrn(nt_hpnd,1))
     621             :          endif
     622             : 
     623             :       endif ! remap_flag
     624             : 
     625             :       !-----------------------------------------------------------------
     626             :       ! Update fractional ice area in each grid cell.
     627             :       !-----------------------------------------------------------------
     628             : 
     629     6816473 :       call aggregate_area (ncat, aicen, aice, aice0)
     630     6816473 :       if (icepack_warnings_aborted(subname)) return
     631             : 
     632             :       !-----------------------------------------------------------------
     633             :       ! Check volume and energy conservation.
     634             :       !-----------------------------------------------------------------
     635             : 
     636     6816473 :       if (conserv_check) then
     637             : 
     638           0 :       do n = 1, ncat
     639             : 
     640           0 :          eicen(n) = c0
     641           0 :          esnon(n) = c0
     642           0 :          vbrin(n) = c0
     643           0 :          sicen(n) = c0
     644             : 
     645           0 :          do k = 1, nilyr
     646           0 :             eicen(n) = eicen(n) + trcrn(nt_qice+k-1,n) &
     647           0 :                      * vicen(n)/real(nilyr,kind=dbl_kind)
     648             :          enddo
     649           0 :          do k = 1, nslyr
     650           0 :             esnon(n) = esnon(n) + trcrn(nt_qsno+k-1,n) &
     651           0 :                      * vsnon(n)/real(nslyr,kind=dbl_kind)
     652             :          enddo
     653             : 
     654           0 :          if (tr_brine) then
     655           0 :             vbrin(n) = vbrin(n) + trcrn(nt_fbri,n) &
     656           0 :                      * vicen(n)
     657             :          endif
     658             : 
     659           0 :          do k = 1, nilyr
     660           0 :             sicen(n) = sicen(n) + trcrn(nt_sice+k-1,n) &
     661           0 :                      * vicen(n)/real(nilyr,kind=dbl_kind)
     662             :          enddo
     663             : 
     664             :       enddo ! n
     665             : 
     666           0 :       call column_sum (ncat, vicen, vice_final)
     667           0 :       if (icepack_warnings_aborted(subname)) return
     668           0 :       call column_sum (ncat, vsnon, vsno_final)
     669           0 :       if (icepack_warnings_aborted(subname)) return
     670           0 :       call column_sum (ncat, eicen, eice_final)
     671           0 :       if (icepack_warnings_aborted(subname)) return
     672           0 :       call column_sum (ncat, esnon, esno_final)
     673           0 :       if (icepack_warnings_aborted(subname)) return
     674           0 :       call column_sum (ncat, sicen, sice_final)
     675           0 :       if (icepack_warnings_aborted(subname)) return
     676           0 :       call column_sum (ncat, vbrin, vbri_final)
     677           0 :       if (icepack_warnings_aborted(subname)) return
     678             : 
     679           0 :       fieldid = subname//':vice'
     680             :       call column_conservation_check (fieldid,               &
     681             :                                       vice_init, vice_final, &   ! LCOV_EXCL_LINE
     682           0 :                                       puny)
     683           0 :       if (icepack_warnings_aborted(subname)) return
     684           0 :       fieldid = subname//':vsno'
     685             :       call column_conservation_check (fieldid,               &
     686             :                                       vsno_init, vsno_final, &   ! LCOV_EXCL_LINE
     687           0 :                                       puny)
     688           0 :       if (icepack_warnings_aborted(subname)) return
     689           0 :       fieldid = subname//':eice'
     690             :       call column_conservation_check (fieldid,               &
     691             :                                       eice_init, eice_final, &   ! LCOV_EXCL_LINE
     692           0 :                                       puny*Lfresh*rhoi)
     693           0 :       if (icepack_warnings_aborted(subname)) return
     694           0 :       fieldid = subname//':esno'
     695             :       call column_conservation_check (fieldid,               &
     696             :                                       esno_init, esno_final, &   ! LCOV_EXCL_LINE
     697           0 :                                       puny*Lfresh*rhos)
     698           0 :       if (icepack_warnings_aborted(subname)) return
     699           0 :       fieldid = subname//':sicen'
     700             :       call column_conservation_check (fieldid,               &
     701             :                                       sice_init, sice_final, &   ! LCOV_EXCL_LINE
     702           0 :                                       puny)
     703           0 :       if (icepack_warnings_aborted(subname)) return
     704           0 :       fieldid = subname//':vbrin'
     705             :       call column_conservation_check (fieldid,               &
     706             :                                       vbri_init, vbri_final, &   ! LCOV_EXCL_LINE
     707           0 :                                       puny*c10)
     708           0 :       if (icepack_warnings_aborted(subname)) return
     709             : 
     710             :       endif                     ! conservation check
     711             : 
     712             :       end subroutine linear_itd
     713             : 
     714             : !=======================================================================
     715             : !
     716             : ! Fit g(h) with a line, satisfying area and volume constraints.
     717             : ! To reduce roundoff errors caused by large values of g0 and g1,
     718             : ! we actually compute g(eta), where eta = h - hL, and hL is the
     719             : ! left boundary.
     720             : !
     721             : ! authors: William H. Lipscomb, LANL
     722             : !          Elizabeth C. Hunke, LANL
     723             : 
     724    40898838 :       subroutine fit_line (aicen,    hice,            &
     725             :                            hbL,      hbR,             &   ! LCOV_EXCL_LINE
     726             :                            g0,       g1,              &   ! LCOV_EXCL_LINE
     727             :                            hL,       hR)
     728             : 
     729             :       real (kind=dbl_kind), intent(in) :: &
     730             :          aicen           ! concentration of ice
     731             : 
     732             :       real (kind=dbl_kind), intent(in) :: &
     733             :          hbL, hbR    , & ! left and right category boundaries   ! LCOV_EXCL_LINE
     734             :          hice            ! ice thickness
     735             : 
     736             :       real (kind=dbl_kind), intent(out):: &
     737             :          g0, g1      , & ! coefficients in linear equation for g(eta)   ! LCOV_EXCL_LINE
     738             :          hL          , & ! min value of range over which g(h) > 0   ! LCOV_EXCL_LINE
     739             :          hR              ! max value of range over which g(h) > 0
     740             : 
     741             :       ! local variables
     742             : 
     743             :       real  (kind=dbl_kind) :: &
     744             :          h13         , & ! hbL + 1/3 * (hbR - hbL)   ! LCOV_EXCL_LINE
     745             :          h23         , & ! hbL + 2/3 * (hbR - hbL)   ! LCOV_EXCL_LINE
     746             :          dhr         , & ! 1 / (hR - hL)   ! LCOV_EXCL_LINE
     747     3782838 :          wk1, wk2        ! temporary variables
     748             : 
     749             :       character(len=*),parameter :: subname='(fit_line)'
     750             : 
     751             :       !-----------------------------------------------------------------
     752             :       ! Compute g0, g1, hL, and hR for each category to be remapped.
     753             :       !-----------------------------------------------------------------
     754             : 
     755    40898838 :          if (aicen > puny .and. hbR - hbL > puny) then
     756             : 
     757             :          ! Initialize hL and hR
     758             : 
     759    40631245 :             hL = hbL
     760    40631245 :             hR = hbR
     761             : 
     762             :          ! Change hL or hR if hicen(n) falls outside central third of range
     763             : 
     764    40631245 :             h13 = p333 * (c2*hL + hR)
     765    40631245 :             h23 = p333 * (hL + c2*hR)
     766    40631245 :             if (hice < h13) then
     767    13296687 :                hR = c3*hice - c2*hL
     768    27334558 :             elseif (hice > h23) then
     769     3254542 :                hL = c3*hice - c2*hR
     770             :             endif
     771             : 
     772             :          ! Compute coefficients of g(eta) = g0 + g1*eta
     773             : 
     774    40631245 :             dhr = c1 / (hR - hL)
     775    40631245 :             wk1 = c6 * aicen * dhr
     776    40631245 :             wk2 = (hice - hL) * dhr
     777    40631245 :             g0 = wk1 * (p666 - wk2)
     778    40631245 :             g1 = c2*dhr * wk1 * (wk2 - p5)
     779             : 
     780             :          else
     781             : 
     782      267593 :             g0 = c0
     783      267593 :             g1 = c0
     784      267593 :             hL = c0
     785      267593 :             hR = c0
     786             : 
     787             :          endif                  ! aicen > puny
     788             : 
     789    40898838 :       end subroutine fit_line
     790             : 
     791             : !=======================================================================
     792             : !
     793             : ! Given some added new ice to the base of the existing ice, recalculate
     794             : ! vertical tracer so that new grid cells are all the same size.
     795             : !
     796             : ! author: A. K. Turner, LANL
     797             : !
     798    56620542 :       subroutine update_vertical_tracers(nilyr, trc, h1, h2, trc0)
     799             : 
     800             :       integer (kind=int_kind), intent(in) :: &
     801             :          nilyr ! number of ice layers
     802             : 
     803             :       real (kind=dbl_kind), dimension(:), intent(inout) :: &
     804             :            trc ! vertical tracer
     805             : 
     806             :       real (kind=dbl_kind), intent(in) :: &
     807             :          h1, & ! old thickness   ! LCOV_EXCL_LINE
     808             :          h2, & ! new thickness   ! LCOV_EXCL_LINE
     809             :          trc0  ! tracer value of added ice on ice bottom
     810             : 
     811             :       ! local variables
     812             : 
     813   122385300 :       real(kind=dbl_kind), dimension(nilyr) :: trc2 ! updated tracer temporary
     814             : 
     815             :       ! vertical indices for old and new grid
     816             :       integer :: k1, k2
     817             : 
     818             :       real (kind=dbl_kind) :: &
     819             :          z1a, z1b, & ! upper, lower boundary of old cell/added new ice at bottom   ! LCOV_EXCL_LINE
     820             :          z2a, z2b, & ! upper, lower boundary of new cell   ! LCOV_EXCL_LINE
     821             :          overlap , & ! overlap between old and new cell   ! LCOV_EXCL_LINE
     822     1524036 :          rnilyr
     823             : 
     824             :       character(len=*),parameter :: subname='(update_vertical_tracers)'
     825             : 
     826    56620542 :         rnilyr = real(nilyr,dbl_kind)
     827             : 
     828             :         ! loop over new grid cells
     829   452964336 :         do k2 = 1, nilyr
     830             : 
     831             :            ! initialize new tracer
     832   396343794 :            trc2(k2) = c0
     833             : 
     834             :            ! calculate upper and lower boundary of new cell
     835   396343794 :            z2a = ((k2 - 1) * h2) / rnilyr
     836   396343794 :            z2b = (k2       * h2) / rnilyr
     837             : 
     838             :            ! loop over old grid cells
     839  3170750352 :            do k1 = 1, nilyr
     840             : 
     841             :               ! calculate upper and lower boundary of old cell
     842  2774406558 :               z1a = ((k1 - 1) * h1) / rnilyr
     843  2774406558 :               z1b = (k1       * h1) / rnilyr
     844             : 
     845             :               ! calculate overlap between old and new cell
     846  2774406558 :               overlap = max(min(z1b, z2b) - max(z1a, z2a), c0)
     847             : 
     848             :               ! aggregate old grid cell contribution to new cell
     849  3170750352 :               trc2(k2) = trc2(k2) + overlap * trc(k1)
     850             : 
     851             :            enddo ! k1
     852             : 
     853             :            ! calculate upper and lower boundary of added new ice at bottom
     854   396343794 :            z1a = h1
     855   396343794 :            z1b = h2
     856             : 
     857             :            ! calculate overlap between added ice and new cell
     858   396343794 :            overlap = max(min(z1b, z2b) - max(z1a, z2a), c0)
     859             :            ! aggregate added ice contribution to new cell
     860   396343794 :            trc2(k2) = trc2(k2) + overlap * trc0
     861             :            ! renormalize new grid cell
     862   452964336 :            trc2(k2) = (rnilyr * trc2(k2)) / h2
     863             : 
     864             :         enddo ! k2
     865             : 
     866             :         ! update vertical tracer array with the adjusted tracer
     867   452964336 :         trc = trc2
     868             : 
     869    56620542 :       end subroutine update_vertical_tracers
     870             : 
     871             : !=======================================================================
     872             : !
     873             : ! Given the fraction of ice melting laterally in each grid cell
     874             : !  (computed in subroutine frzmlt_bottom_lateral), melt ice.
     875             : !
     876             : ! author: C. M. Bitz, UW
     877             : ! 2003:   Modified by William H. Lipscomb and Elizabeth C. Hunke, LANL
     878             : ! 2016    Lettie Roach, NIWA/VUW, added floe size dependence
     879             : !
     880    10719744 :       subroutine lateral_melt (dt,         ncat,       &
     881             :                                nilyr,      nslyr,      &   ! LCOV_EXCL_LINE
     882             :                                n_aero,     &   ! LCOV_EXCL_LINE
     883             :                                fpond,      &   ! LCOV_EXCL_LINE
     884             :                                fresh,      fsalt,      &   ! LCOV_EXCL_LINE
     885             :                                fhocn,      faero_ocn,  &   ! LCOV_EXCL_LINE
     886             :                                fiso_ocn,               &   ! LCOV_EXCL_LINE
     887             :                                rside,      meltl,      &   ! LCOV_EXCL_LINE
     888             :                                fside,      wlat,       &   ! LCOV_EXCL_LINE
     889             :                                aicen,      vicen,      &   ! LCOV_EXCL_LINE
     890             :                                vsnon,      trcrn,      &   ! LCOV_EXCL_LINE
     891             :                                flux_bio,               &   ! LCOV_EXCL_LINE
     892             :                                nbtrcr,     nblyr,      &   ! LCOV_EXCL_LINE
     893             :                                nfsd,       d_afsd_latm,&   ! LCOV_EXCL_LINE
     894    10719744 :                                floe_rad_c, floe_binwidth)
     895             : 
     896             :       real (kind=dbl_kind), intent(in) :: &
     897             :          dt        ! time step (s)
     898             : 
     899             :       integer (kind=int_kind), intent(in) :: &
     900             :          ncat    , & ! number of thickness categories   ! LCOV_EXCL_LINE
     901             :          nilyr   , & ! number of ice layers   ! LCOV_EXCL_LINE
     902             :          nblyr   , & ! number of bio layers   ! LCOV_EXCL_LINE
     903             :          nslyr   , & ! number of snow layers   ! LCOV_EXCL_LINE
     904             :          n_aero  , & ! number of aerosol tracers   ! LCOV_EXCL_LINE
     905             :          nbtrcr      ! number of bio tracers
     906             : 
     907             :       integer (kind=int_kind), intent(in), optional :: &
     908             :          nfsd        ! number of floe size categories
     909             : 
     910             :       real (kind=dbl_kind), dimension (:), intent(inout) :: &
     911             :          aicen   , & ! concentration of ice   ! LCOV_EXCL_LINE
     912             :          vicen   , & ! volume per unit area of ice          (m)   ! LCOV_EXCL_LINE
     913             :          vsnon       ! volume per unit area of snow         (m)
     914             : 
     915             :       real (kind=dbl_kind), dimension (:,:), intent(inout) :: &
     916             :          trcrn       ! tracer array
     917             : 
     918             :       real (kind=dbl_kind), intent(in) :: &
     919             :          rside       ! fraction of ice that melts laterally
     920             : 
     921             :       real (kind=dbl_kind), intent(in), optional :: &
     922             :          wlat        ! lateral melt rate (m/s)
     923             : 
     924             :       real (kind=dbl_kind), intent(inout) :: &
     925             :          fside       ! lateral heat flux (W/m^2)
     926             : 
     927             :       real (kind=dbl_kind), intent(inout) :: &
     928             :          fpond     , & ! fresh water flux to ponds (kg/m^2/s)   ! LCOV_EXCL_LINE
     929             :          fresh     , & ! fresh water flux to ocean (kg/m^2/s)   ! LCOV_EXCL_LINE
     930             :          fsalt     , & ! salt flux to ocean (kg/m^2/s)   ! LCOV_EXCL_LINE
     931             :          fhocn     , & ! net heat flux to ocean (W/m^2)   ! LCOV_EXCL_LINE
     932             :          meltl         ! lateral ice melt         (m/step-->cm/day)
     933             : 
     934             :       real (kind=dbl_kind), dimension(nbtrcr), intent(inout) :: &
     935             :          flux_bio  ! biology tracer flux from layer bgc (mmol/m^2/s)
     936             : 
     937             :       real (kind=dbl_kind), dimension(:), intent(inout) :: &
     938             :          faero_ocn     ! aerosol flux to ocean (kg/m^2/s)
     939             : 
     940             :       real (kind=dbl_kind), dimension(:), intent(inout), optional :: &
     941             :          fiso_ocn     ! isotope flux to ocean (kg/m^2/s)
     942             : 
     943             :       real (kind=dbl_kind), dimension (:), intent(in), optional :: &
     944             :          floe_rad_c     , & ! fsd size bin centre in m (radius)   ! LCOV_EXCL_LINE
     945             :          floe_binwidth      ! fsd size bin width in m (radius)
     946             : 
     947             :       real (kind=dbl_kind), dimension (:), intent(out), optional :: &
     948             :          d_afsd_latm        ! change in fsd due to lateral melt (m)
     949             : 
     950             :       ! local variables
     951             : 
     952             :       integer (kind=int_kind) :: &
     953             :          n           , & ! thickness category index   ! LCOV_EXCL_LINE
     954             :          k           , & ! layer index   ! LCOV_EXCL_LINE
     955             :          nsubt           ! sub timesteps for FSD tendency
     956             : 
     957             :       real (kind=dbl_kind) :: &
     958             :          dfhocn  , & ! change in fhocn   ! LCOV_EXCL_LINE
     959             :          dfpond  , & ! change in fpond   ! LCOV_EXCL_LINE
     960             :          dfresh  , & ! change in fresh   ! LCOV_EXCL_LINE
     961             :          dfsalt  , & ! change in fsalt   ! LCOV_EXCL_LINE
     962             :          dvssl   , & ! snow surface layer volume   ! LCOV_EXCL_LINE
     963             :          dvint   , & ! snow interior layer   ! LCOV_EXCL_LINE
     964     5764320 :          bin1_arealoss, tmp !
     965             : 
     966             :       logical (kind=log_kind) :: &
     967             :          flag        ! .true. if there could be lateral melting
     968             : 
     969             :       real (kind=dbl_kind), dimension (ncat) :: &
     970             :          aicen_init, & ! initial area fraction   ! LCOV_EXCL_LINE
     971             :          vicen_init, & ! volume per unit area of ice (m)   ! LCOV_EXCL_LINE
     972             :          G_radialn , & ! rate of lateral melt (m/s)   ! LCOV_EXCL_LINE
     973             :          delta_an  , & ! change in the ITD   ! LCOV_EXCL_LINE
     974    32968128 :          rsiden        ! delta_an/aicen
     975             : 
     976             :       real (kind=dbl_kind), dimension (:,:), allocatable :: &
     977             :          afsdn     , & ! floe size distribution tracer   ! LCOV_EXCL_LINE
     978    10719744 :          afsdn_init    ! initial value
     979             : 
     980             :       real (kind=dbl_kind), dimension (:), allocatable :: &
     981             :          df_flx    , & ! finite difference for FSD   ! LCOV_EXCL_LINE
     982             :          afsd_tmp  , & !   ! LCOV_EXCL_LINE
     983             :          d_afsd_tmp, & !   ! LCOV_EXCL_LINE
     984    10719744 :          f_flx         !
     985             : 
     986             :       real (kind=dbl_kind) :: &
     987             :          sicen,        &   ! LCOV_EXCL_LINE
     988             :          etot,         & ! column energy per itd cat, for FSD code   ! LCOV_EXCL_LINE
     989             :          elapsed_t,    & ! FSD subcycling   ! LCOV_EXCL_LINE
     990     2882160 :          subdt           ! FSD timestep (s)
     991             : 
     992             :       character(len=*), parameter :: subname='(lateral_melt)'
     993             : 
     994    10719744 :       flag = .false.
     995    10719744 :       dfhocn   = c0
     996    10719744 :       dfpond   = c0
     997    10719744 :       dfresh   = c0
     998    10719744 :       dfsalt   = c0
     999    10719744 :       dvssl    = c0
    1000    10719744 :       dvint    = c0
    1001    10719744 :       bin1_arealoss  = c0
    1002    10719744 :       tmp  = c0
    1003    64318464 :       vicen_init = c0
    1004    64318464 :       G_radialn  = c0
    1005    64318464 :       delta_an   = c0
    1006    64318464 :       rsiden     = c0
    1007             : 
    1008    10719744 :       if (tr_fsd) then
    1009           0 :          call icepack_cleanup_fsd (ncat, nfsd, trcrn(nt_fsd:nt_fsd+nfsd-1,:))
    1010           0 :          if (icepack_warnings_aborted(subname)) return
    1011             : 
    1012           0 :          allocate(afsdn(nfsd,ncat))
    1013           0 :          allocate(afsdn_init(nfsd,ncat))
    1014           0 :          allocate(df_flx(nfsd))
    1015           0 :          allocate(afsd_tmp(nfsd))
    1016           0 :          allocate(d_afsd_tmp(nfsd))
    1017           0 :          allocate(f_flx(nfsd+1))
    1018             : 
    1019           0 :          aicen_init  = aicen
    1020           0 :          afsdn       = trcrn(nt_fsd:nt_fsd+nfsd-1,:)
    1021           0 :          afsdn_init  = afsdn ! for diagnostics
    1022           0 :          df_flx      = c0
    1023           0 :          d_afsd_latm = c0
    1024           0 :          f_flx       = c0
    1025             :       end if
    1026             : 
    1027    10719744 :       if (tr_fsd .and. wlat > puny) then
    1028           0 :          flag = .true.
    1029             : 
    1030             :          ! for FSD rside and fside not yet computed correctly, redo here
    1031           0 :          fside = c0
    1032           0 :          do n = 1, ncat
    1033             : 
    1034           0 :             G_radialn(n) = -wlat ! negative
    1035             : 
    1036           0 :             if (any(afsdn(:,n) < c0)) then
    1037           0 :                write(warnstr,*) subname, 'lateral_melt B afsd < 0 ',n
    1038           0 :                call icepack_warnings_add(warnstr)
    1039             :             endif
    1040             : 
    1041           0 :             bin1_arealoss = -trcrn(nt_fsd+1-1,n) * aicen(n) * dt &
    1042           0 :                              * G_radialn(n) / floe_binwidth(1)
    1043             : 
    1044           0 :             delta_an(n) = c0
    1045           0 :             do k = 1, nfsd
    1046           0 :                delta_an(n) = delta_an(n) + ((c2/floe_rad_c(k))*aicen(n) &
    1047           0 :                     * trcrn(nt_fsd+k-1,n)*G_radialn(n)*dt) ! delta_an < 0
    1048             :             end do
    1049             : 
    1050             :             ! add negative area loss from fsd
    1051           0 :             delta_an(n) = delta_an(n) - bin1_arealoss
    1052             : 
    1053           0 :             if (delta_an(n) > c0) then
    1054           0 :                write(warnstr,*) subname, 'ERROR delta_an > 0 ',delta_an(n)
    1055           0 :                call icepack_warnings_add(warnstr)
    1056             :             endif
    1057             : 
    1058             :             ! following original code, not necessary for fsd
    1059           0 :             if (aicen(n) > c0) rsiden(n) = MIN(-delta_an(n)/aicen(n),c1)
    1060             : 
    1061           0 :             if (rsiden(n) < c0) then
    1062           0 :                write(warnstr,*) subname, 'ERROR rsiden < 0 ',rsiden(n)
    1063           0 :                call icepack_warnings_add(warnstr)
    1064             :             endif
    1065             : 
    1066             :             ! melting energy/unit area in each column, etot < 0
    1067           0 :             etot = c0
    1068           0 :             do k = 1, nslyr
    1069           0 :                etot = etot + trcrn(nt_qsno+k-1,n) * vsnon(n)/real(nslyr,kind=dbl_kind)
    1070             :             enddo
    1071             : 
    1072           0 :             do k = 1, nilyr
    1073           0 :                etot = etot + trcrn(nt_qice+k-1,n) * vicen(n)/real(nilyr,kind=dbl_kind)
    1074             :             enddo                  ! nilyr
    1075             : 
    1076             :             ! lateral heat flux, fside < 0
    1077           0 :             fside = fside + rsiden(n)*etot/dt
    1078             : 
    1079             :          enddo ! ncat
    1080             : 
    1081    10719744 :       else if (rside > c0) then ! original, non-fsd implementation
    1082             : 
    1083      656404 :          flag = .true.
    1084     3938424 :          rsiden(:) = rside ! initialize
    1085             : 
    1086             :       endif
    1087             : 
    1088    10719744 :       if (flag) then ! grid cells with lateral melting.
    1089             : 
    1090     3938424 :          do n = 1, ncat
    1091             : 
    1092             :       !-----------------------------------------------------------------
    1093             :       ! Melt the ice and increment fluxes.
    1094             :       !-----------------------------------------------------------------
    1095             : 
    1096             :             ! fluxes to coupler
    1097             :             ! dfresh > 0, dfsalt > 0, dfpond > 0
    1098             : 
    1099     3282020 :             dfresh = (rhoi*vicen(n) + rhos*vsnon(n))      * rsiden(n) / dt
    1100     3282020 :             if (saltflux_option == 'prognostic') then
    1101           0 :                sicen = c0
    1102           0 :                do k=1,nilyr
    1103           0 :                   sicen = sicen + trcrn(nt_sice+k-1,n) / real(nilyr,kind=dbl_kind)
    1104             :                enddo
    1105           0 :                dfsalt = rhoi*vicen(n)*sicen*p001 * rsiden(n) / dt
    1106             :             else
    1107     3282020 :                dfsalt = rhoi*vicen(n)*ice_ref_salinity*p001 * rsiden(n) / dt
    1108             :             endif
    1109     3282020 :             fresh  = fresh + dfresh
    1110     3282020 :             fsalt  = fsalt + dfsalt
    1111             : 
    1112     3282020 :             if (tr_pond_topo) then
    1113           0 :                dfpond = aicen(n)*trcrn(nt_apnd,n)*trcrn(nt_hpnd,n)*rsiden(n)
    1114           0 :                fpond  = fpond - dfpond
    1115             :             endif
    1116             : 
    1117             :             ! history diagnostics
    1118     3282020 :             meltl = meltl + vicen(n)*rsiden(n)
    1119             : 
    1120             :             ! state variables
    1121     3282020 :             vicen_init(n) = vicen(n)
    1122     3282020 :             aicen(n) = aicen(n) * (c1 - rsiden(n))
    1123     3282020 :             vicen(n) = vicen(n) * (c1 - rsiden(n))
    1124     3282020 :             vsnon(n) = vsnon(n) * (c1 - rsiden(n))
    1125             : 
    1126             :             ! floe size distribution
    1127     3282020 :             if (tr_fsd) then
    1128           0 :                if (rsiden(n) > puny) then
    1129           0 :                   if (aicen(n) > puny) then
    1130             : 
    1131             :                      ! adaptive subtimestep
    1132           0 :                      elapsed_t = c0
    1133           0 :                      afsd_tmp(:) = afsdn_init(:,n)
    1134           0 :                      d_afsd_tmp(:) = c0
    1135           0 :                      nsubt = 0
    1136             : 
    1137           0 :                      DO WHILE (elapsed_t.lt.dt)
    1138             : 
    1139           0 :                          nsubt = nsubt + 1
    1140           0 :                          if (nsubt.gt.100) then
    1141           0 :                              write(warnstr,*) subname, 'latm not converging'
    1142           0 :                              call icepack_warnings_add(warnstr)
    1143             :                          endif
    1144             : 
    1145             :                          ! finite differences
    1146           0 :                          df_flx(:) = c0
    1147           0 :                          f_flx (:) = c0
    1148           0 :                          do k = 2, nfsd
    1149           0 :                            f_flx(k) =  G_radialn(n) * afsd_tmp(k) / floe_binwidth(k)
    1150             :                          end do
    1151             : 
    1152           0 :                          do k = 1, nfsd
    1153           0 :                           df_flx(k)   = f_flx(k+1) - f_flx(k)
    1154             :                          end do
    1155             : 
    1156           0 :                          if (abs(sum(df_flx(:))) > puny) then
    1157           0 :                              write(warnstr,*) subname, 'sum(df_flx) /= 0'
    1158           0 :                              call icepack_warnings_add(warnstr)
    1159             :                          endif
    1160             : 
    1161             :                          ! this term ensures area conservation
    1162           0 :                          tmp = SUM(afsd_tmp(:)/floe_rad_c(:))
    1163             : 
    1164             :                          ! fsd tendency
    1165           0 :                          do k = 1, nfsd
    1166           0 :                            d_afsd_tmp(k) = -df_flx(k) + c2 * G_radialn(n) * afsd_tmp(k) &
    1167           0 :                                        * (c1/floe_rad_c(k) - tmp)
    1168             :                          end do
    1169             : 
    1170             :                          ! timestep required for this
    1171           0 :                          subdt = get_subdt_fsd(nfsd, afsd_tmp(:), d_afsd_tmp(:))
    1172           0 :                          subdt = MIN(subdt, dt)
    1173             : 
    1174             :                         ! update fsd and elapsed time
    1175           0 :                         afsd_tmp(:) = afsd_tmp(:) + subdt*d_afsd_tmp(:)
    1176           0 :                         elapsed_t = elapsed_t + subdt
    1177             : 
    1178             : 
    1179             :                       END DO
    1180             : 
    1181           0 :                      afsdn(:,n) = afsd_tmp(:)
    1182             : 
    1183             : 
    1184             :                   end if ! aicen
    1185             :                end if ! rside > 0, otherwise do nothing
    1186             : 
    1187             :             end if ! tr_fsd
    1188             : 
    1189             :             ! fluxes
    1190    26256160 :             do k = 1, nilyr
    1191             :                ! enthalpy tracers do not change (e/v constant)
    1192             :                ! heat flux to coupler for ice melt (dfhocn < 0)
    1193    26482610 :                dfhocn = trcrn(nt_qice+k-1,n)*rsiden(n) / dt &
    1194    36215445 :                       * vicen(n)/real(nilyr,kind=dbl_kind)
    1195    26256160 :                fhocn  = fhocn + dfhocn
    1196             :             enddo                  ! nilyr
    1197             : 
    1198     6564040 :             do k = 1, nslyr
    1199             :                ! heat flux to coupler for snow melt (dfhocn < 0)
    1200     3783230 :                dfhocn = trcrn(nt_qsno+k-1,n)*rsiden(n) / dt &
    1201     5173635 :                       * vsnon(n)/real(nslyr,kind=dbl_kind)
    1202     6564040 :                fhocn  = fhocn + dfhocn
    1203             :             enddo                  ! nslyr
    1204             : 
    1205     3282020 :             if (tr_aero) then
    1206           0 :                do k = 1, n_aero
    1207           0 :                   faero_ocn(k) = faero_ocn(k) + (vsnon(n) &
    1208             :                                *(trcrn(nt_aero  +4*(k-1),n)   &   ! LCOV_EXCL_LINE
    1209             :                                + trcrn(nt_aero+1+4*(k-1),n))  &   ! LCOV_EXCL_LINE
    1210             :                                               +  vicen(n) &   ! LCOV_EXCL_LINE
    1211             :                                *(trcrn(nt_aero+2+4*(k-1),n)   &   ! LCOV_EXCL_LINE
    1212             :                                + trcrn(nt_aero+3+4*(k-1),n))) &   ! LCOV_EXCL_LINE
    1213           0 :                                * rsiden(n) / dt
    1214             :                enddo ! k
    1215             :             endif    ! tr_aero
    1216             : 
    1217     3282020 :             if (tr_iso) then
    1218           0 :                do k = 1, n_iso
    1219           0 :                   fiso_ocn(k) = fiso_ocn(k) &
    1220             :                               + (vsnon(n)*trcrn(nt_isosno+k-1,n) &   ! LCOV_EXCL_LINE
    1221             :                               +  vicen(n)*trcrn(nt_isoice+k-1,n)) &   ! LCOV_EXCL_LINE
    1222           0 :                               * rside / dt
    1223             :                enddo ! k
    1224             :             endif    ! tr_iso
    1225             : 
    1226             :       !-----------------------------------------------------------------
    1227             :       ! Biogeochemistry
    1228             :       !-----------------------------------------------------------------
    1229             : 
    1230     3938424 :             if (z_tracers) then   ! snow tracers
    1231           0 :                dvssl = min(p5*vsnon(n)/real(nslyr,kind=dbl_kind), hs_ssl*aicen(n)) ! snow surface layer
    1232           0 :                dvint = vsnon(n) - dvssl                                            ! snow interior
    1233           0 :                do k = 1, nbtrcr
    1234           0 :                   flux_bio(k) = flux_bio(k) &
    1235             :                               + (trcrn(bio_index(k)+nblyr+1,n)*dvssl  &   ! LCOV_EXCL_LINE
    1236             :                               +  trcrn(bio_index(k)+nblyr+2,n)*dvint) &   ! LCOV_EXCL_LINE
    1237           0 :                               * rsiden(n) / dt
    1238             :                enddo
    1239             :             endif
    1240             : 
    1241             :          enddo       ! n
    1242             : 
    1243      656404 :          if (z_tracers) &
    1244             :             call lateral_melt_bgc(dt,                         &   ! LCOV_EXCL_LINE
    1245             :                                   ncat,        nblyr,         &   ! LCOV_EXCL_LINE
    1246             :                                   rside,       vicen_init,    &  !echmod: use rsiden   ! LCOV_EXCL_LINE
    1247             :                                   trcrn,                      &   ! LCOV_EXCL_LINE
    1248           0 :                                   flux_bio,    nbtrcr)
    1249      656404 :             if (icepack_warnings_aborted(subname)) return
    1250             : 
    1251             :       endif          ! flag
    1252             : 
    1253    10719744 :       if (tr_fsd) then
    1254             : 
    1255           0 :          trcrn(nt_fsd:nt_fsd+nfsd-1,:) =  afsdn
    1256             : 
    1257           0 :          call icepack_cleanup_fsd (ncat, nfsd, trcrn(nt_fsd:nt_fsd+nfsd-1,:) )
    1258           0 :          if (icepack_warnings_aborted(subname)) return
    1259             : 
    1260             :          ! diagnostics
    1261           0 :          do k = 1, nfsd
    1262           0 :             d_afsd_latm(k) = c0
    1263           0 :             do n = 1, ncat
    1264           0 :                d_afsd_latm(k) = d_afsd_latm(k) &
    1265           0 :                   + afsdn(k,n)*aicen(n) - afsdn_init(k,n)*aicen_init(n)
    1266             :             end do
    1267             :          end do
    1268             : 
    1269           0 :          deallocate(afsdn)
    1270           0 :          deallocate(afsdn_init)
    1271           0 :          deallocate(df_flx)
    1272           0 :          deallocate(afsd_tmp)
    1273           0 :          deallocate(d_afsd_tmp)
    1274           0 :          deallocate(f_flx)
    1275             : 
    1276             :       end if
    1277             : 
    1278    10719744 :       end subroutine lateral_melt
    1279             : 
    1280             : !=======================================================================
    1281             : !
    1282             : ! Given the volume of new ice grown in open water, compute its area
    1283             : ! and thickness and add it to the appropriate category or categories.
    1284             : !
    1285             : ! NOTE: Usually all the new ice is added to category 1.  An exception is
    1286             : !       made if there is no open water or if the new ice is too thick
    1287             : !       for category 1, in which case ice is distributed evenly over the
    1288             : !       entire cell.  Subroutine rebin should be called in case the ice
    1289             : !       thickness lies outside category bounds after new ice formation.
    1290             : !
    1291             : ! When ice must be added to categories above category 1, the mushy
    1292             : ! formulation (ktherm=2) adds it only to the bottom of the ice.  When
    1293             : ! added to only category 1, all formulations combine the new ice and
    1294             : ! existing ice tracers as bulk quantities.
    1295             : !
    1296             : ! authors: William H. Lipscomb, LANL
    1297             : !          Elizabeth C. Hunke, LANL
    1298             : !          Adrian Turner, LANL
    1299             : !          Lettie Roach, NIWA/VUW
    1300             : !
    1301    10719744 :       subroutine add_new_ice (ncat,      nilyr,      &
    1302             :                               nfsd,      nblyr,      &   ! LCOV_EXCL_LINE
    1303             :                               n_aero,    dt,         &   ! LCOV_EXCL_LINE
    1304             :                               ntrcr,     nltrcr,     &   ! LCOV_EXCL_LINE
    1305             :                               hin_max,   ktherm,     &   ! LCOV_EXCL_LINE
    1306             :                               aicen,     trcrn,      &   ! LCOV_EXCL_LINE
    1307             :                               vicen,     vsnon1,     &   ! LCOV_EXCL_LINE
    1308             :                               aice0,     aice,       &   ! LCOV_EXCL_LINE
    1309             :                               frzmlt,    frazil,     &   ! LCOV_EXCL_LINE
    1310             :                               frz_onset, yday,       &   ! LCOV_EXCL_LINE
    1311             :                               fresh,     fsalt,      &   ! LCOV_EXCL_LINE
    1312             :                               Tf,        sss,        &   ! LCOV_EXCL_LINE
    1313             :                               salinz,    phi_init,   &   ! LCOV_EXCL_LINE
    1314             :                               dSin0_frazil,          &   ! LCOV_EXCL_LINE
    1315             :                               bgrid,      cgrid,      igrid,    &   ! LCOV_EXCL_LINE
    1316             :                               nbtrcr,    flux_bio,   &   ! LCOV_EXCL_LINE
    1317             :                               ocean_bio,             &   ! LCOV_EXCL_LINE
    1318             :                               frazil_diag,           &   ! LCOV_EXCL_LINE
    1319             :                               fiso_ocn,              &   ! LCOV_EXCL_LINE
    1320             :                               HDO_ocn, H2_16O_ocn,   &   ! LCOV_EXCL_LINE
    1321             :                               H2_18O_ocn,            &   ! LCOV_EXCL_LINE
    1322             :                               wave_sig_ht,           &   ! LCOV_EXCL_LINE
    1323             :                               wave_spectrum,         &   ! LCOV_EXCL_LINE
    1324             :                               wavefreq,              &   ! LCOV_EXCL_LINE
    1325             :                               dwavefreq,             &   ! LCOV_EXCL_LINE
    1326             :                               d_afsd_latg,           &   ! LCOV_EXCL_LINE
    1327             :                               d_afsd_newi,           &   ! LCOV_EXCL_LINE
    1328    21439488 :                               floe_rad_c, floe_binwidth)
    1329             : 
    1330             :       use icepack_fsd, only: fsd_lateral_growth, fsd_add_new_ice
    1331             : 
    1332             :       integer (kind=int_kind), intent(in) :: &
    1333             :          ncat  , & ! number of thickness categories   ! LCOV_EXCL_LINE
    1334             :          nilyr , & ! number of ice layers   ! LCOV_EXCL_LINE
    1335             :          nblyr , & ! number of bio layers   ! LCOV_EXCL_LINE
    1336             :          ntrcr , & ! number of tracers   ! LCOV_EXCL_LINE
    1337             :          nltrcr, & ! number of zbgc tracers   ! LCOV_EXCL_LINE
    1338             :          n_aero, & ! number of aerosol tracers   ! LCOV_EXCL_LINE
    1339             :          ktherm    ! type of thermodynamics (-1 none, 1 BL99, 2 mushy)
    1340             : 
    1341             :       integer (kind=int_kind), intent(in), optional :: &
    1342             :          nfsd      ! number of floe size categories
    1343             : 
    1344             :       real (kind=dbl_kind), dimension(0:ncat), intent(in) :: &
    1345             :          hin_max      ! category boundaries (m)
    1346             : 
    1347             :       real (kind=dbl_kind), intent(in) :: &
    1348             :          dt    , & ! time step (s)   ! LCOV_EXCL_LINE
    1349             :          aice  , & ! total concentration of ice   ! LCOV_EXCL_LINE
    1350             :          frzmlt, & ! freezing/melting potential (W/m^2)   ! LCOV_EXCL_LINE
    1351             :          Tf    , & ! freezing temperature (C)   ! LCOV_EXCL_LINE
    1352             :          sss   , & ! sea surface salinity (ppt)   ! LCOV_EXCL_LINE
    1353             :          vsnon1    ! category 1 snow volume per ice area (m)
    1354             : 
    1355             :       real (kind=dbl_kind), dimension (:), intent(inout) :: &
    1356             :          aicen , & ! concentration of ice   ! LCOV_EXCL_LINE
    1357             :          vicen     ! volume per unit area of ice          (m)
    1358             : 
    1359             :       real (kind=dbl_kind), dimension (:,:), intent(inout) :: &
    1360             :          trcrn     ! ice tracers
    1361             :                    ! 1: surface temperature
    1362             : 
    1363             :       real (kind=dbl_kind), intent(inout) :: &
    1364             :          aice0     , & ! concentration of open water   ! LCOV_EXCL_LINE
    1365             :          frazil    , & ! frazil ice growth        (m/step-->cm/day)   ! LCOV_EXCL_LINE
    1366             :          frazil_diag,& ! frazil ice growth diagnostic (m/step-->cm/day)   ! LCOV_EXCL_LINE
    1367             :          fresh     , & ! fresh water flux to ocean (kg/m^2/s)   ! LCOV_EXCL_LINE
    1368             :          fsalt         ! salt flux to ocean (kg/m^2/s)
    1369             : 
    1370             :       real (kind=dbl_kind), intent(inout), optional :: &
    1371             :          frz_onset ! day of year that freezing begins (congel or frazil)
    1372             : 
    1373             :       real (kind=dbl_kind), intent(in), optional :: &
    1374             :          yday      ! day of year
    1375             : 
    1376             :       real (kind=dbl_kind), dimension(:), intent(in) :: &
    1377             :          salinz     ! initial salinity profile
    1378             : 
    1379             :       real (kind=dbl_kind), intent(in) :: &
    1380             :          phi_init     , & ! initial frazil liquid fraction   ! LCOV_EXCL_LINE
    1381             :          dSin0_frazil     ! initial frazil bulk salinity reduction from sss
    1382             : 
    1383             :       ! BGC
    1384             :       real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: &
    1385             :          bgrid              ! biology nondimensional vertical grid points
    1386             : 
    1387             :       real (kind=dbl_kind), dimension (nblyr+1), intent(in) :: &
    1388             :          igrid              ! biology vertical interface points
    1389             : 
    1390             :       real (kind=dbl_kind), dimension (nilyr+1), intent(in) :: &
    1391             :          cgrid              ! CICE vertical coordinate
    1392             : 
    1393             :       integer (kind=int_kind), intent(in) :: &
    1394             :          nbtrcr          ! number of biology tracers
    1395             : 
    1396             :       real (kind=dbl_kind), dimension (:), intent(inout) :: &
    1397             :          flux_bio   ! tracer flux to ocean from biology (mmol/m^2/s)
    1398             : 
    1399             :       real (kind=dbl_kind), dimension (:), intent(in) :: &
    1400             :          ocean_bio   ! ocean concentration of biological tracer
    1401             : 
    1402             :       ! water isotopes
    1403             : 
    1404             :       real (kind=dbl_kind), dimension(:), intent(inout), optional :: &
    1405             :          fiso_ocn       ! isotope flux to ocean  (kg/m^2/s)
    1406             : 
    1407             :       real (kind=dbl_kind), intent(in), optional :: &
    1408             :          HDO_ocn    , & ! ocean concentration of HDO (kg/kg)   ! LCOV_EXCL_LINE
    1409             :          H2_16O_ocn , & ! ocean concentration of H2_16O (kg/kg)   ! LCOV_EXCL_LINE
    1410             :          H2_18O_ocn     ! ocean concentration of H2_18O (kg/kg)
    1411             : 
    1412             :       ! floe size distribution
    1413             :       real (kind=dbl_kind), intent(in), optional :: &
    1414             :          wave_sig_ht    ! significant height of waves globally (m)
    1415             : 
    1416             :       real (kind=dbl_kind), dimension(:), intent(in), optional :: &
    1417             :          wave_spectrum  ! ocean surface wave spectrum, E(f) (m^2 s)
    1418             : 
    1419             :       real(kind=dbl_kind), dimension(:), intent(in), optional :: &
    1420             :          wavefreq,              & ! wave frequencies (s^-1)   ! LCOV_EXCL_LINE
    1421             :          dwavefreq                ! wave frequency bin widths (s^-1)
    1422             : 
    1423             :       real (kind=dbl_kind), dimension (:), intent(in), optional :: &
    1424             :          floe_rad_c     , & ! fsd size bin centre in m (radius)   ! LCOV_EXCL_LINE
    1425             :          floe_binwidth      ! fsd size bin width in m (radius)
    1426             : 
    1427             :       real (kind=dbl_kind), dimension(:), intent(out), optional :: &
    1428             :                             ! change in thickness distribution (area)
    1429             :          d_afsd_latg    , & ! due to fsd lateral growth
    1430             :          d_afsd_newi        ! new ice formation
    1431             : 
    1432             :       ! local variables
    1433             : 
    1434             :       integer (kind=int_kind) :: &
    1435             :          ncats        , & ! max categories to which new ice is added, initially   ! LCOV_EXCL_LINE
    1436             :          n            , & ! ice category index   ! LCOV_EXCL_LINE
    1437             :          k            , & ! ice layer index   ! LCOV_EXCL_LINE
    1438             :          it               ! aerosol tracer index
    1439             : 
    1440             :       real (kind=dbl_kind) :: &
    1441             :          ai0new       , & ! area of new ice added to cat 1   ! LCOV_EXCL_LINE
    1442             :          vi0new       , & ! volume of new ice added to cat 1   ! LCOV_EXCL_LINE
    1443             :          hsurp        , & ! thickness of new ice added to each cat   ! LCOV_EXCL_LINE
    1444             :          fnew         , & ! heat flx to open water for new ice (W/m^2)   ! LCOV_EXCL_LINE
    1445             :          hi0new       , & ! thickness of new ice   ! LCOV_EXCL_LINE
    1446             :          hi0max       , & ! max allowed thickness of new ice   ! LCOV_EXCL_LINE
    1447             :          vsurp        , & ! volume of new ice added to each cat   ! LCOV_EXCL_LINE
    1448             :          vtmp         , & ! total volume of new and old ice   ! LCOV_EXCL_LINE
    1449             :          area1        , & ! starting fractional area of existing ice   ! LCOV_EXCL_LINE
    1450             :          alvl         , & ! starting level ice area   ! LCOV_EXCL_LINE
    1451             :          dfresh       , & ! change in fresh   ! LCOV_EXCL_LINE
    1452             :          dfsalt       , & ! change in fsalt   ! LCOV_EXCL_LINE
    1453             :          vi0tmp       , & ! frzmlt part of frazil   ! LCOV_EXCL_LINE
    1454             :          Ti           , & ! frazil temperature   ! LCOV_EXCL_LINE
    1455             :          qi0new       , & ! frazil ice enthalpy   ! LCOV_EXCL_LINE
    1456             :          Si0new       , & ! frazil ice bulk salinity   ! LCOV_EXCL_LINE
    1457             :          vi0_init     , & ! volume of new ice   ! LCOV_EXCL_LINE
    1458             :          vice1        , & ! starting volume of existing ice   ! LCOV_EXCL_LINE
    1459             :          vice_init, vice_final, & ! ice volume summed over categories   ! LCOV_EXCL_LINE
    1460     2882160 :          eice_init, eice_final    ! ice energy summed over categories
    1461             : 
    1462     2882160 :       real (kind=dbl_kind) :: frazil_conc
    1463             : 
    1464             :       real (kind=dbl_kind), dimension (nilyr) :: &
    1465    38732448 :          Sprofile         ! salinity profile used for new ice additions
    1466             : 
    1467             :       character (len=char_len) :: &
    1468             :          fieldid           ! field identifier
    1469             : 
    1470             :       real (kind=dbl_kind), dimension (ncat) :: &
    1471             :          eicen, &     ! energy of melting for each ice layer (J/m^2)   ! LCOV_EXCL_LINE
    1472             :          aicen_init, &    ! fractional area of ice   ! LCOV_EXCL_LINE
    1473    32968128 :          vicen_init       ! volume per unit area of ice (m)
    1474             : 
    1475             :       ! floe size distribution
    1476             :       real (kind=dbl_kind), dimension (:,:), allocatable :: &
    1477    10719744 :          afsdn          ! floe size distribution tracer (originally areal_mfstd_init)
    1478             : 
    1479             : !      real (kind=dbl_kind), dimension (nfsd) :: &
    1480             : !         afsd      , & ! fsd tracer for each thickness category   ! LCOV_EXCL_LINE
    1481             : 
    1482             :       real (kind=dbl_kind), dimension(ncat) :: &  ! for now
    1483             :                             ! change in thickness distribution (area)
    1484    32968128 :          d_an_latg      , & ! due to fsd lateral growth
    1485    32968128 :          d_an_newi          ! new ice formation
    1486             : 
    1487             :       real (kind=dbl_kind), dimension (ncat) :: &
    1488             :          d_an_tot, & ! change in the ITD due to lateral growth and new ice   ! LCOV_EXCL_LINE
    1489    32968128 :          area2       ! area after lateral growth and before new ice formation
    1490             : 
    1491             :       real (kind=dbl_kind), dimension (ncat) :: &
    1492    32968128 :          vin0new          ! volume of new ice added to any thickness cat
    1493             : 
    1494             :       real (kind=dbl_kind) :: &
    1495             :          latsurf_area, & ! fractional area of ice on sides of floes   ! LCOV_EXCL_LINE
    1496             :          lead_area   , & ! fractional area of ice in lead region   ! LCOV_EXCL_LINE
    1497             :          G_radial    , & ! lateral melt rate (m/s)   ! LCOV_EXCL_LINE
    1498             :          tot_latg    , & ! total fsd lateral growth in open water   ! LCOV_EXCL_LINE
    1499     2882160 :          ai0mod          ! ai0new - tot_latg
    1500             : 
    1501             :       character(len=*),parameter :: subname='(add_new_ice)'
    1502             : 
    1503             :       !-----------------------------------------------------------------
    1504             :       ! initialize
    1505             :       !-----------------------------------------------------------------
    1506             : 
    1507    10719744 :       hsurp  = c0
    1508    10719744 :       hi0new = c0
    1509    10719744 :       ai0new = c0
    1510    64318464 :       d_an_latg(:) = c0
    1511    64318464 :       d_an_tot(:) = c0
    1512    64318464 :       d_an_newi(:) = c0
    1513    64318464 :       vin0new(:) = c0
    1514             : 
    1515    10719744 :       if (tr_fsd) then
    1516           0 :           d_afsd_latg(:) = c0    ! diagnostics
    1517           0 :           d_afsd_newi(:) = c0
    1518             :       end if
    1519             : 
    1520    64318464 :       area2(:) = aicen(:)
    1521    10719744 :       lead_area    = c0
    1522    10719744 :       latsurf_area = c0
    1523    10719744 :       G_radial     = c0
    1524    10719744 :       tot_latg     = c0
    1525    10719744 :       if (ncat > 1) then
    1526    10719744 :          hi0max = hin_max(1)*0.9_dbl_kind  ! not too close to boundary
    1527             :       else
    1528           0 :          hi0max = bignum                   ! big number
    1529             :       endif
    1530             : 
    1531    10719744 :       if (tr_fsd) then
    1532           0 :          allocate(afsdn(nfsd,ncat))
    1533           0 :          afsdn(:,:) = c0
    1534           0 :          call icepack_cleanup_fsd (ncat, nfsd, trcrn(nt_fsd:nt_fsd+nfsd-1,:))
    1535           0 :          if (icepack_warnings_aborted(subname)) return
    1536             :       endif
    1537             : 
    1538    64318464 :       do n = 1, ncat
    1539    53598720 :          aicen_init(n) = aicen(n)
    1540    53598720 :          vicen_init(n) = vicen(n)
    1541    53598720 :          eicen(n) = c0
    1542    64318464 :          if (tr_fsd) then
    1543           0 :             do k = 1, nfsd
    1544           0 :                afsdn(k,n) = trcrn(nt_fsd+k-1,n)
    1545             :             enddo
    1546             :          endif
    1547             :       enddo
    1548             : 
    1549    10719744 :       if (conserv_check) then
    1550             : 
    1551           0 :          do n = 1, ncat
    1552           0 :          do k = 1, nilyr
    1553           0 :             eicen(n) = eicen(n) + trcrn(nt_qice+k-1,n) &
    1554           0 :                      * vicen(n)/real(nilyr,kind=dbl_kind)
    1555             :          enddo
    1556             :          enddo
    1557           0 :          call column_sum (ncat, vicen, vice_init)
    1558           0 :          if (icepack_warnings_aborted(subname)) return
    1559           0 :          call column_sum (ncat, eicen, eice_init)
    1560           0 :          if (icepack_warnings_aborted(subname)) return
    1561             : 
    1562             :       endif ! conserv_check
    1563             : 
    1564             :       !-----------------------------------------------------------------
    1565             :       ! Compute average enthalpy of new ice.
    1566             :       ! Sprofile is the salinity profile used when adding new ice to
    1567             :       ! all categories, for ktherm/=2, and to category 1 for all ktherm.
    1568             :       !
    1569             :       ! NOTE:  POP assumes new ice is fresh!
    1570             :       !-----------------------------------------------------------------
    1571             : 
    1572    10719744 :       if (ktherm == 2) then  ! mushy
    1573    10719744 :          if (sss > c2 * dSin0_frazil) then
    1574    10719744 :             Si0new = sss - dSin0_frazil
    1575             :          else
    1576           0 :             Si0new = sss**2 / (c4*dSin0_frazil)
    1577             :          endif
    1578    85757952 :          do k = 1, nilyr
    1579    85757952 :             Sprofile(k) = Si0new
    1580             :          enddo
    1581    10719744 :          Ti = min(liquidus_temperature_mush(Si0new/phi_init), Tliquidus_max)
    1582    10719744 :          qi0new = icepack_enthalpy_mush(Ti, Si0new)
    1583             :       else
    1584           0 :          do k = 1, nilyr
    1585           0 :             Sprofile(k) = salinz(k)
    1586             :          enddo
    1587           0 :          qi0new = -rhoi*Lfresh
    1588             :       endif    ! ktherm
    1589             : 
    1590             :       !-----------------------------------------------------------------
    1591             :       ! Compute the volume, area, and thickness of new ice.
    1592             :       !-----------------------------------------------------------------
    1593             : 
    1594    10719744 :       fnew = max (frzmlt, c0)    ! fnew > 0 iff frzmlt > 0
    1595    10719744 :       vi0new = -fnew*dt / qi0new ! note sign convention, qi < 0
    1596    10719744 :       vi0_init = vi0new          ! for bgc
    1597             : 
    1598             :       ! increment ice volume and energy
    1599    10719744 :       if (conserv_check) then
    1600           0 :          vice_init = vice_init + vi0new
    1601           0 :          eice_init = eice_init + vi0new*qi0new
    1602             :       endif
    1603             : 
    1604             :       ! history diagnostics
    1605    10719744 :       frazil = vi0new
    1606             : 
    1607    10719744 :       if (present(frz_onset) .and. present(yday)) then
    1608    10719744 :          if (frazil > puny .and. frz_onset < puny) frz_onset = yday
    1609             :       endif
    1610             : 
    1611             :       !-----------------------------------------------------------------
    1612             :       ! Update fresh water and salt fluxes.
    1613             :       !
    1614             :       ! NOTE: POP assumes fresh water and salt flux due to frzmlt > 0
    1615             :       !       is NOT included in fluxes fresh and fsalt.
    1616             :       !-----------------------------------------------------------------
    1617             : 
    1618    10719744 :       dfresh = c0
    1619    10719744 :       dfsalt = c0
    1620    10719744 :       if (cpl_frazil == 'external') then
    1621             :          ! do nothing here, calculations are in the coupler or elsewhere
    1622             :       else
    1623    10719744 :          if (update_ocn_f) then
    1624           0 :             dfresh = -rhoi*vi0new/dt
    1625    10719744 :          elseif (cpl_frazil == 'fresh_ice_correction' .and. ktherm == 2) then
    1626             :             ! correct frazil fluxes for mushy
    1627    10719744 :             vi0tmp = fnew*dt / (rhoi*Lfresh) ! ocn/cpl assumes frazil volume is pure, fresh ice
    1628    10719744 :             dfresh = -rhoi*(vi0new - vi0tmp)/dt
    1629    10719744 :             frazil_diag = frazil - vi0tmp
    1630             : !        else 
    1631             : !           do nothing - other correction options could be implemented in the future             
    1632             :          endif
    1633             : 
    1634    10719744 :          if (saltflux_option == 'prognostic') then
    1635           0 :             dfsalt = Si0new*p001*dfresh
    1636             :          else
    1637    10719744 :             dfsalt = ice_ref_salinity*p001*dfresh
    1638             :          endif
    1639    10719744 :          fresh  = fresh + dfresh
    1640    10719744 :          fsalt  = fsalt + dfsalt      
    1641             :       endif
    1642             : 
    1643             :       !-----------------------------------------------------------------
    1644             :       ! Decide how to distribute the new ice.
    1645             :       !-----------------------------------------------------------------
    1646             : 
    1647    10719744 :       if (vi0new > c0) then
    1648             : 
    1649     6144281 :         if (tr_fsd) then ! lateral growth of existing ice
    1650             :             ! calculate change in conc due to lateral growth
    1651             :             ! update vi0new, without change to afsdn or aicen
    1652             :             call fsd_lateral_growth (ncat,       nfsd,         &
    1653             :                                   dt,         aice,         &   ! LCOV_EXCL_LINE
    1654             :                                   aicen,      vicen,        &   ! LCOV_EXCL_LINE
    1655             :                                   vi0new,     frazil,       &   ! LCOV_EXCL_LINE
    1656             :                                   floe_rad_c, afsdn,        &   ! LCOV_EXCL_LINE
    1657             :                                   lead_area,  latsurf_area, &   ! LCOV_EXCL_LINE
    1658             :                                   G_radial,   d_an_latg,    &   ! LCOV_EXCL_LINE
    1659           0 :                                   tot_latg)
    1660           0 :             if (icepack_warnings_aborted(subname)) return
    1661             :          endif
    1662             : 
    1663     6144281 :          ai0mod = aice0
    1664             :          ! separate frazil ice growth from lateral ice growth
    1665     6144281 :          if (tr_fsd) ai0mod = aice0-tot_latg
    1666             : 
    1667             :          ! new ice area and thickness
    1668             :          ! hin_max(0) < new ice thickness < hin_max(1)
    1669     6144281 :          if (ai0mod > puny) then
    1670     6095421 :             hi0new = max(vi0new/ai0mod, hfrazilmin)
    1671     6095421 :             if (hi0new > hi0max .and. ai0mod+puny < c1) then
    1672             :                ! distribute excess volume over all categories (below)
    1673     5613724 :                hi0new = hi0max
    1674     5613724 :                ai0new = ai0mod
    1675     5613724 :                vsurp  = vi0new - ai0new*hi0new
    1676     5613724 :                hsurp  = vsurp / aice
    1677     5613724 :                vi0new = ai0new*hi0new
    1678             :             else
    1679             :                ! put ice in a single category, with hsurp = 0
    1680      481697 :                ai0new = vi0new/hi0new
    1681             :             endif
    1682             :          else                ! aice0 < puny
    1683       48860 :             hsurp = vi0new/aice ! new thickness in each cat
    1684       48860 :             vi0new = c0
    1685             :          endif               ! aice0 > puny
    1686             : 
    1687             :          ! volume added to each category from lateral growth
    1688    36865686 :          do n = 1, ncat
    1689    36865686 :             if (aicen(n) > c0) vin0new(n) = d_an_latg(n) * vicen(n)/aicen(n)
    1690             :          end do
    1691             : 
    1692             :          ! combine areal change from new ice growth and lateral growth
    1693     6144281 :          d_an_newi(1)     = ai0new
    1694    30721405 :          d_an_tot(2:ncat) = d_an_latg(2:ncat)
    1695     6144281 :          d_an_tot(1)      = d_an_latg(1) + d_an_newi(1)
    1696     6144281 :          if (tr_fsd) then
    1697           0 :             vin0new(1)    = vin0new(1) + ai0new*hi0new ! not BFB
    1698             :          else
    1699     6144281 :             vin0new(1)    = vi0new
    1700             :          endif
    1701             : 
    1702             :       endif                  ! vi0new > puny
    1703             : 
    1704             :       !-----------------------------------------------------------------
    1705             :       ! Distribute excess ice volume among ice categories by increasing
    1706             :       ! ice thickness, leaving ice area unchanged.
    1707             :       !
    1708             :       ! NOTE: If new ice contains globally conserved tracers
    1709             :       !       (e.g., isotopes from seawater), code must be added here.
    1710             :       !
    1711             :       ! The mushy formulation (ktherm=2) puts the new ice only at the
    1712             :       ! bottom of existing ice and adjusts the layers accordingly.
    1713             :       ! The other formulations distribute the new ice throughout the
    1714             :       ! existing ice column.
    1715             :       !-----------------------------------------------------------------
    1716             : 
    1717    10719744 :       if (hsurp > c0) then   ! add ice to all categories
    1718             : 
    1719    33975504 :          do n = 1, ncat
    1720             : 
    1721    28312920 :             vsurp = hsurp * aicen(n)
    1722             : 
    1723             :             ! update ice age due to freezing (new ice age = dt)
    1724    28312920 :             vtmp = vicen(n) + vsurp
    1725    28312920 :             if (tr_iage .and. vtmp > puny) &
    1726             :                 trcrn(nt_iage,n) = &   ! LCOV_EXCL_LINE
    1727    28310271 :                (trcrn(nt_iage,n)*vicen(n) + dt*vsurp) / vtmp
    1728             : 
    1729    28312920 :             if (tr_lvl .and. vicen(n) > puny) then
    1730      762018 :                 trcrn(nt_vlvl,n) = &
    1731             :                (trcrn(nt_vlvl,n)*vicen(n) + &   ! LCOV_EXCL_LINE
    1732    28310271 :                 trcrn(nt_alvl,n)*vsurp) / vtmp
    1733             :             endif
    1734             : 
    1735    28312920 :             if (tr_aero .and. vtmp > puny) then
    1736           0 :                do it = 1, n_aero
    1737           0 :                   trcrn(nt_aero+2+4*(it-1),n) = &
    1738           0 :                   trcrn(nt_aero+2+4*(it-1),n)*vicen(n) / vtmp
    1739           0 :                   trcrn(nt_aero+3+4*(it-1),n) = &
    1740           0 :                   trcrn(nt_aero+3+4*(it-1),n)*vicen(n) / vtmp
    1741             :                enddo
    1742             :             endif
    1743             : 
    1744    28312920 :            if (tr_iso .and. vtmp > puny) then
    1745           0 :              do it=1,n_iso
    1746           0 :                frazil_conc = c0
    1747           0 :                if (it==1) &
    1748           0 :                   frazil_conc = isoice_alpha(c0,'HDO'   ,isotope_frac_method)*HDO_ocn
    1749           0 :                if (it==2) &
    1750           0 :                   frazil_conc = isoice_alpha(c0,'H2_16O',isotope_frac_method)*H2_16O_ocn
    1751           0 :                if (it==3) &
    1752           0 :                   frazil_conc = isoice_alpha(c0,'H2_18O',isotope_frac_method)*H2_18O_ocn
    1753             : 
    1754             :                ! dilution and uptake in the ice
    1755           0 :                trcrn(nt_isoice+it-1,n)  &
    1756             :                    = (trcrn(nt_isoice+it-1,n)*vicen(n) &   ! LCOV_EXCL_LINE
    1757             :                    + frazil_conc*rhoi*vsurp) &   ! LCOV_EXCL_LINE
    1758           0 :                    / vtmp
    1759             : 
    1760           0 :                fiso_ocn(it) = fiso_ocn(it) &
    1761           0 :                             - frazil_conc*rhoi*vsurp/dt
    1762             :              enddo
    1763             :             endif
    1764             : 
    1765             :             ! update category volumes
    1766    28312920 :             vicen(n) = vtmp
    1767             : 
    1768    33975504 :             if (ktherm == 2) then
    1769    28312920 :                vsurp = hsurp * aicen(n)  ! note - save this above?
    1770    28312920 :                vtmp = vicen(n) - vsurp   ! vicen is the new volume
    1771    28312920 :                if (vicen(n) > c0) then
    1772             :                   call update_vertical_tracers(nilyr, &
    1773             :                               trcrn(nt_qice:nt_qice+nilyr-1,n), &   ! LCOV_EXCL_LINE
    1774    28310271 :                               vtmp, vicen(n), qi0new)
    1775    28310271 :                   if (icepack_warnings_aborted(subname)) return
    1776             :                   call update_vertical_tracers(nilyr, &
    1777             :                               trcrn(nt_sice:nt_sice+nilyr-1,n), &   ! LCOV_EXCL_LINE
    1778    28310271 :                               vtmp, vicen(n), Si0new)
    1779    28310271 :                   if (icepack_warnings_aborted(subname)) return
    1780             :                endif
    1781             :             else
    1782           0 :                do k = 1, nilyr
    1783             :                   ! factor of nilyr cancels out
    1784           0 :                   vsurp = hsurp * aicen(n)  ! note - save this above?
    1785           0 :                   vtmp = vicen(n) - vsurp      ! vicen is the new volume
    1786           0 :                   if (vicen(n) > c0) then
    1787             :                      ! enthalpy
    1788           0 :                      trcrn(nt_qice+k-1,n) = &
    1789           0 :                     (trcrn(nt_qice+k-1,n)*vtmp + qi0new*vsurp) / vicen(n)
    1790             :                      ! salinity
    1791           0 :                      trcrn(nt_sice+k-1,n) = &
    1792           0 :                     (trcrn(nt_sice+k-1,n)*vtmp + Sprofile(k)*vsurp) / vicen(n)
    1793             :                   endif
    1794             :                enddo               ! k
    1795             :             endif                  ! ktherm
    1796             : 
    1797             :          enddo                     ! n
    1798             : 
    1799             :       endif ! hsurp > 0
    1800             : 
    1801             :       !-----------------------------------------------------------------
    1802             :       ! Combine new ice grown in open water with ice categories.
    1803             :       ! Using the floe size distribution, ice is added laterally to all
    1804             :       ! categories; otherwise it is added to category 1.
    1805             :       ! Assume that vsnon and esnon are unchanged.
    1806             :       ! The mushy formulation assumes salt from frazil is added uniformly
    1807             :       ! to category 1, while the others use a salinity profile.
    1808             :       !-----------------------------------------------------------------
    1809             : 
    1810    10719744 :       ncats = 1                  ! add new ice to category 1 by default
    1811    10719744 :       if (tr_fsd) ncats = ncat   ! add new ice laterally to all categories
    1812             : 
    1813             : 
    1814    21439488 :       do n = 1, ncats
    1815             : 
    1816    21439488 :       if (d_an_tot(n) > c0 .and. vin0new(n) > c0) then  ! add ice to category n
    1817             : 
    1818     6095421 :          area1    = aicen(n)   ! save
    1819     6095421 :          vice1    = vicen(n)   ! save
    1820     6095421 :          area2(n) = aicen_init(n) + d_an_latg(n) ! save area after latg, before newi
    1821     6095421 :          aicen(n) = aicen(n) + d_an_tot(n) ! after lateral growth and new ice growth
    1822             : 
    1823     6095421 :          aice0    = aice0    - d_an_tot(n)
    1824     6095421 :          vicen(n) = vicen(n) + vin0new(n)
    1825             : 
    1826     6095421 :          trcrn(nt_Tsfc,n) = (trcrn(nt_Tsfc,n)*area1 + Tf*d_an_tot(n))/aicen(n)
    1827     6095421 :          trcrn(nt_Tsfc,n) = min (trcrn(nt_Tsfc,n), c0)
    1828             : 
    1829     6095421 :          if (tr_FY) then
    1830     6095421 :             trcrn(nt_FY,n) = (trcrn(nt_FY,n)*area1 + d_an_tot(n))/aicen(n)
    1831     6095421 :             trcrn(nt_FY,n) = min(trcrn(nt_FY,n), c1)
    1832             :          endif
    1833             : 
    1834     6095421 :          if (tr_fsd) then ! evolve the floe size distribution
    1835             :             ! both new frazil ice and lateral growth
    1836             :             call fsd_add_new_ice (ncat, n,    nfsd,          &
    1837             :                                   dt,         ai0new,        &   ! LCOV_EXCL_LINE
    1838             :                                   d_an_latg,  d_an_newi,     &   ! LCOV_EXCL_LINE
    1839             :                                   floe_rad_c, floe_binwidth, &   ! LCOV_EXCL_LINE
    1840             :                                   G_radial,   area2,         &   ! LCOV_EXCL_LINE
    1841             :                                   wave_sig_ht,               &   ! LCOV_EXCL_LINE
    1842             :                                   wave_spectrum,             &   ! LCOV_EXCL_LINE
    1843             :                                   wavefreq,                  &   ! LCOV_EXCL_LINE
    1844             :                                   dwavefreq,                 &   ! LCOV_EXCL_LINE
    1845             :                                   d_afsd_latg,               &   ! LCOV_EXCL_LINE
    1846             :                                   d_afsd_newi,               &   ! LCOV_EXCL_LINE
    1847             :                                   afsdn,      aicen_init,    &   ! LCOV_EXCL_LINE
    1848           0 :                                   aicen,      trcrn)
    1849           0 :             if (icepack_warnings_aborted(subname)) return
    1850             :          endif
    1851             : 
    1852     6095421 :          if (vicen(n) > puny) then
    1853     6095421 :             if (tr_iage) &
    1854     6095421 :                trcrn(nt_iage,n) = (trcrn(nt_iage,n)*vice1 + dt*vin0new(n))/vicen(n)
    1855             : 
    1856     6095421 :             if (tr_aero) then
    1857           0 :                do it = 1, n_aero
    1858           0 :                   trcrn(nt_aero+2+4*(it-1),n) = &
    1859           0 :                   trcrn(nt_aero+2+4*(it-1),n)*vice1/vicen(n)
    1860           0 :                   trcrn(nt_aero+3+4*(it-1),n) = &
    1861           0 :                   trcrn(nt_aero+3+4*(it-1),n)*vice1/vicen(n)
    1862             :                enddo
    1863             :             endif
    1864             : 
    1865     6095421 :            if (tr_iso) then
    1866           0 :               do it=1,n_iso
    1867           0 :                 frazil_conc = c0
    1868           0 :                 if (it==1) &
    1869           0 :                    frazil_conc = isoice_alpha(c0,'HDO'   ,isotope_frac_method)*HDO_ocn
    1870           0 :                 if (it==2) &
    1871           0 :                    frazil_conc = isoice_alpha(c0,'H2_16O',isotope_frac_method)*H2_16O_ocn
    1872           0 :                 if (it==3) &
    1873           0 :                    frazil_conc = isoice_alpha(c0,'H2_18O',isotope_frac_method)*H2_18O_ocn
    1874             : 
    1875           0 :                 trcrn(nt_isoice+it-1,1) &
    1876             :                   = (trcrn(nt_isoice+it-1,1)*vice1) &   ! LCOV_EXCL_LINE
    1877           0 :                   + frazil_conc*rhoi*vi0new/vicen(1)
    1878             : 
    1879           0 :                 fiso_ocn(it) = fiso_ocn(it) &
    1880           0 :                              - frazil_conc*rhoi*vi0new/dt
    1881             :               enddo
    1882             :            endif
    1883             : 
    1884     6095421 :             if (tr_lvl) then
    1885     6095421 :                 alvl = trcrn(nt_alvl,n)
    1886      242214 :                 trcrn(nt_alvl,n) = &
    1887     6095421 :                (trcrn(nt_alvl,n)*area1 + d_an_tot(n))/aicen(n)
    1888      242214 :                 trcrn(nt_vlvl,n) = &
    1889     6095421 :                (trcrn(nt_vlvl,n)*vice1 + vin0new(n))/vicen(n)
    1890             :             endif
    1891             : 
    1892     6095421 :             if (tr_pond_topo) then
    1893           0 :                trcrn(nt_apnd,n) = &
    1894           0 :                trcrn(nt_apnd,n)*area1/aicen(n)
    1895     6095421 :             elseif (tr_pond_lvl) then
    1896     6095421 :                if (trcrn(nt_alvl,n) > puny) then
    1897      242214 :                   trcrn(nt_apnd,n) = &
    1898     6095421 :                   trcrn(nt_apnd,n) * alvl*area1 / (trcrn(nt_alvl,n)*aicen(n))
    1899             :                endif
    1900             :             endif
    1901             :          endif
    1902             : 
    1903    48763368 :          do k = 1, nilyr
    1904    48763368 :             if (vicen(n) > c0) then
    1905             :                ! factor of nilyr cancels out
    1906             :                ! enthalpy
    1907     3390996 :                trcrn(nt_qice+k-1,n) = &
    1908    44363445 :               (trcrn(nt_qice+k-1,n)*vice1 + qi0new*vin0new(n))/vicen(n)
    1909             :                ! salinity
    1910     3390996 :                trcrn(nt_sice+k-1,n) = &
    1911    44363445 :               (trcrn(nt_sice+k-1,n)*vice1 + Sprofile(k)*vin0new(n))/vicen(n)
    1912             :             endif
    1913             :          enddo
    1914             : 
    1915             :       endif ! vi0new > 0
    1916             : 
    1917             :       enddo ! ncats
    1918             : 
    1919    10719744 :       if (conserv_check) then
    1920             : 
    1921           0 :          do n = 1, ncat
    1922           0 :             eicen(n) = c0
    1923           0 :             do k = 1, nilyr
    1924           0 :                eicen(n) = eicen(n) + trcrn(nt_qice+k-1,n) &
    1925           0 :                         * vicen(n)/real(nilyr,kind=dbl_kind)
    1926             :             enddo
    1927             :          enddo
    1928           0 :          call column_sum (ncat, vicen, vice_final)
    1929           0 :          if (icepack_warnings_aborted(subname)) return
    1930           0 :          call column_sum (ncat, eicen, eice_final)
    1931           0 :          if (icepack_warnings_aborted(subname)) return
    1932             : 
    1933           0 :          fieldid = subname//':vice'
    1934             :          call column_conservation_check (fieldid,               &
    1935             :                                          vice_init, vice_final, &   ! LCOV_EXCL_LINE
    1936           0 :                                          puny)
    1937           0 :          if (icepack_warnings_aborted(subname)) return
    1938           0 :          fieldid = subname//':eice'
    1939             :          call column_conservation_check (fieldid,               &
    1940             :                                          eice_init, eice_final, &   ! LCOV_EXCL_LINE
    1941           0 :                                          puny*Lfresh*rhoi)
    1942           0 :          if (icepack_warnings_aborted(subname)) return
    1943             : 
    1944             :       endif ! conserv_check
    1945             : 
    1946             :       !-----------------------------------------------------------------
    1947             :       ! Biogeochemistry
    1948             :       !-----------------------------------------------------------------
    1949    10719744 :       if (tr_brine .or. nbtrcr > 0) then
    1950             :          call add_new_ice_bgc(dt,         nblyr,                &
    1951             :                               ncat, nilyr, nltrcr, &   ! LCOV_EXCL_LINE
    1952             :                               bgrid,      cgrid,      igrid,    &   ! LCOV_EXCL_LINE
    1953             :                               aicen_init, vicen_init, vi0_init, &   ! LCOV_EXCL_LINE
    1954             :                               aicen,      vicen,      vsnon1,   &   ! LCOV_EXCL_LINE
    1955             :                               vi0new,     ntrcr,      trcrn,    &   ! LCOV_EXCL_LINE
    1956             :                               nbtrcr,     sss,        ocean_bio,&   ! LCOV_EXCL_LINE
    1957           0 :                               flux_bio,   hsurp)
    1958           0 :          if (icepack_warnings_aborted(subname)) return
    1959             :       endif
    1960             : 
    1961    10719744 :       if (tr_fsd) then
    1962           0 :          deallocate(afsdn)
    1963             :       endif
    1964             : 
    1965    10719744 :       end subroutine add_new_ice
    1966             : 
    1967             : !=======================================================================
    1968             : !autodocument_start icepack_step_therm2
    1969             : ! Driver for thermodynamic changes not needed for coupling:
    1970             : ! transport in thickness space, lateral growth and melting.
    1971             : !
    1972             : ! authors: William H. Lipscomb, LANL
    1973             : !          Elizabeth C. Hunke, LANL
    1974             : 
    1975    10719744 :       subroutine icepack_step_therm2 (dt, ncat, nltrcr,           &
    1976             :                                      nilyr,        nslyr,         &   ! LCOV_EXCL_LINE
    1977             :                                      hin_max,      nblyr,         &   ! LCOV_EXCL_LINE
    1978             :                                      aicen,                       &   ! LCOV_EXCL_LINE
    1979             :                                      vicen,        vsnon,         &   ! LCOV_EXCL_LINE
    1980             :                                      aicen_init,   vicen_init,    &   ! LCOV_EXCL_LINE
    1981             :                                      trcrn,                       &   ! LCOV_EXCL_LINE
    1982             :                                      aice0,        aice,          &   ! LCOV_EXCL_LINE
    1983             :                                      trcr_depend,                 &   ! LCOV_EXCL_LINE
    1984             :                                      trcr_base,    n_trcr_strata, &   ! LCOV_EXCL_LINE
    1985             :                                      nt_strata,                   &   ! LCOV_EXCL_LINE
    1986             :                                      Tf,           sss,           &   ! LCOV_EXCL_LINE
    1987             :                                      salinz,                      &   ! LCOV_EXCL_LINE
    1988             :                                      rside,        meltl,         &   ! LCOV_EXCL_LINE
    1989             :                                      fside,        wlat,          &   ! LCOV_EXCL_LINE
    1990             :                                      frzmlt,       frazil,        &   ! LCOV_EXCL_LINE
    1991             :                                      frain,        fpond,         &   ! LCOV_EXCL_LINE
    1992             :                                      fresh,        fsalt,         &   ! LCOV_EXCL_LINE
    1993             :                                      fhocn,        update_ocn_f,  &   ! LCOV_EXCL_LINE
    1994             :                                      bgrid,        cgrid,         &   ! LCOV_EXCL_LINE
    1995             :                                      igrid,        faero_ocn,     &   ! LCOV_EXCL_LINE
    1996             :                                      first_ice,    fzsal,         &   ! LCOV_EXCL_LINE
    1997             :                                      flux_bio,     ocean_bio,     &   ! LCOV_EXCL_LINE
    1998             :                                      frazil_diag,                 &   ! LCOV_EXCL_LINE
    1999             :                                      frz_onset,    yday,          &   ! LCOV_EXCL_LINE
    2000             :                                      fiso_ocn,     HDO_ocn,       &   ! LCOV_EXCL_LINE
    2001             :                                      H2_16O_ocn,   H2_18O_ocn,    &   ! LCOV_EXCL_LINE
    2002             :                                      nfsd,         wave_sig_ht,   &   ! LCOV_EXCL_LINE
    2003             :                                      wave_spectrum,               &   ! LCOV_EXCL_LINE
    2004             :                                      wavefreq,                    &   ! LCOV_EXCL_LINE
    2005             :                                      dwavefreq,                   &   ! LCOV_EXCL_LINE
    2006             :                                      d_afsd_latg,  d_afsd_newi,   &   ! LCOV_EXCL_LINE
    2007             :                                      d_afsd_latm,  d_afsd_weld,   &   ! LCOV_EXCL_LINE
    2008    10719744 :                                      floe_rad_c,   floe_binwidth)
    2009             : 
    2010             :       use icepack_parameters, only: icepack_init_parameters
    2011             : 
    2012             :       integer (kind=int_kind), intent(in) :: &
    2013             :          ncat     , & ! number of thickness categories   ! LCOV_EXCL_LINE
    2014             :          nltrcr   , & ! number of zbgc tracers   ! LCOV_EXCL_LINE
    2015             :          nblyr    , & ! number of bio layers   ! LCOV_EXCL_LINE
    2016             :          nilyr    , & ! number of ice layers   ! LCOV_EXCL_LINE
    2017             :          nslyr        ! number of snow layers
    2018             : 
    2019             :       integer (kind=int_kind), intent(in), optional :: &
    2020             :          nfsd         ! number of floe size categories
    2021             : 
    2022             :       logical (kind=log_kind), intent(in), optional :: &
    2023             :          update_ocn_f ! if true, update fresh water and salt fluxes
    2024             : 
    2025             :       real (kind=dbl_kind), dimension(0:ncat), intent(in) :: &
    2026             :          hin_max      ! category boundaries (m)
    2027             : 
    2028             :       real (kind=dbl_kind), intent(in) :: &
    2029             :          dt       , & ! time step   ! LCOV_EXCL_LINE
    2030             :          Tf       , & ! freezing temperature (C)   ! LCOV_EXCL_LINE
    2031             :          sss      , & ! sea surface salinity (ppt)   ! LCOV_EXCL_LINE
    2032             :          rside    , & ! fraction of ice that melts laterally   ! LCOV_EXCL_LINE
    2033             :          frzmlt       ! freezing/melting potential (W/m^2)
    2034             : 
    2035             :       integer (kind=int_kind), dimension (:), intent(in) :: &
    2036             :          trcr_depend, & ! = 0 for aicen tracers, 1 for vicen, 2 for vsnon   ! LCOV_EXCL_LINE
    2037             :          n_trcr_strata  ! number of underlying tracer layers
    2038             : 
    2039             :       real (kind=dbl_kind), dimension (:,:), intent(in) :: &
    2040             :          trcr_base    ! = 0 or 1 depending on tracer dependency
    2041             :                       ! argument 2:  (1) aice, (2) vice, (3) vsno
    2042             : 
    2043             :       integer (kind=int_kind), dimension (:,:), intent(in) :: &
    2044             :          nt_strata    ! indices of underlying tracer layers
    2045             : 
    2046             :       real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: &
    2047             :          bgrid        ! biology nondimensional vertical grid points
    2048             : 
    2049             :       real (kind=dbl_kind), dimension (nblyr+1), intent(in) :: &
    2050             :          igrid        ! biology vertical interface points
    2051             : 
    2052             :       real (kind=dbl_kind), dimension (nilyr+1), intent(in) :: &
    2053             :          cgrid        ! CICE vertical coordinate
    2054             : 
    2055             :       real (kind=dbl_kind), dimension(:), intent(in) :: &
    2056             :          salinz   , & ! initial salinity profile   ! LCOV_EXCL_LINE
    2057             :          ocean_bio    ! ocean concentration of biological tracer
    2058             : 
    2059             :       real (kind=dbl_kind), intent(inout) :: &
    2060             :          aice     , & ! sea ice concentration   ! LCOV_EXCL_LINE
    2061             :          aice0    , & ! concentration of open water   ! LCOV_EXCL_LINE
    2062             :          fside    , & ! lateral heat flux (W/m^2)   ! LCOV_EXCL_LINE
    2063             :          frain    , & ! rainfall rate (kg/m^2 s)   ! LCOV_EXCL_LINE
    2064             :          fpond    , & ! fresh water flux to ponds (kg/m^2/s)   ! LCOV_EXCL_LINE
    2065             :          fresh    , & ! fresh water flux to ocean (kg/m^2/s)   ! LCOV_EXCL_LINE
    2066             :          fsalt    , & ! salt flux to ocean (kg/m^2/s)   ! LCOV_EXCL_LINE
    2067             :          fhocn    , & ! net heat flux to ocean (W/m^2)   ! LCOV_EXCL_LINE
    2068             :          meltl    , & ! lateral ice melt         (m/step-->cm/day)   ! LCOV_EXCL_LINE
    2069             :          frazil   , & ! frazil ice growth        (m/step-->cm/day)   ! LCOV_EXCL_LINE
    2070             :          frazil_diag  ! frazil ice growth diagnostic (m/step-->cm/day)
    2071             : 
    2072             :       real (kind=dbl_kind), intent(inout), optional :: &
    2073             :          fzsal        ! salt flux to ocean from zsalinity (kg/m^2/s) (deprecated)
    2074             : 
    2075             :       real (kind=dbl_kind), intent(in), optional :: &
    2076             :          wlat         ! lateral melt rate (m/s)
    2077             : 
    2078             :       real (kind=dbl_kind), dimension(:), intent(inout) :: &
    2079             :          aicen_init,& ! initial concentration of ice   ! LCOV_EXCL_LINE
    2080             :          vicen_init,& ! initial volume per unit area of ice          (m)   ! LCOV_EXCL_LINE
    2081             :          aicen    , & ! concentration of ice   ! LCOV_EXCL_LINE
    2082             :          vicen    , & ! volume per unit area of ice          (m)   ! LCOV_EXCL_LINE
    2083             :          vsnon    , & ! volume per unit area of snow         (m)   ! LCOV_EXCL_LINE
    2084             :          faero_ocn, & ! aerosol flux to ocean  (kg/m^2/s)   ! LCOV_EXCL_LINE
    2085             :          flux_bio     ! all bio fluxes to ocean
    2086             : 
    2087             :       real (kind=dbl_kind), dimension(:,:), intent(inout) :: &
    2088             :          trcrn        ! tracers
    2089             : 
    2090             :       logical (kind=log_kind), dimension(:), intent(inout) :: &
    2091             :          first_ice    ! true until ice forms
    2092             : 
    2093             :       real (kind=dbl_kind), intent(inout), optional :: &
    2094             :          frz_onset    ! day of year that freezing begins (congel or frazil)
    2095             : 
    2096             :       real (kind=dbl_kind), intent(in), optional :: &
    2097             :          yday         ! day of year
    2098             : 
    2099             :       ! water isotopes
    2100             :       real (kind=dbl_kind), dimension(:), intent(inout), optional :: &
    2101             :          fiso_ocn     ! isotope flux to ocean  (kg/m^2/s)
    2102             : 
    2103             :       real (kind=dbl_kind), intent(in), optional :: &
    2104             :          HDO_ocn    , & ! ocean concentration of HDO (kg/kg)   ! LCOV_EXCL_LINE
    2105             :          H2_16O_ocn , & ! ocean concentration of H2_16O (kg/kg)   ! LCOV_EXCL_LINE
    2106             :          H2_18O_ocn     ! ocean concentration of H2_18O (kg/kg)
    2107             : 
    2108             :       real (kind=dbl_kind), intent(in), optional :: &
    2109             :          wave_sig_ht    ! significant height of waves in ice (m)
    2110             : 
    2111             :       real (kind=dbl_kind), dimension(:), intent(in), optional  :: &
    2112             :          wave_spectrum  ! ocean surface wave spectrum E(f) (m^2 s)
    2113             : 
    2114             :       real(kind=dbl_kind), dimension(:), intent(in), optional :: &
    2115             :          wavefreq, &    ! wave frequencies (s^-1)   ! LCOV_EXCL_LINE
    2116             :          dwavefreq      ! wave frequency bin widths (s^-1)
    2117             : 
    2118             :       real (kind=dbl_kind), dimension(:), intent(out), optional :: &
    2119             :                         ! change in floe size distribution (area)
    2120             :          d_afsd_latg, & ! due to fsd lateral growth
    2121             :          d_afsd_newi, & ! new ice formation   ! LCOV_EXCL_LINE
    2122             :          d_afsd_latm, & ! lateral melt   ! LCOV_EXCL_LINE
    2123             :          d_afsd_weld    ! welding
    2124             : 
    2125             :       real (kind=dbl_kind), dimension (:), intent(in), optional :: &
    2126             :          floe_rad_c, &  ! fsd size bin centre in m (radius)   ! LCOV_EXCL_LINE
    2127             :          floe_binwidth  ! fsd size bin width in m (radius)
    2128             : 
    2129             : !autodocument_end
    2130             : 
    2131             :       ! local variables
    2132             : 
    2133             :       logical (kind=log_kind), save :: &
    2134             :          first_call = .true.   ! first call flag
    2135             : 
    2136             :       character(len=*),parameter :: subname='(icepack_step_therm2)'
    2137             : 
    2138             :       !-----------------------------------------------------------------
    2139             :       ! Check optional arguments and set local values
    2140             :       !-----------------------------------------------------------------
    2141             : 
    2142    10719744 :        if (present(update_ocn_f)) then
    2143           0 :           call icepack_init_parameters(update_ocn_f_in=update_ocn_f)
    2144             :        endif
    2145    10719744 :        if (icepack_chkoptargflag(first_call)) then
    2146          37 :           if (tr_iso) then
    2147           0 :              if (.not.(present(fiso_ocn)   .and. &
    2148             :                        present(HDO_ocn)    .and. &   ! LCOV_EXCL_LINE
    2149             :                        present(H2_16O_ocn) .and. &   ! LCOV_EXCL_LINE
    2150             :                        present(H2_18O_ocn))) then
    2151           0 :                 call icepack_warnings_add(subname//' error in iso arguments, tr_iso=T')
    2152           0 :                 call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    2153           0 :                 return
    2154             :              endif
    2155             :           endif
    2156          37 :           if (tr_fsd) then
    2157           0 :              if (.not.(present(nfsd)          .and. &
    2158             :                        present(wlat)          .and. &   ! LCOV_EXCL_LINE
    2159             :                        present(wave_sig_ht)   .and. &   ! LCOV_EXCL_LINE
    2160             :                        present(wave_spectrum) .and. &   ! LCOV_EXCL_LINE
    2161             :                        present(wavefreq)      .and. &   ! LCOV_EXCL_LINE
    2162             :                        present(dwavefreq)     .and. &   ! LCOV_EXCL_LINE
    2163             :                        present(d_afsd_latg)   .and. &   ! LCOV_EXCL_LINE
    2164             :                        present(d_afsd_newi)   .and. &   ! LCOV_EXCL_LINE
    2165             :                        present(d_afsd_latm)   .and. &   ! LCOV_EXCL_LINE
    2166             :                        present(d_afsd_weld)   .and. &   ! LCOV_EXCL_LINE
    2167             :                        present(floe_rad_c)    .and. &   ! LCOV_EXCL_LINE
    2168             :                        present(floe_binwidth))) then
    2169           0 :                 call icepack_warnings_add(subname//' error in FSD arguments, tr_fsd=T')
    2170           0 :                 call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
    2171           0 :                 return
    2172             :              endif
    2173             :           endif
    2174             :       endif
    2175             : 
    2176             :       !-----------------------------------------------------------------
    2177             :       ! Let rain drain through to the ocean.
    2178             :       !-----------------------------------------------------------------
    2179             : 
    2180    10719744 :       fresh  = fresh + frain * aice
    2181             : 
    2182             :       !-----------------------------------------------------------------
    2183             :       ! Given thermodynamic growth rates, transport ice between
    2184             :       ! thickness categories.
    2185             :       !-----------------------------------------------------------------
    2186             : 
    2187             : !      call ice_timer_start(timer_catconv)    ! category conversions
    2188             : 
    2189             :       !-----------------------------------------------------------------
    2190             :       ! Compute fractional ice area in each grid cell.
    2191             :       !-----------------------------------------------------------------
    2192             : 
    2193    10719744 :       call aggregate_area (ncat, aicen, aice, aice0)
    2194    10719744 :       if (icepack_warnings_aborted(subname)) return
    2195             : 
    2196    10719744 :       if (kitd == 1) then
    2197             : 
    2198             :       !-----------------------------------------------------------------
    2199             :       ! Identify grid cells with ice.
    2200             :       !-----------------------------------------------------------------
    2201             : 
    2202    10719744 :          if (aice > puny) then
    2203             : 
    2204             :             call linear_itd (ncat,     hin_max,        &
    2205             :                              nilyr,    nslyr,          &   ! LCOV_EXCL_LINE
    2206             :                              ntrcr,    trcr_depend,    &   ! LCOV_EXCL_LINE
    2207             :                              trcr_base,        &   ! LCOV_EXCL_LINE
    2208             :                              n_trcr_strata,   &   ! LCOV_EXCL_LINE
    2209             :                              nt_strata,                &   ! LCOV_EXCL_LINE
    2210             :                              aicen_init,            &   ! LCOV_EXCL_LINE
    2211             :                              vicen_init,            &   ! LCOV_EXCL_LINE
    2212             :                              aicen,                 &   ! LCOV_EXCL_LINE
    2213             :                              trcrn,           &   ! LCOV_EXCL_LINE
    2214             :                              vicen,                 &   ! LCOV_EXCL_LINE
    2215             :                              vsnon,                 &   ! LCOV_EXCL_LINE
    2216             :                              aice      ,         &   ! LCOV_EXCL_LINE
    2217             :                              aice0     ,         &   ! LCOV_EXCL_LINE
    2218     6816473 :                              fpond, Tf       )
    2219     6816473 :             if (icepack_warnings_aborted(subname)) return
    2220             : 
    2221             :          endif ! aice > puny
    2222             : 
    2223             :       endif  ! kitd = 1
    2224             : 
    2225             : !      call ice_timer_stop(timer_catconv)    ! category conversions
    2226             : 
    2227             :       !-----------------------------------------------------------------
    2228             :       ! Add frazil ice growing in leads.
    2229             :       !-----------------------------------------------------------------
    2230             : 
    2231             :       ! identify ice-ocean cells
    2232             : 
    2233             :          call add_new_ice (ncat,          nilyr,        &
    2234             :                            nfsd,          nblyr,        &   ! LCOV_EXCL_LINE
    2235             :                            n_aero,        dt,           &   ! LCOV_EXCL_LINE
    2236             :                            ntrcr,         nltrcr,       &   ! LCOV_EXCL_LINE
    2237             :                            hin_max,       ktherm,       &   ! LCOV_EXCL_LINE
    2238             :                            aicen,         trcrn,        &   ! LCOV_EXCL_LINE
    2239             :                            vicen,         vsnon(1),     &   ! LCOV_EXCL_LINE
    2240             :                            aice0,         aice,         &   ! LCOV_EXCL_LINE
    2241             :                            frzmlt,        frazil,       &   ! LCOV_EXCL_LINE
    2242             :                            frz_onset,     yday,         &   ! LCOV_EXCL_LINE
    2243             :                            fresh,         fsalt,        &   ! LCOV_EXCL_LINE
    2244             :                            Tf,            sss,          &   ! LCOV_EXCL_LINE
    2245             :                            salinz,        phi_init,     &   ! LCOV_EXCL_LINE
    2246             :                            dSin0_frazil,  bgrid,        &   ! LCOV_EXCL_LINE
    2247             :                            cgrid,         igrid,        &   ! LCOV_EXCL_LINE
    2248             :                            nbtrcr,        flux_bio,     &   ! LCOV_EXCL_LINE
    2249             :                            ocean_bio,                   &   ! LCOV_EXCL_LINE
    2250             :                            frazil_diag,   fiso_ocn,     &   ! LCOV_EXCL_LINE
    2251             :                            HDO_ocn,       H2_16O_ocn,   &   ! LCOV_EXCL_LINE
    2252             :                            H2_18O_ocn,                  &   ! LCOV_EXCL_LINE
    2253             :                            wave_sig_ht,                 &   ! LCOV_EXCL_LINE
    2254             :                            wave_spectrum,               &   ! LCOV_EXCL_LINE
    2255             :                            wavefreq,      dwavefreq,    &   ! LCOV_EXCL_LINE
    2256             :                            d_afsd_latg,   d_afsd_newi,  &   ! LCOV_EXCL_LINE
    2257    10719744 :                            floe_rad_c, floe_binwidth)
    2258             : 
    2259    10719744 :          if (icepack_warnings_aborted(subname)) return
    2260             : 
    2261             :       !-----------------------------------------------------------------
    2262             :       ! Melt ice laterally.
    2263             :       !-----------------------------------------------------------------
    2264             : 
    2265             :       call lateral_melt (dt,        ncat,          &
    2266             :                          nilyr,     nslyr,         &   ! LCOV_EXCL_LINE
    2267             :                          n_aero,    fpond,         &   ! LCOV_EXCL_LINE
    2268             :                          fresh,     fsalt,         &   ! LCOV_EXCL_LINE
    2269             :                          fhocn,     faero_ocn,     &   ! LCOV_EXCL_LINE
    2270             :                          fiso_ocn,                 &   ! LCOV_EXCL_LINE
    2271             :                          rside,     meltl,         &   ! LCOV_EXCL_LINE
    2272             :                          fside,     wlat,          &   ! LCOV_EXCL_LINE
    2273             :                          aicen,     vicen,         &   ! LCOV_EXCL_LINE
    2274             :                          vsnon,     trcrn,         &   ! LCOV_EXCL_LINE
    2275             :                          flux_bio,                 &   ! LCOV_EXCL_LINE
    2276             :                          nbtrcr,    nblyr,         &   ! LCOV_EXCL_LINE
    2277             :                          nfsd,      d_afsd_latm,   &   ! LCOV_EXCL_LINE
    2278    10719744 :                          floe_rad_c,floe_binwidth)
    2279    10719744 :       if (icepack_warnings_aborted(subname)) return
    2280             : 
    2281             :       ! Floe welding during freezing conditions
    2282    10719744 :       if (tr_fsd) then
    2283             :          call fsd_weld_thermo (ncat,  nfsd,   &
    2284             :                                dt,    frzmlt, &   ! LCOV_EXCL_LINE
    2285             :                                aicen, trcrn,  &   ! LCOV_EXCL_LINE
    2286           0 :                                d_afsd_weld)
    2287           0 :          if (icepack_warnings_aborted(subname)) return
    2288             :       endif
    2289             : 
    2290             :       !-----------------------------------------------------------------
    2291             :       ! For the special case of a single category, adjust the area and
    2292             :       ! volume (assuming that half the volume change decreases the
    2293             :       ! thickness, and the other half decreases the area).
    2294             :       !-----------------------------------------------------------------
    2295             : 
    2296             : !echmod: test this
    2297    10719744 :       if (ncat==1) &
    2298             :          call reduce_area (hin_max   (0),                &   ! LCOV_EXCL_LINE
    2299             :                            aicen     (1), vicen     (1), &   ! LCOV_EXCL_LINE
    2300           0 :                            aicen_init(1), vicen_init(1))
    2301    10719744 :          if (icepack_warnings_aborted(subname)) return
    2302             : 
    2303             :       !-----------------------------------------------------------------
    2304             :       ! ITD cleanup: Rebin thickness categories if necessary, and remove
    2305             :       !  categories with very small areas.
    2306             :       !-----------------------------------------------------------------
    2307             : 
    2308             :       call cleanup_itd (dt,                   ntrcr,            &
    2309             :                         nilyr,                nslyr,            &   ! LCOV_EXCL_LINE
    2310             :                         ncat,                 hin_max,          &   ! LCOV_EXCL_LINE
    2311             :                         aicen,                trcrn(1:ntrcr,:), &   ! LCOV_EXCL_LINE
    2312             :                         vicen,                vsnon,            &   ! LCOV_EXCL_LINE
    2313             :                         aice0,                aice,             &   ! LCOV_EXCL_LINE
    2314             :                         n_aero,                                 &   ! LCOV_EXCL_LINE
    2315             :                         nbtrcr,               nblyr,            &   ! LCOV_EXCL_LINE
    2316             :                         tr_aero,                                &   ! LCOV_EXCL_LINE
    2317             :                         tr_pond_topo,                           &   ! LCOV_EXCL_LINE
    2318             :                         first_ice,                              &   ! LCOV_EXCL_LINE
    2319             :                         trcr_depend,          trcr_base,        &   ! LCOV_EXCL_LINE
    2320             :                         n_trcr_strata,        nt_strata,        &   ! LCOV_EXCL_LINE
    2321             :                         fpond,                fresh,            &   ! LCOV_EXCL_LINE
    2322             :                         fsalt,                fhocn,            &   ! LCOV_EXCL_LINE
    2323             :                         faero_ocn,            fiso_ocn,         &   ! LCOV_EXCL_LINE
    2324    10719744 :                         flux_bio,             Tf                )
    2325    10719744 :       if (icepack_warnings_aborted(subname)) return
    2326             : 
    2327    10719744 :       first_call = .false.
    2328             : 
    2329             :       end subroutine icepack_step_therm2
    2330             : 
    2331             : !=======================================================================
    2332             : 
    2333             :       end module icepack_therm_itd
    2334             : 
    2335             : !=======================================================================

Generated by: LCOV version 1.14-6-g40580cd