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

Generated by: LCOV version 1.14-6-g40580cd