LCOV - code coverage report
Current view: top level - cicecore/cicedyn/dynamics - ice_transport_remap.F90 (source / functions) Hit Total Coverage
Test: 231018-211459:8916b9ff2c:1:quick Lines: 1135 1410 80.50 %
Date: 2023-10-18 15:30:36 Functions: 10 10 100.00 %

          Line data    Source code
       1             : !=======================================================================
       2             : ! Transports quantities using the second-order conservative remapping
       3             : ! scheme developed by John Dukowicz and John Baumgardner (DB) and modified
       4             : ! for sea ice by William Lipscomb and Elizabeth Hunke.
       5             : !
       6             : ! References:
       7             : !
       8             : ! Dukowicz, J. K., and J. R. Baumgardner, 2000: Incremental
       9             : !  remapping as a transport/advection algorithm, J. Comput. Phys.,
      10             : !  160, 318-335.
      11             : !
      12             : ! Lipscomb, W. H., and E. C. Hunke, 2004: Modeling sea ice
      13             : !  transport using incremental remapping, Mon. Wea. Rev., 132,
      14             : !  1341-1354.
      15             : !
      16             : ! authors William H. Lipscomb, LANL
      17             : !         John Baumgardner, LANL
      18             : !
      19             : ! 2003: Vectorized by Clifford Chen (Fujitsu) and William Lipscomb
      20             : ! 2004-05: Block structure added (WHL)
      21             : ! 2006: Moved remap driver to ice_transport_driver
      22             : !       Geometry changes:
      23             : !       (1) Reconstruct fields in stretched logically rectangular coordinates
      24             : !       (2) Modify geometry so that the area flux across each edge
      25             : !           can be specified (following an idea of Mats Bentsen)
      26             : ! 2010: ECH removed unnecessary grid arrays and optional arguments from
      27             : !       horizontal_remap
      28             : 
      29             :       module ice_transport_remap
      30             : 
      31             :       use ice_kinds_mod
      32             :       use ice_blocks, only: nx_block, ny_block
      33             :       use ice_calendar, only: istep1
      34             :       use ice_communicate, only: my_task
      35             :       use ice_constants, only: c0, c1, c2, c12, p333, p4, p5, p6, &
      36             :           eps13, eps16, &   ! LCOV_EXCL_LINE
      37             :           field_loc_center, field_type_scalar, &   ! LCOV_EXCL_LINE
      38             :           field_loc_NEcorner, field_type_vector
      39             :       use ice_diagnostics, only: diagnostic_abort
      40             :       use ice_domain_size, only: max_blocks, ncat
      41             :       use ice_fileunits, only: nu_diag
      42             :       use ice_exit, only: abort_ice
      43             :       use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted
      44             :       use icepack_intfc, only: icepack_query_parameters
      45             :       use ice_grid, only : grid_ice
      46             : 
      47             :       implicit none
      48             :       private
      49             :       public :: init_remap, horizontal_remap, make_masks
      50             : 
      51             :       integer (kind=int_kind), parameter ::     &
      52             :          ngroups  = 6      ,&! number of groups of triangles that   ! LCOV_EXCL_LINE
      53             :                              ! contribute transports across each edge
      54             :          nvert = 3           ! number of vertices in a triangle
      55             : 
      56             :       ! for triangle integral formulas
      57             :       real (kind=dbl_kind), parameter ::  &
      58             :          p5625m = -9._dbl_kind/16._dbl_kind    ,&   ! LCOV_EXCL_LINE
      59             :          p52083 = 25._dbl_kind/48._dbl_kind
      60             : 
      61             :       logical :: &
      62             :          l_fixed_area ! if true, prescribe area flux across each edge
      63             :                       ! if false, area flux is determined internally
      64             :                       ! and is passed out
      65             : 
      66             :       logical (kind=log_kind), parameter :: bugcheck = .false.
      67             : 
      68             : !=======================================================================
      69             : ! Here is some information about how the incremental remapping scheme
      70             : ! works in CICE and how it can be adapted for use in other models.
      71             : !
      72             : ! The remapping routine is designed to transport a generic mass-like
      73             : ! field (in CICE, the ice fractional area) along with an arbitrary number
      74             : ! of tracers in two dimensions.  The velocity components are assumed
      75             : ! to lie at grid cell corners and the transported scalars at cell centers.
      76             : ! Incremental remapping has the following desirable properties:
      77             : !
      78             : ! (1) Tracer monotonicity is preserved.  That is, no new local
      79             : !     extrema are produced in fields like ice thickness or internal
      80             : !     energy.
      81             : ! (2) The reconstucted mass and tracer fields vary linearly in x and y.
      82             : !     This means that remapping is 2nd-order accurate in space,
      83             : !     except where horizontal gradients are limited to preserve
      84             : !     monotonicity.
      85             : ! (3) There are economies of scale.  Transporting a single field
      86             : !     is rather expensive, but additional fields have a relatively
      87             : !     low marginal cost.
      88             : !
      89             : ! The following generic conservation equations may be solved:
      90             : !
      91             : !            dm/dt = del*(u*m)             (0)
      92             : !       d(m*T1)/dt = del*(u*m*T1)          (1)
      93             : !    d(m*T1*T2)/dt = del*(u*m*T1*T2)       (2)
      94             : ! d(m*T1*T2*T3)/dt = del*(u*m*T1*T2*T3)    (3)
      95             : !
      96             : ! where d is a partial derivative, del is the 2D divergence operator,
      97             : ! u is the horizontal velocity, m is the mass density field, and
      98             : ! T1, T2, and T3 are tracers.
      99             : !
     100             : ! In CICE, these equations have the form
     101             : !
     102             : !               da/dt = del*(u*a)          (4)
     103             : ! dv/dt =   d(a*h)/dt = del*(u*a*h)        (5)
     104             : ! de/dt = d(a*h*q)/dt = del*(u*a*h*q)      (6)
     105             : !            d(aT)/dt = del*(u*a*t)        (7)
     106             : !
     107             : ! where a = fractional ice area, v = ice/snow volume, h = v/a = thickness,
     108             : ! e = ice/snow internal energy (J/m^2), q = e/v = internal energy per
     109             : ! unit volume (J/m^3), and T is a tracer.  These equations express
     110             : ! conservation of ice area, volume, internal energy, and area-weighted
     111             : ! tracer, respectively.
     112             : !
     113             : ! (Note: In CICE, a, v and e are prognostic quantities from which
     114             : !  h and q are diagnosed.  The remapping routine works with tracers,
     115             : !  which means that h and q must be derived from a, v, and e before
     116             : !  calling the remapping routine.)
     117             : !
     118             : ! Earlier versions of CICE assumed fixed ice and snow density.
     119             : ! Beginning with CICE 4.0, the ice and snow density can be variable.
     120             : ! In this case, equations (5) and (6) are replaced by
     121             : !
     122             : ! dv/dt =        d(a*h)/dt = del*(u*a*h)          (8)
     123             : ! dm/dt =    d(a*h*rho)/dt = del*(u*a*h*rho)      (9)
     124             : ! de/dt = d(a*h*rho*qm)/dt = del*(u*a*h*rho*qm)   (10)
     125             : !
     126             : ! where rho = density and qm = internal energy per unit mass (J/kg).
     127             : ! Eq. (9) expresses mass conservation, which in the variable-density
     128             : ! case is no longer equivalent to volume conservation (8).
     129             : !
     130             : ! Tracers satisfying equations of the form (1) are called "type 1."
     131             : ! In CICE the paradigmatic type 1 tracers are hi and hs.
     132             : !
     133             : ! Tracers satisfying equations of the form (2) are called "type 2".
     134             : ! The paradigmatic type 2 tracers are qi and qs (or rhoi and rhos
     135             : !  in the variable-density case).
     136             : !
     137             : ! Tracers satisfying equations of the form (3) are called "type 3."
     138             : ! The paradigmatic type 3 tracers are qmi and qms in the variable-density
     139             : ! case.  There are no such tracers in the constant-density case.
     140             : !
     141             : ! The fields a, T1, and T2 are reconstructed in each grid cell with
     142             : ! 2nd-order accuracy.  T3 is reconstructed with 1st-order accuracy
     143             : ! (i.e., it is transported in upwind fashion) in order to avoid
     144             : ! additional mathematical complexity.
     145             : !
     146             : ! The mass-like field lives in the array "mm" (shorthand for mean
     147             : ! mass) and the tracers fields in the array "tm" (mean tracers).
     148             : ! In order to transport tracers correctly, the remapping routine
     149             : ! needs to know the tracers types and relationships.  This is done
     150             : ! as follows:
     151             : !
     152             : ! Each field in the "tm" array is assigned an index, 1:ntrace.
     153             : ! (Note: ntrace is not the same as ntrcr, the number of tracers
     154             : ! in the trcrn state variable array.  For remapping purposes we
     155             : ! have additional tracers hi and hs.)
     156             : !
     157             : ! The tracer types (1,2,3) are contained in the "tracer_type" array.
     158             : ! For standard CICE:
     159             : !
     160             : !     tracer_type = (1 1 1 2 2 2 2 2)
     161             : !
     162             : ! Type 2 and type 3 tracers are said to depend on type 1 tracers.
     163             : ! For instance, qi depends on hi, which is to say that
     164             : ! there is a conservation equation of the form (2) or (6).
     165             : ! Thus we define a "depend" array.  For standard CICE:
     166             : !
     167             : !          depend = (0 0 0 1 1 1 1 2)
     168             : !
     169             : ! which implies that elements 1-3 (hi, hs, Ts) are type 1,
     170             : ! elements 4-7 (qi) depend on element 1 (hi), and element 8 (qs)
     171             : ! depends on element 2 (hs).
     172             : !
     173             : ! We also define a logical array "has_dependents".  In standard CICE:
     174             : !
     175             : !  has_dependents = (T T F F F F F F),
     176             : !
     177             : ! which means that only elements 1 and 2 (hi and hs) have dependent
     178             : ! tracers.
     179             : !
     180             : ! For the variable-density case, things are a bit more complicated.
     181             : ! Suppose we have 4 variable-density ice layers and one variable-
     182             : ! density snow layer.  Then the indexing is as follows:
     183             : ! 1    = hi
     184             : ! 2    = hs
     185             : ! 3    = Ts
     186             : ! 4-7  = rhoi
     187             : ! 8    = rhos
     188             : ! 9-12 = qmi
     189             : ! 13   = qms
     190             : !
     191             : ! The key arrays are:
     192             : !
     193             : !    tracer_type = (1 1 1 2 2 2 2 2 3 3 3 3 3)
     194             : !
     195             : !         depend = (0 0 0 1 1 1 1 2 4 5 6 7 8)
     196             : !
     197             : ! has_dependents = (T T F T T T T T F F F F F)
     198             : !
     199             : ! which imply that hi and hs are type 1 with dependents rhoi and rhos,
     200             : ! while rhoi and rhos are type 2 with dependents qmi and qms.
     201             : !
     202             : ! Tracers added to the ntrcr array are handled automatically
     203             : ! by the remapping with little extra coding.  It is necessary
     204             : ! only to provide the correct type and dependency information.
     205             : !
     206             : ! When using this routine in other models, most of the tracer dependency
     207             : ! apparatus may be irrelevant.  In a layered ocean model, for example,
     208             : ! the transported fields are the layer thickness h (the mass density
     209             : ! field) and two or more tracers (T, S, and various trace species).
     210             : ! Suppose there are just two tracers, T and S.  Then the tracer arrays
     211             : ! have the values:
     212             : !
     213             : !    tracer_type = (1 1)
     214             : !         depend = (0 0)
     215             : ! has_dependents = (F F)
     216             : !
     217             : ! which is to say that all tracer transport equations are of the form (1).
     218             : !
     219             : ! The tracer dependency arrays are optional input arguments for the
     220             : ! main remapping subroutine.  If these arrays are not passed in, they
     221             : ! take on the default values tracer_type(:) = 1, depend(:) = 0, and
     222             : ! has_dependents(:) = F, which are appropriate for most purposes.
     223             : !
     224             : ! Another optional argument is integral_order.  If integral_order = 1,
     225             : ! then the triangle integrals are exact for linear functions of x and y.
     226             : ! If integral_order = 2, these integrals are exact for both linear and
     227             : ! quadratic functions.  If integral_order = 3, integrals are exact for
     228             : ! cubic functions as well.  If all tracers are of type 1, then the
     229             : ! integrals of mass*tracer are quadratic, and integral_order = 2 is
     230             : ! sufficient.  In CICE, where there are type 2 tracers, we integrate
     231             : ! functions of the form mass*tracer1*tracer2.  Thus integral_order = 3
     232             : ! is required for exactness, though integral_order = 2 may be good enough
     233             : ! in practice.
     234             : !
     235             : ! Finally, a few words about the edgearea fields:
     236             : !
     237             : ! In earlier versions of this scheme, the divergence of the velocity
     238             : ! field implied by the remapping was, in general, different from the
     239             : ! value of del*u computed in the dynamics.  For energetic consistency
     240             : ! (in CICE as well as in layered ocean models such as HYPOP),
     241             : ! these two values should agree.  This can be ensured by setting
     242             : ! l_fixed_area = T and specifying the area transported across each grid
     243             : ! cell edge in the arrays edgearea_e and edgearea_n.  The departure
     244             : ! regions are then tweaked, following an idea by Mats Bentsen, such
     245             : ! that they have the desired area.  If l_fixed_area = F, these regions
     246             : ! are not tweaked, and the edgearea arrays are output variables.
     247             : !
     248             : !=======================================================================
     249             : 
     250             :       contains
     251             : 
     252             : !=======================================================================
     253             : !
     254             : ! Grid quantities used by the remapping transport scheme
     255             : !
     256             : ! Note:  the arrays xyav, xxxav, etc are not needed for rectangular grids
     257             : ! but may be needed in the future for other nonuniform grids.  They have
     258             : ! been commented out here to save memory and flops.
     259             : !
     260             : ! author William H. Lipscomb, LANL
     261             : 
     262          37 :       subroutine init_remap
     263             : 
     264             :       use ice_domain, only: nblocks
     265             :       use ice_grid, only: xav, yav, xxav, yyav
     266             : !                          dxT, dyT, xyav, &
     267             : !                          xxxav, xxyav, xyyav, yyyav
     268             : 
     269             :       integer (kind=int_kind) ::     &
     270             :         i, j, iblk     ! standard indices
     271             : 
     272             :       character(len=*), parameter :: subname = '(init_remap)'
     273             : 
     274             :       ! Compute grid cell average geometric quantities on the scaled
     275             :       ! rectangular grid with dx = 1, dy = 1.
     276             :       !
     277             :       ! Note: On a rectangular grid, the integral of any odd function
     278             :       !       of x or y = 0.
     279             : 
     280          20 :       !$OMP PARALLEL DO PRIVATE(iblk,i,j) SCHEDULE(runtime)
     281          50 :       do iblk = 1, nblocks
     282        1276 :          do j = 1, ny_block
     283       50267 :          do i = 1, nx_block
     284       49028 :             xav(i,j,iblk) = c0
     285       49028 :             yav(i,j,iblk) = c0
     286             : !!!            These formulas would be used on a rectangular grid
     287             : !!!            with dimensions (dxT, dyT):
     288             : !!!            xxav(i,j,iblk) = dxT(i,j,iblk)**2 / c12
     289             : !!!            yyav(i,j,iblk) = dyT(i,j,iblk)**2 / c12
     290       49028 :             xxav(i,j,iblk) = c1/c12
     291       50234 :             yyav(i,j,iblk) = c1/c12
     292             : !            xyav(i,j,iblk) = c0
     293             : !            xxxav(i,j,iblk) = c0
     294             : !            xxyav(i,j,iblk) = c0
     295             : !            xyyav(i,j,iblk) = c0
     296             : !            yyyav(i,j,iblk) = c0
     297             :          enddo
     298             :          enddo
     299             :       enddo
     300             :       !$OMP END PARALLEL DO
     301             : 
     302             :       !-------------------------------------------------------------------
     303             :       ! Set logical l_fixed_area depending of the grid type.
     304             :       !
     305             :       ! If l_fixed_area is true, the area of each departure region is
     306             :       !  computed in advance (e.g., by taking the divergence of the
     307             :       !  velocity field and passed to locate_triangles.  The departure
     308             :       !  regions are adjusted to obtain the desired area.
     309             :       ! If false, edgearea is computed in locate_triangles and passed out.
     310             :       !
     311             :       ! l_fixed_area = .false. has been the default approach in CICE. It is 
     312             :       ! used like this for the B-grid. However, idealized tests with the 
     313             :       ! C-grid have shown that l_fixed_area = .false. leads to a checkerboard 
     314             :       ! pattern in prognostic fields (e.g. aice). Using l_fixed_area = .true. 
     315             :       ! eliminates the checkerboard pattern in C-grid simulations.
     316             :       ! 
     317             :       !-------------------------------------------------------------------
     318             : 
     319          37 :       if (grid_ice == 'CD' .or. grid_ice == 'C') then
     320           0 :          l_fixed_area = .true.
     321             :       else
     322          37 :          l_fixed_area = .false.
     323             :       endif
     324             : 
     325          37 :       end subroutine init_remap
     326             : 
     327             : !=======================================================================
     328             : !
     329             : ! Solve the transport equations for one timestep using the incremental
     330             : ! remapping scheme developed by John Dukowicz and John Baumgardner (DB)
     331             : ! and modified for sea ice by William Lipscomb and Elizabeth Hunke.
     332             : !
     333             : ! This scheme preserves monotonicity of ice area and tracers.  That is,
     334             : ! it does not produce new extrema.  It is second-order accurate in space,
     335             : ! except where gradients are limited to preserve monotonicity.
     336             : !
     337             : ! This version of the remapping allows the user to specify the areal
     338             : ! flux across each edge, based on an idea developed by Mats Bentsen.
     339             : !
     340             : ! author William H. Lipscomb, LANL
     341             : ! 2006: Moved driver (subroutine transport_remap) into separate module.
     342             : !       Geometry changes (logically rectangular coordinates, fixed
     343             : !        area fluxes)
     344             : 
     345        5784 :       subroutine horizontal_remap (dt,             ntrace,   &
     346             :                                    uvel,           vvel,     &   ! LCOV_EXCL_LINE
     347             :                                    mm,             tm,       &   ! LCOV_EXCL_LINE
     348             :                                    tracer_type,    depend,   &   ! LCOV_EXCL_LINE
     349             :                                    has_dependents,           &   ! LCOV_EXCL_LINE
     350             :                                    integral_order,           &   ! LCOV_EXCL_LINE
     351             :                                    l_dp_midpt,               &   ! LCOV_EXCL_LINE
     352           0 :                                    uvelE,          vvelN)
     353             : 
     354             :       use ice_boundary, only: ice_halo, ice_HaloMask, ice_HaloUpdate, &
     355             :           ice_HaloDestroy
     356             :       use ice_domain, only: nblocks, blocks_ice, halo_info, maskhalo_remap
     357             :       use ice_blocks, only: block, get_block, nghost
     358             :       use ice_grid, only: HTE, HTN, dxu, dyu,       &
     359             :                           earea, narea, tarear, hm,                  &   ! LCOV_EXCL_LINE
     360             :                           xav, yav, xxav, yyav
     361             : !                          xyav, xxxav, xxyav, xyyav, yyyav
     362             :       use ice_timers, only: ice_timer_start, ice_timer_stop, timer_bound
     363             : 
     364             :       real (kind=dbl_kind), intent(in) ::     &
     365             :          dt       ! time step
     366             : 
     367             :       integer (kind=int_kind), intent(in) :: &
     368             :          ntrace   ! number of tracers in use
     369             : 
     370             :       real (kind=dbl_kind), intent(in), dimension(nx_block,ny_block,max_blocks) :: &
     371             :          uvel,  & ! x-component of velocity (m/s) ugrid   ! LCOV_EXCL_LINE
     372             :          vvel     ! y-component of velocity (m/s) ugrid
     373             : 
     374             :       real (kind=dbl_kind), intent(in), optional, dimension(nx_block,ny_block,max_blocks) :: &
     375             :          uvelE, & ! x-component of velocity (m/s) egrid   ! LCOV_EXCL_LINE
     376             :          vvelN    ! y-component of velocity (m/s) ngrid
     377             : 
     378             :       real (kind=dbl_kind), intent(inout), dimension (nx_block,ny_block,0:ncat,max_blocks) :: &
     379             :          mm       ! mean mass values in each grid cell
     380             : 
     381             :       real (kind=dbl_kind), intent(inout), dimension (nx_block,ny_block,ntrace,ncat,max_blocks) :: &
     382             :          tm       ! mean tracer values in each grid cell
     383             : 
     384             :       integer (kind=int_kind), dimension (ntrace), intent(in) :: &
     385             :          tracer_type    , & ! = 1, 2, or 3 (see comments above)   ! LCOV_EXCL_LINE
     386             :          depend             ! tracer dependencies (see above)
     387             : 
     388             :       logical (kind=log_kind), dimension (ntrace), intent(in) :: &
     389             :          has_dependents     ! true if a tracer has dependent tracers
     390             : 
     391             :       integer (kind=int_kind), intent(in) :: &
     392             :          integral_order     ! polynomial order for triangle integrals
     393             : 
     394             :       logical (kind=log_kind), intent(in) :: &
     395             :          l_dp_midpt         ! if true, find departure points using
     396             :                             ! corrected midpoint velocity
     397             :       ! local variables
     398             : 
     399             :       integer (kind=int_kind) ::     &
     400             :          i, j           , & ! horizontal indices   ! LCOV_EXCL_LINE
     401             :          iblk           , & ! block index   ! LCOV_EXCL_LINE
     402             :          ilo,ihi,jlo,jhi, & ! beginning and end of physical domain   ! LCOV_EXCL_LINE
     403             :          n, m               ! ice category, tracer indices
     404             : 
     405             :       integer (kind=int_kind), dimension(0:ncat,max_blocks) ::     &
     406       11568 :          icellsnc           ! number of cells with ice
     407             : 
     408             :       integer (kind=int_kind), dimension(nx_block*ny_block,0:ncat) ::     &
     409       11568 :          indxinc, indxjnc   ! compressed i/j indices
     410             : 
     411             :       real (kind=dbl_kind), dimension(nx_block,ny_block) ::  &
     412             :          edgearea_e     , & ! area of departure regions for east edges   ! LCOV_EXCL_LINE
     413     1260048 :          edgearea_n         ! area of departure regions for north edges
     414             : 
     415             :       real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks) ::     &
     416             :          dpx            , & ! x coordinates of departure points at cell corners   ! LCOV_EXCL_LINE
     417     5015568 :          dpy                ! y coordinates of departure points at cell corners
     418             : 
     419             :       real (kind=dbl_kind), dimension(nx_block,ny_block,0:ncat,max_blocks) :: &
     420             :          mc             , & ! mass at geometric center of cell   ! LCOV_EXCL_LINE
     421    60086928 :          mx, my             ! limited derivative of mass wrt x and y
     422             : 
     423             :       real (kind=dbl_kind), dimension(nx_block,ny_block,0:ncat) :: &
     424     7518288 :          mmask              ! = 1. if mass is present, = 0. otherwise
     425             : 
     426             :       real (kind=dbl_kind), dimension (nx_block,ny_block,ntrace,ncat,max_blocks) :: &
     427             :          tc             , & ! tracer values at geometric center of cell   ! LCOV_EXCL_LINE
     428  1301493648 :          tx, ty             ! limited derivative of tracer wrt x and y
     429             : 
     430             :       real (kind=dbl_kind), dimension (nx_block,ny_block,ntrace,ncat) ::     &
     431   162694128 :          tmask              ! = 1. if tracer is present, = 0. otherwise
     432             : 
     433             :       real (kind=dbl_kind), dimension (nx_block,ny_block,0:ncat) ::     &
     434    15026448 :          mflxe, mflxn       ! mass transports across E and N cell edges
     435             : 
     436             :       real (kind=dbl_kind), dimension (nx_block,ny_block,ntrace,ncat) :: &
     437   325378128 :          mtflxe, mtflxn     ! mass*tracer transports across E and N cell edges
     438             : 
     439             :       real (kind=dbl_kind), dimension (nx_block,ny_block,ngroups) ::     &
     440     7518288 :          triarea            ! area of east-edge departure triangle
     441             : 
     442             :       real (kind=dbl_kind), dimension (nx_block,ny_block,0:nvert,ngroups) ::  &
     443    60092688 :          xp, yp             ! x and y coordinates of special triangle points
     444             :                             ! (need 4 points for triangle integrals)
     445             :       integer (kind=int_kind), dimension (nx_block,ny_block,ngroups) ::     &
     446             :          iflux          , & ! i index of cell contributing transport   ! LCOV_EXCL_LINE
     447       11568 :          jflux              ! j index of cell contributing transport
     448             : 
     449             :       integer (kind=int_kind), dimension(ngroups,max_blocks) ::     &
     450       11568 :          icellsng           ! number of cells with ice
     451             : 
     452             :       integer (kind=int_kind), dimension(nx_block*ny_block,ngroups) ::     &
     453       11568 :          indxing, indxjng   ! compressed i/j indices
     454             : 
     455             :       integer (kind=int_kind), dimension(nx_block,ny_block,max_blocks) :: &
     456       10128 :          halomask           ! temporary mask for fast halo updates
     457             : 
     458             :       logical (kind=log_kind) ::     &
     459             :          l_stop             ! if true, abort the model
     460             : 
     461             :       integer (kind=int_kind) ::     &
     462             :          istop, jstop       ! indices of grid cell where model aborts
     463             : 
     464             :       character (len=char_len) ::   &
     465             :          edge               ! 'north' or 'east'
     466             : 
     467             :       type (ice_halo) :: &
     468             :          halo_info_tracer   ! masked halo
     469             : 
     470             :       type (block) ::     &
     471             :          this_block         ! block information for current block
     472             : 
     473             :       character(len=*), parameter :: subname = '(horizontal_remap)'
     474             : 
     475             :       !-------------------------------------------------------------------
     476             :       ! Remap the ice area and associated tracers.
     477             :       ! Remap the open water area (without tracers).
     478             :       !-------------------------------------------------------------------
     479             : 
     480             :       !$OMP PARALLEL DO PRIVATE(iblk,ilo,ihi,jlo,jhi,this_block,n,   &
     481             :       !$OMP          indxinc,indxjnc,mmask,tmask,istop,jstop,l_stop) &   ! LCOV_EXCL_LINE
     482        2880 :       !$OMP SCHEDULE(runtime)
     483        8688 :       do iblk = 1, nblocks
     484             : 
     485        5784 :          l_stop = .false.
     486        5784 :          istop = 0
     487        5784 :          jstop = 0
     488             : 
     489        5784 :          this_block = get_block(blocks_ice(iblk),iblk)
     490        5784 :          ilo = this_block%ilo
     491        5784 :          ihi = this_block%ihi
     492        5784 :          jlo = this_block%jlo
     493        5784 :          jhi = this_block%jhi
     494             : 
     495             :          !-------------------------------------------------------------------
     496             :          ! Compute masks and count ice cells.
     497             :          ! Masks are used to prevent tracer values in cells without ice from
     498             :          !  being used to compute tracer gradients.
     499             :          !-------------------------------------------------------------------
     500             : 
     501             :          call make_masks (nx_block,           ny_block,              &
     502             :                           ilo, ihi,           jlo, jhi,              &   ! LCOV_EXCL_LINE
     503             :                           nghost,             ntrace,                &   ! LCOV_EXCL_LINE
     504             :                           has_dependents,     icellsnc(:,iblk),      &   ! LCOV_EXCL_LINE
     505             :                           indxinc(:,:),       indxjnc(:,:),          &   ! LCOV_EXCL_LINE
     506             :                           mm  (:,:,:,iblk),   mmask(:,:,:),          &   ! LCOV_EXCL_LINE
     507        5784 :                           tm(:,:,:,:,iblk),   tmask(:,:,:,:))
     508             : 
     509             :          !-------------------------------------------------------------------
     510             :          ! Construct linear fields, limiting gradients to preserve monotonicity.
     511             :          ! Note: Pass in unit arrays instead of true distances HTE, HTN, etc.
     512             :          !       The resulting gradients are in scaled coordinates.
     513             :          !-------------------------------------------------------------------
     514             : 
     515             :          ! open water
     516             :          call construct_fields(nx_block,          ny_block,          &
     517             :                                ilo, ihi,          jlo, jhi,          &   ! LCOV_EXCL_LINE
     518             :                                nghost,            ntrace,            &   ! LCOV_EXCL_LINE
     519             :                                tracer_type,       depend,            &   ! LCOV_EXCL_LINE
     520             :                                has_dependents,    icellsnc(0,iblk),  &   ! LCOV_EXCL_LINE
     521             :                                indxinc(:,0),      indxjnc(:,0),      &   ! LCOV_EXCL_LINE
     522             :                                hm     (:,:,iblk), xav   (:,:,iblk),  &   ! LCOV_EXCL_LINE
     523             :                                yav    (:,:,iblk), xxav  (:,:,iblk),  &   ! LCOV_EXCL_LINE
     524             :                                yyav   (:,:,iblk),                    &   ! LCOV_EXCL_LINE
     525             : !                               xyav   (:,:,iblk),                    &   ! LCOV_EXCL_LINE
     526             : !                               xxxav  (:,:,iblk), xxyav (:,:,iblk),  &   ! LCOV_EXCL_LINE
     527             : !                               xyyav  (:,:,iblk), yyyav (:,:,iblk),  &   ! LCOV_EXCL_LINE
     528             :                                mm   (:,:,0,iblk), mc  (:,:,0,iblk),  &   ! LCOV_EXCL_LINE
     529             :                                mx   (:,:,0,iblk), my  (:,:,0,iblk),  &   ! LCOV_EXCL_LINE
     530        5784 :                                mmask(:,:,0) )
     531             : 
     532             :          ! ice categories
     533             : 
     534       34704 :          do n = 1, ncat
     535             : 
     536             :             call construct_fields(nx_block,            ny_block,            &
     537             :                                   ilo, ihi,            jlo, jhi,            &   ! LCOV_EXCL_LINE
     538             :                                   nghost,              ntrace,              &   ! LCOV_EXCL_LINE
     539             :                                   tracer_type,         depend,              &   ! LCOV_EXCL_LINE
     540             :                                   has_dependents,      icellsnc (n,iblk),   &   ! LCOV_EXCL_LINE
     541             :                                   indxinc  (:,n),      indxjnc(:,n),        &   ! LCOV_EXCL_LINE
     542             :                                   hm       (:,:,iblk), xav    (:,:,iblk),   &   ! LCOV_EXCL_LINE
     543             :                                   yav      (:,:,iblk), xxav   (:,:,iblk),   &   ! LCOV_EXCL_LINE
     544             :                                   yyav     (:,:,iblk),                      &   ! LCOV_EXCL_LINE
     545             : !                                  xyav     (:,:,iblk),                      &   ! LCOV_EXCL_LINE
     546             : !                                  xxxav    (:,:,iblk), xxyav  (:,:,iblk),   &   ! LCOV_EXCL_LINE
     547             : !                                  xyyav    (:,:,iblk), yyyav  (:,:,iblk),   &   ! LCOV_EXCL_LINE
     548             :                                   mm     (:,:,n,iblk),  mc  (:,:,n,iblk),    &   ! LCOV_EXCL_LINE
     549             :                                   mx     (:,:,n,iblk),  my  (:,:,n,iblk),    &   ! LCOV_EXCL_LINE
     550             :                                   mmask  (:,:,n),                            &   ! LCOV_EXCL_LINE
     551             :                                   tm   (:,:,:,n,iblk),  tc(:,:,:,n,iblk),    &   ! LCOV_EXCL_LINE
     552             :                                   tx   (:,:,:,n,iblk),  ty(:,:,:,n,iblk),    &   ! LCOV_EXCL_LINE
     553       34704 :                                   tmask(:,:,:,n) )
     554             : 
     555             :          enddo                  ! n
     556             : 
     557             :          !-------------------------------------------------------------------
     558             :          ! Given velocity field at cell corners, compute departure points
     559             :          ! of trajectories.
     560             :          !-------------------------------------------------------------------
     561             : 
     562             :          call departure_points(nx_block,         ny_block,          &
     563             :                                ilo, ihi,         jlo, jhi,          &   ! LCOV_EXCL_LINE
     564             :                                nghost,           dt,                &   ! LCOV_EXCL_LINE
     565             :                                uvel  (:,:,iblk), vvel(:,:,iblk),    &   ! LCOV_EXCL_LINE
     566             :                                dxu   (:,:,iblk), dyu (:,:,iblk),    &   ! LCOV_EXCL_LINE
     567             :                                HTN   (:,:,iblk), HTE (:,:,iblk),    &   ! LCOV_EXCL_LINE
     568             :                                dpx   (:,:,iblk), dpy (:,:,iblk),    &   ! LCOV_EXCL_LINE
     569             :                                l_dp_midpt,       l_stop,            &   ! LCOV_EXCL_LINE
     570        5784 :                                istop,            jstop)
     571             : 
     572       11568 :          if (l_stop) then
     573           0 :             call diagnostic_abort(istop,jstop,iblk,'bad departure points')
     574             :          endif
     575             : 
     576             :       enddo                     ! iblk
     577             :       !$OMP END PARALLEL DO
     578             : 
     579             :       !-------------------------------------------------------------------
     580             :       ! Ghost cell updates
     581             :       ! If nghost >= 2, these calls are not needed
     582             :       !-------------------------------------------------------------------
     583             : 
     584             :       if (nghost==1) then
     585             : 
     586        5784 :          call ice_timer_start(timer_bound)
     587             : 
     588             :          ! departure points
     589           0 :          call ice_HaloUpdate (dpx,                halo_info, &
     590        5784 :                               field_loc_NEcorner, field_type_vector)
     591           0 :          call ice_HaloUpdate (dpy,                halo_info, &
     592        5784 :                               field_loc_NEcorner, field_type_vector)
     593             : 
     594             :          ! mass field
     595           0 :          call ice_HaloUpdate (mc,               halo_info, &
     596        5784 :                               field_loc_center, field_type_scalar)
     597           0 :          call ice_HaloUpdate (mx,               halo_info, &
     598        5784 :                               field_loc_center, field_type_vector)
     599           0 :          call ice_HaloUpdate (my,               halo_info, &
     600        5784 :                               field_loc_center, field_type_vector)
     601             : 
     602             :          ! tracer fields
     603        5784 :          if (maskhalo_remap) then
     604           0 :             halomask(:,:,:) = 0
     605           0 :             !$OMP PARALLEL DO PRIVATE(iblk,this_block,ilo,ihi,jlo,jhi,n,m,j,i) SCHEDULE(runtime)
     606           0 :             do iblk = 1, nblocks
     607           0 :                this_block = get_block(blocks_ice(iblk),iblk)
     608           0 :                ilo = this_block%ilo
     609           0 :                ihi = this_block%ihi
     610           0 :                jlo = this_block%jlo
     611           0 :                jhi = this_block%jhi
     612             : 
     613           0 :                do n = 1, ncat
     614           0 :                do m = 1, ntrace
     615           0 :                do j = jlo, jhi
     616           0 :                do i = ilo, ihi
     617           0 :                   if (tc(i,j,m,n,iblk) /= c0) halomask(i,j,iblk) = 1
     618           0 :                   if (tx(i,j,m,n,iblk) /= c0) halomask(i,j,iblk) = 1
     619           0 :                   if (ty(i,j,m,n,iblk) /= c0) halomask(i,j,iblk) = 1
     620             :                enddo
     621             :                enddo
     622             :                enddo
     623             :                enddo
     624             :             enddo
     625             :             !$OMP END PARALLEL DO
     626           0 :             call ice_HaloUpdate (halomask,         halo_info, &
     627           0 :                                  field_loc_center, field_type_scalar)
     628           0 :             call ice_HaloMask(halo_info_tracer, halo_info, halomask)
     629             : 
     630           0 :             call ice_HaloUpdate (tc,               halo_info_tracer, &
     631           0 :                                  field_loc_center, field_type_scalar)
     632           0 :             call ice_HaloUpdate (tx,               halo_info_tracer, &
     633           0 :                                  field_loc_center, field_type_vector)
     634           0 :             call ice_HaloUpdate (ty,               halo_info_tracer, &
     635           0 :                                  field_loc_center, field_type_vector)
     636           0 :             call ice_HaloDestroy(halo_info_tracer)
     637             :          else
     638           0 :             call ice_HaloUpdate (tc,               halo_info, &
     639        5784 :                                  field_loc_center, field_type_scalar)
     640           0 :             call ice_HaloUpdate (tx,               halo_info, &
     641        5784 :                                  field_loc_center, field_type_vector)
     642           0 :             call ice_HaloUpdate (ty,               halo_info, &
     643        5784 :                                  field_loc_center, field_type_vector)
     644             :          endif
     645        5784 :          call ice_timer_stop(timer_bound)
     646             : 
     647             :       endif  ! nghost
     648             : 
     649             :       ! tcraig, this OMP loop sometimes fails with cce/14.0.3, compiler bug??
     650             :       !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block,n,  &
     651             :       !$OMP                     edgearea_e,edgearea_n,edge,iflux,jflux, &   ! LCOV_EXCL_LINE
     652             :       !$OMP                     xp,yp,indxing,indxjng,mflxe,mflxn, &   ! LCOV_EXCL_LINE
     653             :       !$OMP                     mtflxe,mtflxn,triarea,istop,jstop,l_stop) &   ! LCOV_EXCL_LINE
     654        2880 :       !$OMP SCHEDULE(runtime)
     655        8688 :       do iblk = 1, nblocks
     656             : 
     657        5784 :          l_stop = .false.
     658        5784 :          istop = 0
     659        5784 :          jstop = 0
     660             : 
     661        5784 :          this_block = get_block(blocks_ice(iblk),iblk)
     662        5784 :          ilo = this_block%ilo
     663        5784 :          ihi = this_block%ihi
     664        5784 :          jlo = this_block%jlo
     665        5784 :          jhi = this_block%jhi
     666             : 
     667             :          !-------------------------------------------------------------------
     668             :          ! If l_fixed_area is true, compute edgearea by taking the divergence
     669             :          !  of the velocity field.  Otherwise, initialize edgearea.
     670             :          !-------------------------------------------------------------------
     671             : 
     672      204456 :          do j = 1, ny_block
     673     7151880 :          do i = 1, nx_block
     674     6947424 :             edgearea_e(i,j) = c0
     675     7146096 :             edgearea_n(i,j) = c0
     676             :          enddo
     677             :          enddo
     678             : 
     679        5784 :          if (l_fixed_area) then
     680           0 :             if (grid_ice == 'CD' .or. grid_ice == 'C') then ! velocities are already on the center
     681           0 :                if (.not.present(uvelE).or..not.present(vvelN)) then
     682           0 :                   call abort_ice (subname//'ERROR: uvelE,vvelN required with C|CD and l_fixed_area')
     683             :                endif
     684             : 
     685           0 :                do j = jlo, jhi
     686           0 :                do i = ilo-1, ihi
     687           0 :                   edgearea_e(i,j) = uvelE(i,j,iblk) * HTE(i,j,iblk) * dt
     688             :                enddo
     689             :                enddo
     690             : 
     691           0 :                do j = jlo-1, jhi
     692           0 :                do i = ilo, ihi
     693           0 :                   edgearea_n(i,j) = vvelN(i,j,iblk)*HTN(i,j,iblk) * dt
     694             :                enddo
     695             :                enddo
     696             : 
     697             :             else
     698           0 :                do j = jlo, jhi
     699           0 :                do i = ilo-1, ihi
     700             :                   edgearea_e(i,j) = (uvel(i,j,iblk) + uvel(i,j-1,iblk)) &
     701           0 :                                         * p5 * HTE(i,j,iblk) * dt
     702             :                enddo
     703             :                enddo
     704             : 
     705           0 :                do j = jlo-1, jhi
     706           0 :                do i = ilo, ihi
     707             :                   edgearea_n(i,j) = (vvel(i,j,iblk) + vvel(i-1,j,iblk)) &
     708           0 :                                         * p5 * HTN(i,j,iblk) * dt
     709             :                enddo
     710             :                enddo
     711             :             endif
     712             :          endif
     713             : 
     714             :          !-------------------------------------------------------------------
     715             :          ! Transports for east cell edges.
     716             :          !-------------------------------------------------------------------
     717             : 
     718             :          !-------------------------------------------------------------------
     719             :          ! Compute areas and vertices of departure triangles.
     720             :          !-------------------------------------------------------------------
     721             : 
     722        5784 :          edge = 'east'
     723             :          call locate_triangles(nx_block,          ny_block,           &
     724             :                                ilo, ihi,          jlo, jhi,           &   ! LCOV_EXCL_LINE
     725             :                                nghost,            edge,               &   ! LCOV_EXCL_LINE
     726             :                                icellsng(:,iblk),                      &   ! LCOV_EXCL_LINE
     727             :                                indxing(:,:),      indxjng(:,:),       &   ! LCOV_EXCL_LINE
     728             :                                dpx   (:,:,iblk),  dpy(:,:,iblk),      &   ! LCOV_EXCL_LINE
     729             :                                dxu   (:,:,iblk),  dyu(:,:,iblk),      &   ! LCOV_EXCL_LINE
     730             :                                earea (:,:,iblk),  narea (:,:,iblk),   &   ! LCOV_EXCL_LINE
     731             :                                xp    (:,:,:,:),   yp (:,:,:,:),       &   ! LCOV_EXCL_LINE
     732             :                                iflux,             jflux,              &   ! LCOV_EXCL_LINE
     733        5784 :                                triarea,           edgearea_e(:,:))
     734             : 
     735             :          !-------------------------------------------------------------------
     736             :          ! Given triangle vertices, compute coordinates of triangle points
     737             :          !  needed for transport integrals.
     738             :          !-------------------------------------------------------------------
     739             : 
     740             :          call triangle_coordinates (nx_block,        ny_block,         &
     741             :                                     integral_order,  icellsng(:,iblk), &   ! LCOV_EXCL_LINE
     742             :                                     indxing(:,:),    indxjng(:,:),     &   ! LCOV_EXCL_LINE
     743        5784 :                                     xp,              yp)
     744             : 
     745             :          !-------------------------------------------------------------------
     746             :          ! Compute the transport across east cell edges by summing contributions
     747             :          ! from each triangle.
     748             :          !-------------------------------------------------------------------
     749             : 
     750             :          ! open water
     751             :          call transport_integrals(nx_block,        ny_block,           &
     752             :                                   ntrace,          icellsng (:,iblk),  &   ! LCOV_EXCL_LINE
     753             :                                   indxing(:,:),    indxjng(:,:),       &   ! LCOV_EXCL_LINE
     754             :                                   tracer_type,     depend,             &   ! LCOV_EXCL_LINE
     755             :                                   integral_order,  triarea,            &   ! LCOV_EXCL_LINE
     756             :                                   iflux,           jflux,              &   ! LCOV_EXCL_LINE
     757             :                                   xp,              yp,                 &   ! LCOV_EXCL_LINE
     758             :                                   mc(:,:,0,iblk),  mx   (:,:,0,iblk),  &   ! LCOV_EXCL_LINE
     759        5784 :                                   my(:,:,0,iblk),  mflxe(:,:,0))
     760             : 
     761             :          ! ice categories
     762       34704 :          do n = 1, ncat
     763             :             call transport_integrals                                     &
     764             :                                (nx_block,          ny_block,             &   ! LCOV_EXCL_LINE
     765             :                                 ntrace,            icellsng (:,iblk),    &   ! LCOV_EXCL_LINE
     766             :                                 indxing(:,:),      indxjng(:,:),         &   ! LCOV_EXCL_LINE
     767             :                                 tracer_type,       depend,               &   ! LCOV_EXCL_LINE
     768             :                                 integral_order,    triarea,              &   ! LCOV_EXCL_LINE
     769             :                                 iflux,             jflux,                &   ! LCOV_EXCL_LINE
     770             :                                 xp,                yp,                   &   ! LCOV_EXCL_LINE
     771             :                                 mc(:,:,  n,iblk),  mx    (:,:,  n,iblk), &   ! LCOV_EXCL_LINE
     772             :                                 my(:,:,  n,iblk),  mflxe (:,:,  n),      &   ! LCOV_EXCL_LINE
     773             :                                 tc(:,:,:,n,iblk),  tx    (:,:,:,n,iblk), &   ! LCOV_EXCL_LINE
     774       34704 :                                 ty(:,:,:,n,iblk),  mtflxe(:,:,:,n))
     775             : 
     776             :          enddo
     777             : 
     778             :          !-------------------------------------------------------------------
     779             :          ! Repeat for north edges
     780             :          !-------------------------------------------------------------------
     781             : 
     782        5784 :          edge = 'north'
     783             :          call locate_triangles(nx_block,          ny_block,           &
     784             :                                ilo, ihi,          jlo, jhi,           &   ! LCOV_EXCL_LINE
     785             :                                nghost,            edge,               &   ! LCOV_EXCL_LINE
     786             :                                icellsng(:,iblk),                      &   ! LCOV_EXCL_LINE
     787             :                                indxing(:,:),      indxjng(:,:),       &   ! LCOV_EXCL_LINE
     788             :                                dpx   (:,:,iblk),  dpy (:,:,iblk),     &   ! LCOV_EXCL_LINE
     789             :                                dxu   (:,:,iblk),  dyu (:,:,iblk),     &   ! LCOV_EXCL_LINE
     790             :                                earea (:,:,iblk),  narea (:,:,iblk),   &   ! LCOV_EXCL_LINE
     791             :                                xp    (:,:,:,:),   yp(:,:,:,:),        &   ! LCOV_EXCL_LINE
     792             :                                iflux,             jflux,              &   ! LCOV_EXCL_LINE
     793        5784 :                                triarea,           edgearea_n(:,:))
     794             : 
     795             :          call triangle_coordinates (nx_block,        ny_block,         &
     796             :                                     integral_order,  icellsng(:,iblk), &   ! LCOV_EXCL_LINE
     797             :                                     indxing(:,:),    indxjng(:,:),     &   ! LCOV_EXCL_LINE
     798        5784 :                                     xp,              yp)
     799             : 
     800             :          ! open water
     801             :          call transport_integrals(nx_block,        ny_block,          &
     802             :                                   ntrace,          icellsng (:,iblk), &   ! LCOV_EXCL_LINE
     803             :                                   indxing(:,:),    indxjng(:,:),      &   ! LCOV_EXCL_LINE
     804             :                                   tracer_type,     depend,            &   ! LCOV_EXCL_LINE
     805             :                                   integral_order,  triarea,           &   ! LCOV_EXCL_LINE
     806             :                                   iflux,           jflux,             &   ! LCOV_EXCL_LINE
     807             :                                   xp,              yp,                &   ! LCOV_EXCL_LINE
     808             :                                   mc(:,:,0,iblk),  mx   (:,:,0,iblk), &   ! LCOV_EXCL_LINE
     809        5784 :                                   my(:,:,0,iblk),  mflxn(:,:,0))
     810             : 
     811             :          ! ice categories
     812       34704 :          do n = 1, ncat
     813             :             call transport_integrals                                     &
     814             :                                (nx_block,          ny_block,             &   ! LCOV_EXCL_LINE
     815             :                                 ntrace,            icellsng (:,iblk),    &   ! LCOV_EXCL_LINE
     816             :                                 indxing(:,:),      indxjng(:,:),         &   ! LCOV_EXCL_LINE
     817             :                                 tracer_type,       depend,               &   ! LCOV_EXCL_LINE
     818             :                                 integral_order,    triarea,              &   ! LCOV_EXCL_LINE
     819             :                                 iflux,             jflux,                &   ! LCOV_EXCL_LINE
     820             :                                 xp,                yp,                   &   ! LCOV_EXCL_LINE
     821             :                                 mc(:,:,  n,iblk),  mx    (:,:,  n,iblk), &   ! LCOV_EXCL_LINE
     822             :                                 my(:,:,  n,iblk),  mflxn (:,:,  n),      &   ! LCOV_EXCL_LINE
     823             :                                 tc(:,:,:,n,iblk),  tx    (:,:,:,n,iblk), &   ! LCOV_EXCL_LINE
     824       34704 :                                 ty(:,:,:,n,iblk),  mtflxn(:,:,:,n))
     825             : 
     826             :          enddo                  ! n
     827             : 
     828             :          !-------------------------------------------------------------------
     829             :          ! Update the ice area and tracers.
     830             :          !-------------------------------------------------------------------
     831             : 
     832             :          ! open water
     833             :          call update_fields (nx_block,           ny_block,          &
     834             :                              ilo, ihi,           jlo, jhi,          &   ! LCOV_EXCL_LINE
     835             :                              ntrace,                                &   ! LCOV_EXCL_LINE
     836             :                              tracer_type,        depend,            &   ! LCOV_EXCL_LINE
     837             :                              tarear(:,:,iblk),   l_stop,            &   ! LCOV_EXCL_LINE
     838             :                              istop,              jstop,             &   ! LCOV_EXCL_LINE
     839             :                              mflxe(:,:,0),       mflxn(:,:,0),      &   ! LCOV_EXCL_LINE
     840        5784 :                              mm   (:,:,0,iblk))
     841             : 
     842        5784 :          if (l_stop) then
     843           0 :             call diagnostic_abort(istop,jstop,iblk,'negative area (open water)')
     844             :          endif
     845             : 
     846             :          ! ice categories
     847       40488 :          do n = 1, ncat
     848             : 
     849             :             call update_fields(nx_block,             ny_block,         &
     850             :                                ilo, ihi,             jlo, jhi,         &   ! LCOV_EXCL_LINE
     851             :                                ntrace,                                 &   ! LCOV_EXCL_LINE
     852             :                                tracer_type,          depend,           &   ! LCOV_EXCL_LINE
     853             :                                tarear    (:,:,iblk), l_stop,           &   ! LCOV_EXCL_LINE
     854             :                                istop,                jstop,            &   ! LCOV_EXCL_LINE
     855             :                                mflxe (:,:,  n),      mflxn (:,:,  n),  &   ! LCOV_EXCL_LINE
     856             :                                mm    (:,:,  n,iblk),                   &   ! LCOV_EXCL_LINE
     857             :                                mtflxe(:,:,:,n),      mtflxn(:,:,:,n),  &   ! LCOV_EXCL_LINE
     858       28920 :                                tm    (:,:,:,n,iblk))
     859             : 
     860       34704 :             if (l_stop) then
     861           0 :                write (nu_diag,*) 'istep1, my_task, iblk, cat =',     &
     862           0 :                                   istep1, my_task, iblk, n
     863           0 :                call diagnostic_abort(istop,jstop,iblk,'negative area (ice)')
     864             :             endif
     865             :          enddo                  ! n
     866             : 
     867             :       enddo                     ! iblk
     868             :       !$OMP END PARALLEL DO
     869             : 
     870        5784 :       end subroutine horizontal_remap
     871             : 
     872             : !=======================================================================
     873             : !
     874             : ! Make area and tracer masks.
     875             : !
     876             : ! If an area is masked out (mm < puny), then the values of tracers
     877             : !  in that grid cell are assumed to have no physical meaning.
     878             : !
     879             : ! Similarly, if a tracer with dependents is masked out
     880             : !  (abs(tm) < puny), then the values of its dependent tracers in that
     881             : !  grid cell are assumed to have no physical meaning.
     882             : ! For example, the enthalpy value has no meaning if the thickness
     883             : !  is zero.
     884             : !
     885             : ! author William H. Lipscomb, LANL
     886             : 
     887       22944 :       subroutine make_masks (nx_block,       ny_block, &
     888             :                              ilo, ihi,       jlo, jhi, &   ! LCOV_EXCL_LINE
     889             :                              nghost,         ntrace,   &   ! LCOV_EXCL_LINE
     890             :                              has_dependents,           &   ! LCOV_EXCL_LINE
     891             :                              icells,                   &   ! LCOV_EXCL_LINE
     892             :                              indxi,          indxj,    &   ! LCOV_EXCL_LINE
     893             :                              mm,             mmask,    &   ! LCOV_EXCL_LINE
     894       45888 :                              tm,             tmask)
     895             : 
     896             :       integer (kind=int_kind), intent(in) ::     &
     897             :          nx_block, ny_block, & ! block dimensions   ! LCOV_EXCL_LINE
     898             :          ilo,ihi,jlo,jhi   , & ! beginning and end of physical domain   ! LCOV_EXCL_LINE
     899             :          nghost            , & ! number of ghost cells   ! LCOV_EXCL_LINE
     900             :          ntrace                ! number of tracers in use
     901             : 
     902             : 
     903             :       logical (kind=log_kind), dimension (ntrace), intent(in) ::     &
     904             :          has_dependents        ! true if a tracer has dependent tracers
     905             : 
     906             :       integer (kind=int_kind), dimension(0:ncat), intent(out) ::     &
     907             :          icells                ! number of cells with ice
     908             : 
     909             :       integer (kind=int_kind), dimension(nx_block*ny_block,0:ncat), intent(out) :: &
     910             :          indxi             , & ! compressed i/j indices   ! LCOV_EXCL_LINE
     911             :          indxj
     912             : 
     913             :       real (kind=dbl_kind), dimension (nx_block,ny_block,0:ncat), intent(in) :: &
     914             :          mm                    ! mean ice area in each grid cell
     915             : 
     916             :       real (kind=dbl_kind), dimension (nx_block,ny_block,0:ncat), intent(out) :: &
     917             :          mmask                 ! = 1. if ice is present, else = 0.
     918             : 
     919             :       real (kind=dbl_kind), dimension (nx_block, ny_block, ntrace, ncat), intent(in), optional :: &
     920             :          tm                    ! mean tracer values in each grid cell
     921             : 
     922             :       real (kind=dbl_kind), dimension (nx_block, ny_block, ntrace, ncat), intent(out), optional :: &
     923             :          tmask                 ! = 1. if tracer is present, else = 0.
     924             : 
     925             :       ! local variables
     926             : 
     927             :       integer (kind=int_kind) ::     &
     928             :          i, j, ij          , & ! horizontal indices   ! LCOV_EXCL_LINE
     929             :          n                 , & ! ice category index   ! LCOV_EXCL_LINE
     930             :          nt                    ! tracer index
     931             : 
     932             :       real (kind=dbl_kind) :: &
     933        5760 :          puny                  !
     934             : 
     935             :       character(len=*), parameter :: subname = '(make_masks)'
     936             : 
     937       22944 :       call icepack_query_parameters(puny_out=puny)
     938       22944 :       call icepack_warnings_flush(nu_diag)
     939       22944 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
     940           0 :          file=__FILE__, line=__LINE__)
     941             : 
     942      160608 :       do n = 0, ncat
     943    92757072 :          do ij = 1, nx_block*ny_block
     944    92596464 :             indxi(ij,n) = 0
     945    92734128 :             indxj(ij,n) = 0
     946             :          enddo
     947             :       enddo
     948             : 
     949             :       !-------------------------------------------------------------------
     950             :       ! open water mask
     951             :       !-------------------------------------------------------------------
     952             : 
     953       22944 :       icells(0) = 0
     954      753576 :       do j = 1, ny_block
     955    16186320 :       do i = 1, nx_block
     956    16163376 :          if (mm(i,j,0) > puny) then
     957     8718039 :             mmask(i,j,0) = c1
     958     8718039 :             icells(0) = icells(0) + 1
     959     8718039 :             ij = icells(0)
     960     8718039 :             indxi(ij,0) = i
     961     8718039 :             indxj(ij,0) = j
     962             :          else
     963     6714705 :             mmask(i,j,0) = c0
     964             :          endif
     965             :       enddo
     966             :       enddo
     967             : 
     968      137664 :       do n = 1, ncat
     969             : 
     970             :          !-------------------------------------------------------------------
     971             :          ! Find grid cells where ice is present.
     972             :          !-------------------------------------------------------------------
     973             : 
     974      114720 :          icells(n) = 0
     975     3767880 :          do j = 1, ny_block
     976    80931600 :          do i = 1, nx_block
     977    80816880 :             if (mm(i,j,n) > puny) then
     978    37655263 :                icells(n) = icells(n) + 1
     979    37655263 :                ij = icells(n)
     980    37655263 :                indxi(ij,n) = i
     981    37655263 :                indxj(ij,n) = j
     982             :             endif               ! mm > puny
     983             :          enddo
     984             :          enddo
     985             : 
     986             :          !-------------------------------------------------------------------
     987             :          ! ice area mask
     988             :          !-------------------------------------------------------------------
     989             : 
     990    80931600 :          mmask(:,:,n) = c0
     991    37769983 :          do ij = 1, icells(n)
     992    37655263 :             i = indxi(ij,n)
     993    37655263 :             j = indxj(ij,n)
     994    37769983 :             mmask(i,j,n) = c1
     995             :          enddo
     996             : 
     997             :          !-------------------------------------------------------------------
     998             :          ! tracer masks
     999             :          !-------------------------------------------------------------------
    1000             : 
    1001      114720 :          if (present(tm)) then
    1002             : 
    1003  2104336320 :             tmask(:,:,:,n) = c0
    1004             : 
    1005     3097440 :             do nt = 1, ntrace
    1006     3097440 :                if (has_dependents(nt)) then
    1007   151079932 :                   do ij = 1, icells(n)
    1008   150621052 :                      i = indxi(ij,n)
    1009   150621052 :                      j = indxj(ij,n)
    1010   151079932 :                      if (abs(tm(i,j,nt,n)) > puny) then
    1011   105244210 :                         tmask(i,j,nt,n) = c1
    1012             :                      endif
    1013             :                   enddo
    1014             :                endif
    1015             :             enddo
    1016             : 
    1017             :          endif                     ! present(tm)
    1018             : 
    1019             :          !-------------------------------------------------------------------
    1020             :          ! Redefine icells
    1021             :          ! For nghost = 1, exclude ghost cells
    1022             :          ! For nghost = 2, include one layer of ghost cells
    1023             :          !-------------------------------------------------------------------
    1024             : 
    1025      114720 :          icells(n) = 0
    1026     3561384 :          do j = jlo-nghost+1, jhi+nghost-1
    1027    69134640 :          do i = ilo-nghost+1, ihi+nghost-1
    1028    69019920 :             if (mm(i,j,n) > puny) then
    1029    33882955 :                icells(n) = icells(n) + 1
    1030    33882955 :                ij = icells(n)
    1031    33882955 :                indxi(ij,n) = i
    1032    33882955 :                indxj(ij,n) = j
    1033             :             endif               ! mm > puny
    1034             :          enddo
    1035             :          enddo
    1036             : 
    1037             :       enddo ! n
    1038             : 
    1039       68832 :       end subroutine make_masks
    1040             : 
    1041             : !=======================================================================
    1042             : !
    1043             : ! Construct fields of ice area and tracers.
    1044             : !
    1045             : ! authors William H. Lipscomb, LANL
    1046             : !         John R. Baumgardner, LANL
    1047             : 
    1048      137664 :       subroutine construct_fields (nx_block,       ny_block,   &
    1049             :                                    ilo, ihi,       jlo, jhi,   &   ! LCOV_EXCL_LINE
    1050             :                                    nghost,         ntrace,     &   ! LCOV_EXCL_LINE
    1051             :                                    tracer_type,    depend,     &   ! LCOV_EXCL_LINE
    1052             :                                    has_dependents, icells,     &   ! LCOV_EXCL_LINE
    1053             :                                    indxi,          indxj,      &   ! LCOV_EXCL_LINE
    1054             :                                    hm,             xav,        &   ! LCOV_EXCL_LINE
    1055             :                                    yav,            xxav,       &   ! LCOV_EXCL_LINE
    1056             :                                    yyav,       &   ! LCOV_EXCL_LINE
    1057             : !                                   xyav,      &   ! LCOV_EXCL_LINE
    1058             : !                                   xxxav,          xxyav,      &   ! LCOV_EXCL_LINE
    1059             : !                                   xyyav,          yyyav,      &   ! LCOV_EXCL_LINE
    1060             :                                    mm,             mc,         &   ! LCOV_EXCL_LINE
    1061             :                                    mx,             my,         &   ! LCOV_EXCL_LINE
    1062             :                                    mmask,                      &   ! LCOV_EXCL_LINE
    1063             :                                    tm,             tc,         &   ! LCOV_EXCL_LINE
    1064             :                                    tx,             ty,         &   ! LCOV_EXCL_LINE
    1065      114720 :                                    tmask)
    1066             : 
    1067             :       integer (kind=int_kind), intent(in) ::   &
    1068             :          nx_block, ny_block, & ! block dimensions   ! LCOV_EXCL_LINE
    1069             :          ilo,ihi,jlo,jhi   , & ! beginning and end of physical domain   ! LCOV_EXCL_LINE
    1070             :          nghost            , & ! number of ghost cells   ! LCOV_EXCL_LINE
    1071             :          ntrace            , & ! number of tracers in use   ! LCOV_EXCL_LINE
    1072             :          icells                ! number of cells with mass
    1073             : 
    1074             :       integer (kind=int_kind), dimension (ntrace), intent(in) ::     &
    1075             :          tracer_type       , & ! = 1, 2, or 3 (see comments above)   ! LCOV_EXCL_LINE
    1076             :          depend                ! tracer dependencies (see above)
    1077             : 
    1078             :       logical (kind=log_kind), dimension (ntrace), intent(in) ::     &
    1079             :          has_dependents        ! true if a tracer has dependent tracers
    1080             : 
    1081             :       integer (kind=int_kind), dimension(nx_block*ny_block), intent(in) :: &
    1082             :          indxi             , & ! compressed i/j indices   ! LCOV_EXCL_LINE
    1083             :          indxj
    1084             : 
    1085             :       real (kind=dbl_kind), dimension (nx_block,ny_block), intent(in) ::   &
    1086             :          hm                , & ! land/boundary mask, thickness (T-cell)   ! LCOV_EXCL_LINE
    1087             :          xav,  yav         , & ! mean T-cell values of x, y   ! LCOV_EXCL_LINE
    1088             :          xxav, yyav            ! mean T-cell values of xx, yy
    1089             : !         xyav,             , & ! mean T-cell values of xy
    1090             : !         xxxav,xxyav,xyyav,yyyav ! mean T-cell values of xxx, xxy, xyy, yyy
    1091             : 
    1092             :       real (kind=dbl_kind), dimension (nx_block,ny_block), intent(in) ::   &
    1093             :          mm                , & ! mean value of mass field   ! LCOV_EXCL_LINE
    1094             :          mmask                 ! = 1. if ice is present, = 0. otherwise
    1095             : 
    1096             :       real (kind=dbl_kind), dimension (nx_block,ny_block,ntrace), intent(in), optional ::   &
    1097             :          tm                , & ! mean tracer   ! LCOV_EXCL_LINE
    1098             :          tmask                 ! = 1. if tracer is present, = 0. otherwise
    1099             : 
    1100             :       real (kind=dbl_kind), dimension (nx_block,ny_block), intent(out) ::   &
    1101             :          mc                , & ! mass value at geometric center of cell   ! LCOV_EXCL_LINE
    1102             :          mx, my                ! limited derivative of mass wrt x and y
    1103             : 
    1104             :       real (kind=dbl_kind), dimension (nx_block,ny_block,ntrace), intent(out), optional ::   &
    1105             :          tc                , & ! tracer at geometric center of cell   ! LCOV_EXCL_LINE
    1106             :          tx, ty                ! limited derivative of tracer wrt x and y
    1107             : 
    1108             :       ! local variables
    1109             : 
    1110             :       integer (kind=int_kind) ::   &
    1111             :          i, j              , & ! horizontal indices   ! LCOV_EXCL_LINE
    1112             :          nt, nt1           , & ! tracer indices   ! LCOV_EXCL_LINE
    1113             :          ij                    ! combined i/j horizontal index
    1114             : 
    1115             :       real (kind=dbl_kind), dimension (nx_block,ny_block) ::    &
    1116             :          mxav              , & ! x coordinate of center of mass   ! LCOV_EXCL_LINE
    1117    30238848 :          myav                  ! y coordinate of center of mass
    1118             : 
    1119             :       real (kind=dbl_kind), dimension (nx_block,ny_block,ntrace) ::  &
    1120             :          mtxav             , & ! x coordinate of center of mass*tracer   ! LCOV_EXCL_LINE
    1121   781089408 :          mtyav                 ! y coordinate of center of mass*tracer
    1122             : 
    1123             :       real (kind=dbl_kind) ::   &
    1124             :          puny, &   ! LCOV_EXCL_LINE
    1125       34560 :          w1, w2, w3, w7        ! work variables
    1126             : 
    1127             :       character(len=*), parameter :: subname = '(construct_fields)'
    1128             : 
    1129             :       !-------------------------------------------------------------------
    1130             :       ! Compute field values at the geometric center of each grid cell,
    1131             :       ! and compute limited gradients in the x and y directions.
    1132             :       !
    1133             :       ! For second order accuracy, each state variable is approximated as
    1134             :       ! a field varying linearly over x and y within each cell.  For each
    1135             :       ! category, the integrated value of m(x,y) over the cell must
    1136             :       ! equal mm(i,j,n)*tarea(i,j), where tarea(i,j) is the cell area.
    1137             :       ! Similarly, the integrated value of m(x,y)*t(x,y) must equal
    1138             :       ! the total mass*tracer, mm(i,j,n)*tm(i,j,n)*tarea(i,j).
    1139             :       !
    1140             :       ! These integral conditions are satisfied for linear fields if we
    1141             :       ! stipulate the following:
    1142             :       ! (1) The mean mass, mm, is equal to the mass at the cell centroid.
    1143             :       ! (2) The mean value tm1 of type 1 tracers is equal to the value
    1144             :       !     at the center of mass.
    1145             :       ! (3) The mean value tm2 of type 2 tracers is equal to the value
    1146             :       !     at the center of mass*tm1, where tm2 depends on tm1.
    1147             :       !     (See comments at the top of the module.)
    1148             :       !
    1149             :       ! We want to find the value of each state variable at a standard
    1150             :       ! reference point, which we choose to be the geometric center of
    1151             :       ! the cell.  The geometric center is located at the intersection
    1152             :       ! of the line joining the midpoints of the north and south edges
    1153             :       ! with the line joining the midpoints of the east and west edges.
    1154             :       ! To find the value at the geometric center, we must know the
    1155             :       ! location of the cell centroid/center of mass, along with the
    1156             :       ! mean value and the gradients with respect to x and y.
    1157             :       !
    1158             :       ! The cell gradients are first computed from the difference between
    1159             :       ! values in the neighboring cells, then limited by requiring that
    1160             :       ! no new extrema are created within the cell.
    1161             :       !
    1162             :       ! For rectangular coordinates the centroid and the geometric
    1163             :       ! center coincide, which means that some of the equations in this
    1164             :       ! subroutine could be simplified.  However, the full equations
    1165             :       ! are retained for generality.
    1166             :       !-------------------------------------------------------------------
    1167             : 
    1168             :       !-------------------------------------------------------------------
    1169             :       ! Initialize
    1170             :       !-------------------------------------------------------------------
    1171             : 
    1172      137664 :       call icepack_query_parameters(puny_out=puny)
    1173      137664 :       call icepack_warnings_flush(nu_diag)
    1174      137664 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    1175           0 :          file=__FILE__, line=__LINE__)
    1176             : 
    1177     4521456 :       do j = 1, ny_block
    1178    97117920 :       do i = 1, nx_block
    1179    92596464 :          mc(i,j)  = c0
    1180    92596464 :          mx(i,j)  = c0
    1181    92596464 :          my(i,j)  = c0
    1182    92596464 :          mxav(i,j) = c0
    1183    96980256 :          myav(i,j) = c0
    1184             :       enddo
    1185             :       enddo
    1186             : 
    1187      137664 :       if (present(tm)) then
    1188     3097440 :          do nt = 1, ntrace
    1189    98079600 :             do j = 1, ny_block
    1190  2104221600 :             do i = 1, nx_block
    1191  2006256720 :                tc(i,j,nt) = c0
    1192  2006256720 :                tx(i,j,nt) = c0
    1193  2101238880 :                ty(i,j,nt) = c0
    1194             :             enddo
    1195             :             enddo
    1196             :          enddo
    1197             :       endif
    1198             : 
    1199             :       ! limited gradient of mass field in each cell (except masked cells)
    1200             :       ! Note: The gradient is computed in scaled coordinates with
    1201             :       !       dxT = dyT = hte = htn = 1.
    1202             : 
    1203             :       call limited_gradient (nx_block, ny_block,   &
    1204             :                              ilo, ihi, jlo, jhi,   &   ! LCOV_EXCL_LINE
    1205             :                              nghost,               &   ! LCOV_EXCL_LINE
    1206             :                              mm,       hm,         &   ! LCOV_EXCL_LINE
    1207             :                              xav,      yav,        &   ! LCOV_EXCL_LINE
    1208      137664 :                              mx,       my)
    1209             : 
    1210    42738658 :       do ij = 1,icells   ! ice is present
    1211    42600994 :          i = indxi(ij)
    1212    42600994 :          j = indxj(ij)
    1213             : 
    1214             :          ! mass field at geometric center
    1215             :          ! echmod: xav = yav = 0
    1216    42738658 :          mc(i,j) = mm(i,j)
    1217             : 
    1218             : !         mc(i,j) = mm(i,j) - xav(i,j)*mx(i,j)   &
    1219             : !                           - yav(i,j)*my(i,j)
    1220             : 
    1221             :       enddo                     ! ij
    1222             : 
    1223             :       ! tracers
    1224             : 
    1225      137664 :       if (present(tm)) then
    1226             : 
    1227    33997675 :          do ij = 1,icells       ! cells with mass
    1228    33882955 :             i = indxi(ij)
    1229    33882955 :             j = indxj(ij)
    1230             : 
    1231             :             ! center of mass (mxav,myav) for each cell
    1232             :             ! echmod: xyav = 0
    1233     3085762 :             mxav(i,j) = (mx(i,j)*xxav(i,j)    &
    1234    33882955 :                        + mc(i,j)*xav (i,j)) / mm(i,j)
    1235     3085762 :             myav(i,j) = (my(i,j)*yyav(i,j)    &
    1236    33997675 :                        + mc(i,j)*yav(i,j)) / mm(i,j)
    1237             : 
    1238             : !            mxav(i,j) = (mx(i,j)*xxav(i,j)    &
    1239             : !                       + my(i,j)*xyav(i,j)    &   ! LCOV_EXCL_LINE
    1240             : !                       + mc(i,j)*xav (i,j)) / mm(i,j)
    1241             : !            myav(i,j) = (mx(i,j)*xyav(i,j)    &
    1242             : !                       + my(i,j)*yyav(i,j)    &   ! LCOV_EXCL_LINE
    1243             : !                       + mc(i,j)*yav(i,j)) / mm(i,j)
    1244             :          enddo
    1245             : 
    1246     3097440 :          do nt = 1, ntrace
    1247             : 
    1248     3097440 :             if (tracer_type(nt)==1) then ! independent of other tracers
    1249             : 
    1250             :                call limited_gradient(nx_block,     ny_block,  &
    1251             :                                      ilo, ihi,     jlo, jhi,  &   ! LCOV_EXCL_LINE
    1252             :                                      nghost,                  &   ! LCOV_EXCL_LINE
    1253             :                                      tm(:,:,nt),   mmask,     &   ! LCOV_EXCL_LINE
    1254             :                                      mxav,         myav,      &   ! LCOV_EXCL_LINE
    1255      688320 :                                      tx(:,:,nt),   ty(:,:,nt))
    1256             : 
    1257      688320 :                if (has_dependents(nt)) then   ! need center of area*tracer
    1258             : 
    1259    11303640 :                   do j = 1, ny_block
    1260   242794800 :                   do i = 1, nx_block
    1261   231491160 :                      mtxav(i,j,nt) = c0
    1262   242450640 :                      mtyav(i,j,nt) = c0
    1263             :                   enddo
    1264             :                   enddo
    1265             : 
    1266   101993025 :                   do ij = 1, icells  ! Note: no tx or ty in ghost cells
    1267             :                                      ! (bound calls are later)
    1268   101648865 :                      i = indxi(ij)
    1269   101648865 :                      j = indxj(ij)
    1270             : 
    1271             :                      ! tracer value at geometric center
    1272     9257286 :                      tc(i,j,nt) = tm(i,j,nt) - tx(i,j,nt)*mxav(i,j)   &
    1273   101648865 :                                              - ty(i,j,nt)*myav(i,j)
    1274             : 
    1275   101993025 :                      if (tmask(i,j,nt) > puny) then
    1276             : 
    1277             :                         ! center of area*tracer
    1278    82794204 :                         w1 = mc(i,j)*tc(i,j,nt)
    1279     9056294 :                         w2 = mc(i,j)*tx(i,j,nt)   &
    1280    82794204 :                            + mx(i,j)*tc(i,j,nt)
    1281     9056294 :                         w3 = mc(i,j)*ty(i,j,nt)   &
    1282    82794204 :                            + my(i,j)*tc(i,j,nt)
    1283             : !                        w4 = mx(i,j)*tx(i,j,nt)
    1284             : !                        w5 = mx(i,j)*ty(i,j,nt)   &
    1285             : !                           + my(i,j)*tx(i,j,nt)
    1286             : !                        w6 = my(i,j)*ty(i,j,nt)
    1287    82794204 :                         w7 = c1 / (mm(i,j)*tm(i,j,nt))
    1288             :                         ! echmod: grid arrays = 0
    1289     9056294 :                         mtxav(i,j,nt) = (w1*xav (i,j)  + w2*xxav (i,j))   &
    1290    82794204 :                                        * w7
    1291     9056294 :                         mtyav(i,j,nt) = (w1*yav(i,j)   + w3*yyav(i,j)) &
    1292    82794204 :                                        * w7
    1293             : 
    1294             : !                        mtxav(i,j,nt) = (w1*xav (i,j)  + w2*xxav (i,j)   &
    1295             : !                                       + w3*xyav (i,j) + w4*xxxav(i,j)   &   ! LCOV_EXCL_LINE
    1296             : !                                       + w5*xxyav(i,j) + w6*xyyav(i,j))  &   ! LCOV_EXCL_LINE
    1297             : !                                       * w7
    1298             : !                        mtyav(i,j,nt) = (w1*yav(i,j)   + w2*xyav (i,j)   &
    1299             : !                                       + w3*yyav(i,j)  + w4*xxyav(i,j)   &   ! LCOV_EXCL_LINE
    1300             : !                                       + w5*xyyav(i,j) + w6*yyyav(i,j))  &   ! LCOV_EXCL_LINE
    1301             : !                                       * w7
    1302             :                      endif         ! tmask
    1303             : 
    1304             :                   enddo            ! ij
    1305             : 
    1306             :                else                ! no dependents
    1307             : 
    1308   101993025 :                   do ij = 1, icells      ! mass is present
    1309   101648865 :                      i = indxi(ij)
    1310   101648865 :                      j = indxj(ij)
    1311             : 
    1312             :                      ! tracer value at geometric center
    1313     9257286 :                      tc(i,j,nt) = tm(i,j,nt) - tx(i,j,nt)*mxav(i,j)   &
    1314   101993025 :                                              - ty(i,j,nt)*myav(i,j)
    1315             :                   enddo            ! ij
    1316             : 
    1317             :                endif               ! has_dependents
    1318             : 
    1319     2294400 :             elseif (tracer_type(nt)==2) then   ! tracer nt depends on nt1
    1320     2064960 :                nt1 = depend(nt)
    1321             : 
    1322             :                call limited_gradient(nx_block,       ny_block,         &
    1323             :                                      ilo, ihi,       jlo, jhi,         &   ! LCOV_EXCL_LINE
    1324             :                                      nghost,                           &   ! LCOV_EXCL_LINE
    1325             :                                      tm   (:,:,nt),  tmask(:,:,nt1),   &   ! LCOV_EXCL_LINE
    1326             :                                      mtxav(:,:,nt1), mtyav(:,:,nt1),   &   ! LCOV_EXCL_LINE
    1327     2064960 :                                      tx   (:,:,nt),  ty   (:,:,nt))
    1328             : 
    1329   611958150 :                do ij = 1, icells     ! ice is present
    1330   609893190 :                   i = indxi(ij)
    1331   609893190 :                   j = indxj(ij)
    1332    55543716 :                   tc(i,j,nt) = tm(i,j,nt)                    &
    1333             :                              - tx(i,j,nt) * mtxav(i,j,nt1)   &   ! LCOV_EXCL_LINE
    1334   611958150 :                              - ty(i,j,nt) * mtyav(i,j,nt1)
    1335             :                enddo               ! ij
    1336             : 
    1337      229440 :             elseif (tracer_type(nt)==3) then  ! upwind approx; gradient = 0
    1338             : 
    1339    67995350 :                do ij = 1, icells
    1340    67765910 :                   i = indxi(ij)
    1341    67765910 :                   j = indxj(ij)
    1342             : 
    1343    67995350 :                   tc(i,j,nt) = tm(i,j,nt)
    1344             : !                  tx(i,j,nt) = c0   ! already initialized to 0.
    1345             : !                  ty(i,j,nt) = c0
    1346             :                enddo               ! ij
    1347             : 
    1348             :             endif                  ! tracer_type
    1349             : 
    1350             :          enddo                    ! ntrace
    1351             : 
    1352             :       endif                     ! present (tm)
    1353             : 
    1354      596544 :       end subroutine construct_fields
    1355             : 
    1356             : !=======================================================================
    1357             : !
    1358             : ! Compute a limited gradient of the scalar field phi in scaled coordinates.
    1359             : ! "Limited" means that we do not create new extrema in phi.  For
    1360             : ! instance, field values at the cell corners can neither exceed the
    1361             : ! maximum of phi(i,j) in the cell and its eight neighbors, nor fall
    1362             : ! below the minimum.
    1363             : !
    1364             : ! authors William H. Lipscomb, LANL
    1365             : !         John R. Baumgardner, LANL
    1366             : 
    1367     2890944 :       subroutine limited_gradient (nx_block, ny_block,   &
    1368             :                                    ilo, ihi, jlo, jhi,   &   ! LCOV_EXCL_LINE
    1369             :                                    nghost,               &   ! LCOV_EXCL_LINE
    1370             :                                    phi,      phimask,    &   ! LCOV_EXCL_LINE
    1371             :                                    cnx,      cny,        &   ! LCOV_EXCL_LINE
    1372     2890944 :                                    gx,       gy)
    1373             : 
    1374             :       integer (kind=int_kind), intent(in) ::   &
    1375             :          nx_block, ny_block, & ! block dimensions   ! LCOV_EXCL_LINE
    1376             :          ilo,ihi,jlo,jhi   , & ! beginning and end of physical domain   ! LCOV_EXCL_LINE
    1377             :          nghost                ! number of ghost cells
    1378             : 
    1379             :       real (kind=dbl_kind), dimension (nx_block,ny_block), intent (in) ::   &
    1380             :          phi      , & ! input tracer field (mean values in each grid cell)   ! LCOV_EXCL_LINE
    1381             :          cnx      , & ! x-coordinate of phi relative to geometric center of cell   ! LCOV_EXCL_LINE
    1382             :          cny      , & ! y-coordinate of phi relative to geometric center of cell   ! LCOV_EXCL_LINE
    1383             :          phimask      ! phimask(i,j) = 1 if phi(i,j) has physical meaning, = 0 otherwise.
    1384             :                       ! For instance, aice has no physical meaning in land cells,
    1385             :                       ! and hice no physical meaning where aice = 0.
    1386             : 
    1387             :       real (kind=dbl_kind), dimension (nx_block,ny_block), intent(out) ::   &
    1388             :          gx       , & ! limited x-direction gradient   ! LCOV_EXCL_LINE
    1389             :          gy           ! limited y-direction gradient
    1390             : 
    1391             :       ! local variables
    1392             : 
    1393             :       integer (kind=int_kind) ::   &
    1394             :          i, j, ij , & ! standard indices   ! LCOV_EXCL_LINE
    1395             :          icells       ! number of cells to limit
    1396             : 
    1397             :       integer (kind=int_kind), dimension(nx_block*ny_block) ::   &
    1398     5781888 :          indxi, indxj ! combined i/j horizontal indices
    1399             : 
    1400             :       real (kind=dbl_kind) ::   &
    1401             :          phi_nw, phi_n, phi_ne , & ! values of phi in 8 neighbor cells   ! LCOV_EXCL_LINE
    1402             :          phi_w,         phi_e  , &   ! LCOV_EXCL_LINE
    1403             :          phi_sw, phi_s, phi_se , &   ! LCOV_EXCL_LINE
    1404             :          qmn, qmx              , & ! min and max value of phi within grid cell   ! LCOV_EXCL_LINE
    1405             :          pmn, pmx              , & ! min and max value of phi among neighbor cells   ! LCOV_EXCL_LINE
    1406      725760 :          w1, w2, w3, w4            ! work variables
    1407             : 
    1408             :       real (kind=dbl_kind) ::   &
    1409             :          puny        , & !   ! LCOV_EXCL_LINE
    1410      725760 :          gxtmp, gytmp    ! temporary term for x- and y- limited gradient
    1411             : 
    1412             :       character(len=*), parameter :: subname = '(limited_gradient)'
    1413             : 
    1414     2890944 :       call icepack_query_parameters(puny_out=puny)
    1415     2890944 :       call icepack_warnings_flush(nu_diag)
    1416     2890944 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    1417           0 :          file=__FILE__, line=__LINE__)
    1418             : 
    1419  2039476320 :       gx(:,:) = c0
    1420  2039476320 :       gy(:,:) = c0
    1421             : 
    1422             :       ! For nghost = 1, loop over physical cells and update ghost cells later
    1423             :       ! For nghost = 2, loop over a layer of ghost cells and skip the update
    1424             : 
    1425     2890944 :       icells = 0
    1426    89168688 :       do j = jlo-nghost+1, jhi+nghost-1
    1427  1742192928 :       do i = ilo-nghost+1, ihi+nghost-1
    1428  1739301984 :          if (phimask(i,j) > puny) then
    1429   858654723 :             icells = icells + 1
    1430   858654723 :             indxi(icells) = i
    1431   858654723 :             indxj(icells) = j
    1432             :          endif                  ! phimask > puny
    1433             :       enddo
    1434             :       enddo
    1435             : 
    1436   861545667 :       do ij = 1, icells
    1437   858654723 :          i = indxi(ij)
    1438   858654723 :          j = indxj(ij)
    1439             : 
    1440             :          ! Store values of phi in the 8 neighbor cells.
    1441             :          ! Note: phimask = 1. or 0.  If phimask = 1., use the true value;
    1442             :          !  if phimask = 0., use the home cell value so that non-physical
    1443             :          !  values of phi do not contribute to the gradient.
    1444   364601024 :          phi_nw = phimask(i-1,j+1) * phi(i-1,j+1)  &
    1445  1223255747 :             + (c1-phimask(i-1,j+1))* phi(i  ,j  )
    1446   182300512 :          phi_n  = phimask(i  ,j+1) * phi(i  ,j+1)  &
    1447  1040955235 :             + (c1-phimask(i  ,j+1))* phi(i  ,j  )
    1448   364601024 :          phi_ne = phimask(i+1,j+1) * phi(i+1,j+1)  &
    1449  1223255747 :             + (c1-phimask(i+1,j+1))* phi(i  ,j  )
    1450   273450768 :          phi_w  = phimask(i-1,j  ) * phi(i-1,j  )  &
    1451  1040955235 :             + (c1-phimask(i-1,j  ))* phi(i  ,j  )
    1452   273450768 :          phi_e  = phimask(i+1,j  ) * phi(i+1,j  )  &
    1453  1040955235 :             + (c1-phimask(i+1,j  ))* phi(i  ,j  )
    1454   364601024 :          phi_sw = phimask(i-1,j-1) * phi(i-1,j-1)  &
    1455  1223255747 :             + (c1-phimask(i-1,j-1))* phi(i  ,j  )
    1456   182300512 :          phi_s  = phimask(i  ,j-1) * phi(i  ,j-1)  &
    1457  1040955235 :             + (c1-phimask(i  ,j-1))* phi(i  ,j  )
    1458   364601024 :          phi_se = phimask(i+1,j-1) * phi(i+1,j-1)  &
    1459  1223255747 :             + (c1-phimask(i+1,j-1))* phi(i  ,j  )
    1460             : 
    1461             :          ! unlimited gradient components
    1462             :          ! (factors of two cancel out)
    1463             : 
    1464   858654723 :          gxtmp = (phi_e - phi_w) * p5
    1465   858654723 :          gytmp = (phi_n - phi_s) * p5
    1466             : 
    1467             :          ! minimum and maximum among the nine local cells
    1468    91150256 :          pmn = min (phi_nw, phi_n,  phi_ne, phi_w, phi(i,j),   &
    1469   858654723 :                     phi_e,  phi_sw, phi_s,  phi_se)
    1470    91150256 :          pmx = max (phi_nw, phi_n,  phi_ne, phi_w, phi(i,j),   &
    1471   858654723 :                     phi_e,  phi_sw, phi_s,  phi_se)
    1472             : 
    1473   858654723 :          pmn = pmn - phi(i,j)
    1474   858654723 :          pmx = pmx - phi(i,j)
    1475             : 
    1476             :          ! minimum and maximum deviation of phi within the cell
    1477    91150256 :          w1  =  (p5 - cnx(i,j)) * gxtmp   &
    1478   858654723 :               + (p5 - cny(i,j)) * gytmp
    1479    91150256 :          w2  =  (p5 - cnx(i,j)) * gxtmp   &
    1480   858654723 :               - (p5 + cny(i,j)) * gytmp
    1481    91150256 :          w3  = -(p5 + cnx(i,j)) * gxtmp   &
    1482   858654723 :               - (p5 + cny(i,j)) * gytmp
    1483    91150256 :          w4  =  (p5 - cny(i,j)) * gytmp   &
    1484   858654723 :               - (p5 + cnx(i,j)) * gxtmp
    1485             : 
    1486   858654723 :          qmn = min (w1, w2, w3, w4)
    1487   858654723 :          qmx = max (w1, w2, w3, w4)
    1488             : 
    1489             :          ! the limiting coefficient
    1490   858654723 :          if ( abs(qmn) > abs(pmn) ) then ! 'abs(qmn) > puny' not sufficient
    1491    86773338 :             w1 = max(c0, pmn/qmn)
    1492             :          else
    1493   771881385 :             w1 = c1
    1494             :          endif
    1495             : 
    1496   858654723 :          if ( abs(qmx) > abs(pmx) ) then
    1497    65479305 :             w2 = max(c0, pmx/qmx)
    1498             :          else
    1499   793175418 :             w2 = c1
    1500             :          endif
    1501             : 
    1502   858654723 :          w1 = min(w1, w2)
    1503             : 
    1504             :          ! Limit the gradient components
    1505   858654723 :          gx(i,j) = w1 * gxtmp
    1506   861545667 :          gy(i,j) = w1 * gytmp
    1507             : 
    1508             :       enddo                     ! ij
    1509             : 
    1510     2890944 :       end subroutine limited_gradient
    1511             : 
    1512             : !=======================================================================
    1513             : !
    1514             : ! Given velocity fields on cell corners, compute departure points
    1515             : ! of back trajectories in nondimensional coordinates.
    1516             : !
    1517             : ! author William H. Lipscomb, LANL
    1518             : 
    1519       22944 :       subroutine departure_points (nx_block,   ny_block,   &
    1520             :                                    ilo, ihi,   jlo, jhi,   &   ! LCOV_EXCL_LINE
    1521             :                                    nghost,     dt,   &   ! LCOV_EXCL_LINE
    1522             :                                    uvel,       vvel,    &   ! LCOV_EXCL_LINE
    1523             :                                    dxu,        dyu,     &   ! LCOV_EXCL_LINE
    1524             :                                    HTN,        HTE,     &   ! LCOV_EXCL_LINE
    1525             :                                    dpx,        dpy,     &   ! LCOV_EXCL_LINE
    1526             :                                    l_dp_midpt, l_stop,   &   ! LCOV_EXCL_LINE
    1527             :                                    istop,      jstop)
    1528             : 
    1529             :       integer (kind=int_kind), intent(in) ::   &
    1530             :          nx_block, ny_block, & ! block dimensions   ! LCOV_EXCL_LINE
    1531             :          ilo,ihi,jlo,jhi,    & ! beginning and end of physical domain   ! LCOV_EXCL_LINE
    1532             :          nghost                ! number of ghost cells
    1533             : 
    1534             :       real (kind=dbl_kind), intent(in) ::   &
    1535             :          dt               ! time step (s)
    1536             : 
    1537             :       real (kind=dbl_kind), dimension (nx_block,ny_block), intent(in) ::   &
    1538             :          uvel         , & ! x-component of velocity (m/s)   ! LCOV_EXCL_LINE
    1539             :          vvel         , & ! y-component of velocity (m/s)   ! LCOV_EXCL_LINE
    1540             :          dxu          , & ! E-W dimensions of U-cell (m)   ! LCOV_EXCL_LINE
    1541             :          dyu          , & ! N-S dimensions of U-cell (m)   ! LCOV_EXCL_LINE
    1542             :          HTN          , & ! length of north face of T-cell (m)   ! LCOV_EXCL_LINE
    1543             :          HTE              ! length of east face of T-cell (m)
    1544             : 
    1545             :       real (kind=dbl_kind), dimension (nx_block,ny_block), intent(out) ::   &
    1546             :          dpx          , & ! coordinates of departure points (m)   ! LCOV_EXCL_LINE
    1547             :          dpy              ! coordinates of departure points (m)
    1548             : 
    1549             :       logical (kind=log_kind), intent(in) ::   &
    1550             :          l_dp_midpt       ! if true, find departure points using
    1551             :                           ! corrected midpoint velocity
    1552             : 
    1553             :       logical (kind=log_kind), intent(inout) ::   &
    1554             :          l_stop           ! if true, abort on return
    1555             : 
    1556             :       integer (kind=int_kind), intent(inout) ::   &
    1557             :          istop, jstop     ! indices of grid cell where model aborts
    1558             : 
    1559             :       ! local variables
    1560             : 
    1561             :       integer (kind=int_kind) ::   &
    1562             :          i, j, i2, j2     ! horizontal indices
    1563             : 
    1564             :       real (kind=dbl_kind) ::                  &
    1565             :          mpx,  mpy    , & ! coordinates of midpoint of back trajectory,   ! LCOV_EXCL_LINE
    1566             :                           ! relative to cell corner
    1567        5760 :          mpxt, mpyt   , & ! midpoint coordinates relative to cell center
    1568        5760 :          ump,  vmp        ! corrected velocity at midpoint
    1569             : 
    1570             :       character(len=*), parameter :: subname = '(departure_points)'
    1571             : 
    1572             :       !-------------------------------------------------------------------
    1573             :       ! Estimate departure points.
    1574             :       ! This estimate is 1st-order accurate in time; improve accuracy by
    1575             :       !  using midpoint approximation (to add later).
    1576             :       ! For nghost = 1, loop over physical cells and update ghost cells later.
    1577             :       ! For nghost = 2, loop over a layer of ghost cells and skip update.
    1578             :       !-------------------------------------------------------------------
    1579             : 
    1580    16186320 :       dpx(:,:) = c0
    1581    16186320 :       dpy(:,:) = c0
    1582             : 
    1583      707688 :       do j = jlo-nghost+1, jhi+nghost-1
    1584    13826928 :       do i = ilo-nghost+1, ihi+nghost-1
    1585             : 
    1586    13119240 :          dpx(i,j) = -dt*uvel(i,j)
    1587    13119240 :          dpy(i,j) = -dt*vvel(i,j)
    1588             : 
    1589             :          ! Check for values out of bounds (more than one grid cell away)
    1590     8352000 :          if (dpx(i,j) < -HTN(i,j) .or. dpx(i,j) > HTN(i+1,j) .or.   &
    1591    17979984 :              dpy(i,j) < -HTE(i,j) .or. dpy(i,j) > HTE(i,j+1)) then
    1592           0 :             l_stop = .true.
    1593           0 :             istop = i
    1594           0 :             jstop = j
    1595             :          endif
    1596             : 
    1597             :       enddo
    1598             :       enddo
    1599             : 
    1600       22944 :       if (l_stop) then
    1601           0 :          i = istop
    1602           0 :          j = jstop
    1603           0 :          write (nu_diag,*) ' '
    1604             :          write (nu_diag,*)   &
    1605           0 :                     'Warning: Departure points out of bounds in remap'
    1606           0 :          write (nu_diag,*) 'my_task, i, j =', my_task, i, j
    1607           0 :          write (nu_diag,*) 'dpx, dpy =', dpx(i,j), dpy(i,j)
    1608           0 :          write (nu_diag,*) 'HTN(i,j), HTN(i+1,j) =', HTN(i,j), HTN(i+1,j)
    1609           0 :          write (nu_diag,*) 'HTE(i,j), HTE(i,j+1) =', HTE(i,j), HTE(i,j+1)
    1610           0 :          return
    1611             :       endif
    1612             : 
    1613       22944 :       if (l_dp_midpt) then ! find dep pts using corrected midpt velocity
    1614             : 
    1615      707688 :          do j = jlo-nghost+1, jhi+nghost-1
    1616    13826928 :          do i = ilo-nghost+1, ihi+nghost-1
    1617    13803984 :             if (uvel(i,j)/=c0 .or. vvel(i,j)/=c0) then
    1618             : 
    1619             :                !-------------------------------------------------------------------
    1620             :                ! Scale departure points to coordinate system in which grid cells
    1621             :                ! have sides of unit length.
    1622             :                !-------------------------------------------------------------------
    1623             : 
    1624     6452519 :                dpx(i,j) = dpx(i,j) / dxu(i,j)
    1625     6452519 :                dpy(i,j) = dpy(i,j) / dyu(i,j)
    1626             : 
    1627             :                !-------------------------------------------------------------------
    1628             :                ! Estimate midpoint of backward trajectory relative to corner (i,j).
    1629             :                !-------------------------------------------------------------------
    1630             : 
    1631     6452519 :                mpx = p5 * dpx(i,j)
    1632     6452519 :                mpy = p5 * dpy(i,j)
    1633             : 
    1634             :                !-------------------------------------------------------------------
    1635             :                ! Determine the indices (i2,j2) of the cell where the trajectory lies.
    1636             :                ! Compute the coordinates of the midpoint of the backward trajectory
    1637             :                !  relative to the cell center in a stretch coordinate system
    1638             :                !  with vertices at (1/2, 1/2), (1/2, -1/2), etc.
    1639             :                !-------------------------------------------------------------------
    1640             : 
    1641     6452519 :                if (mpx >= c0 .and. mpy >= c0) then    ! cell (i+1,j+1)
    1642      214554 :                   i2 = i+1
    1643      214554 :                   j2 = j+1
    1644      214554 :                   mpxt = mpx - p5
    1645      214554 :                   mpyt = mpy - p5
    1646     6237965 :                elseif (mpx < c0 .and. mpy < c0) then  ! cell (i,j)
    1647     5198378 :                   i2 = i
    1648     5198378 :                   j2 = j
    1649     5198378 :                   mpxt = mpx + p5
    1650     5198378 :                   mpyt = mpy + p5
    1651     1039587 :                elseif (mpx >= c0 .and. mpy < c0) then ! cell (i+1,j)
    1652      226767 :                   i2 = i+1
    1653      226767 :                   j2 = j
    1654      226767 :                   mpxt = mpx - p5
    1655      226767 :                   mpyt = mpy + p5
    1656      812820 :                elseif (mpx < c0 .and. mpy >= c0) then ! cell (i,j+1)
    1657      812820 :                   i2 = i
    1658      812820 :                   j2 = j+1
    1659      812820 :                   mpxt = mpx + p5
    1660      812820 :                   mpyt = mpy - p5
    1661             :                endif
    1662             : 
    1663             :                !-------------------------------------------------------------------
    1664             :                ! Using a bilinear approximation, estimate the velocity at the
    1665             :                ! trajectory midpoint in the (i2,j2) reference frame.
    1666             :                !-------------------------------------------------------------------
    1667             : 
    1668      944754 :                ump = uvel(i2-1,j2-1)*(mpxt-p5)*(mpyt-p5)     &
    1669             :                    - uvel(i2,  j2-1)*(mpxt+p5)*(mpyt-p5)     &   ! LCOV_EXCL_LINE
    1670             :                    + uvel(i2,  j2  )*(mpxt+p5)*(mpyt+p5)     &   ! LCOV_EXCL_LINE
    1671     7869650 :                    - uvel(i2-1,j2  )*(mpxt-p5)*(mpyt+p5)
    1672             : 
    1673      944754 :                vmp = vvel(i2-1,j2-1)*(mpxt-p5)*(mpyt-p5)     &
    1674             :                    - vvel(i2,  j2-1)*(mpxt+p5)*(mpyt-p5)     &   ! LCOV_EXCL_LINE
    1675             :                    + vvel(i2,  j2  )*(mpxt+p5)*(mpyt+p5)     &   ! LCOV_EXCL_LINE
    1676     7869650 :                    - vvel(i2-1,j2  )*(mpxt-p5)*(mpyt+p5)
    1677             : 
    1678             :                !-------------------------------------------------------------------
    1679             :                ! Use the midpoint velocity to estimate the coordinates of the
    1680             :                !  departure point relative to corner (i,j).
    1681             :                !-------------------------------------------------------------------
    1682             : 
    1683     6452519 :                dpx(i,j) = -dt * ump
    1684     6452519 :                dpy(i,j) = -dt * vmp
    1685             : 
    1686             :             endif               ! nonzero velocity
    1687             : 
    1688             :          enddo                 ! i
    1689             :          enddo                 ! j
    1690             : 
    1691             :       endif                  ! l_dp_midpt
    1692             : 
    1693             :       end subroutine departure_points
    1694             : 
    1695             : !=======================================================================
    1696             : !
    1697             : ! Compute areas and vertices of transport triangles for north or
    1698             : !  east cell edges.
    1699             : !
    1700             : ! authors William H. Lipscomb, LANL
    1701             : !         John R. Baumgardner, LANL
    1702             : 
    1703       45888 :       subroutine locate_triangles (nx_block,     ny_block,   &
    1704             :                                    ilo, ihi,     jlo, jhi,   &   ! LCOV_EXCL_LINE
    1705             :                                    nghost,       edge,       &   ! LCOV_EXCL_LINE
    1706             :                                    icells,                   &   ! LCOV_EXCL_LINE
    1707             :                                    indxi,        indxj,      &   ! LCOV_EXCL_LINE
    1708             :                                    dpx,          dpy,        &   ! LCOV_EXCL_LINE
    1709             :                                    dxu,          dyu,        &   ! LCOV_EXCL_LINE
    1710             :                                    earea,        narea,      &   ! LCOV_EXCL_LINE
    1711             :                                    xp,           yp,         &   ! LCOV_EXCL_LINE
    1712             :                                    iflux,        jflux,      &   ! LCOV_EXCL_LINE
    1713       45888 :                                    triarea,      edgearea)
    1714             : 
    1715             :       integer (kind=int_kind), intent(in) ::   &
    1716             :          nx_block, ny_block, & ! block dimensions   ! LCOV_EXCL_LINE
    1717             :          ilo,ihi,jlo,jhi   , & ! beginning and end of physical domain   ! LCOV_EXCL_LINE
    1718             :          nghost                ! number of ghost cells
    1719             : 
    1720             :       character (len=char_len), intent(in) ::   &
    1721             :          edge             ! 'north' or 'east'
    1722             : 
    1723             :       real (kind=dbl_kind), dimension(nx_block,ny_block), intent(in) ::  &
    1724             :          dpx          , & ! x coordinates of departure points at cell corners   ! LCOV_EXCL_LINE
    1725             :          dpy          , & ! y coordinates of departure points at cell corners   ! LCOV_EXCL_LINE
    1726             :          dxu          , & ! E-W dimension of U-cell (m)   ! LCOV_EXCL_LINE
    1727             :          dyu          , & ! N-S dimension of U-cell (m)   ! LCOV_EXCL_LINE
    1728             :          earea        , & ! area of E-cell    ! LCOV_EXCL_LINE
    1729             :          narea            ! area of N-cell
    1730             : 
    1731             :       real (kind=dbl_kind), dimension (nx_block,ny_block,0:nvert,ngroups), intent(out) :: &
    1732             :          xp, yp           ! coordinates of triangle vertices
    1733             : 
    1734             :       real (kind=dbl_kind), dimension (nx_block,ny_block,ngroups), intent(out) :: &
    1735             :          triarea          ! area of departure triangle
    1736             : 
    1737             :       integer (kind=int_kind), dimension (nx_block,ny_block,ngroups), intent(out) :: &
    1738             :          iflux        , & ! i index of cell contributing transport   ! LCOV_EXCL_LINE
    1739             :          jflux            ! j index of cell contributing transport
    1740             : 
    1741             :       integer (kind=int_kind), dimension (ngroups), intent(out) ::   &
    1742             :          icells           ! number of cells where triarea > puny
    1743             : 
    1744             :       integer (kind=int_kind), dimension (nx_block*ny_block,ngroups), intent(out) :: &
    1745             :          indxi        , & ! compressed index in i-direction   ! LCOV_EXCL_LINE
    1746             :          indxj            ! compressed index in j-direction
    1747             : 
    1748             :       real (kind=dbl_kind), dimension(nx_block,ny_block), intent(inout) ::   &
    1749             :          edgearea         ! area of departure region for each edge
    1750             :                           ! edgearea > 0 for eastward/northward flow
    1751             : 
    1752             :       ! local variables
    1753             : 
    1754             :       integer (kind=int_kind) ::   &
    1755             :          i, j, ij, ic         , & ! horizontal indices   ! LCOV_EXCL_LINE
    1756             :          ib, jb               , & ! limits for loops for bugcheck   ! LCOV_EXCL_LINE
    1757             :          ng, nv               , & ! triangle indices   ! LCOV_EXCL_LINE
    1758             :          ishift   , jshift    , & ! differences between neighbor cells   ! LCOV_EXCL_LINE
    1759             :          ishift_tl, jshift_tl , & ! i,j indices of TL cell relative to edge   ! LCOV_EXCL_LINE
    1760             :          ishift_bl, jshift_bl , & ! i,j indices of BL cell relative to edge   ! LCOV_EXCL_LINE
    1761             :          ishift_tr, jshift_tr , & ! i,j indices of TR cell relative to edge   ! LCOV_EXCL_LINE
    1762             :          ishift_br, jshift_br , & ! i,j indices of BR cell relative to edge   ! LCOV_EXCL_LINE
    1763             :          ishift_tc, jshift_tc , & ! i,j indices of TC cell relative to edge   ! LCOV_EXCL_LINE
    1764             :          ishift_bc, jshift_bc , & ! i,j indices of BC cell relative to edge   ! LCOV_EXCL_LINE
    1765             :          is_l, js_l           , & ! i,j shifts for TL1, BL2 for area consistency    ! LCOV_EXCL_LINE
    1766             :          is_r, js_r           , & ! i,j shifts for TR1, BR2 for area consistency    ! LCOV_EXCL_LINE
    1767             :          ise_tl, jse_tl       , & ! i,j of TL other edge relative to edge   ! LCOV_EXCL_LINE
    1768             :          ise_bl, jse_bl       , & ! i,j of BL other edge relative to edge   ! LCOV_EXCL_LINE
    1769             :          ise_tr, jse_tr       , & ! i,j of TR other edge relative to edge   ! LCOV_EXCL_LINE
    1770             :          ise_br, jse_br           ! i,j of BR other edge relative to edge
    1771             : 
    1772             :       integer (kind=int_kind) ::   &
    1773             :          icellsd          ! number of cells where departure area > 0.
    1774             : 
    1775             :       integer (kind=int_kind), dimension (nx_block*ny_block) ::  &
    1776             :          indxid       , & ! compressed index in i-direction   ! LCOV_EXCL_LINE
    1777       91776 :          indxjd           ! compressed index in j-direction
    1778             : 
    1779             :       real (kind=dbl_kind), dimension(nx_block,ny_block) ::   &
    1780             :          dx, dy       , & ! scaled departure points   ! LCOV_EXCL_LINE
    1781             :          areafac_c    , & ! earea or narea   ! LCOV_EXCL_LINE
    1782    10079616 :          areafac_ce       ! areafac_c on other edge (narea or earea)
    1783             : 
    1784             :       real (kind=dbl_kind) ::   &
    1785             :          xcl, ycl     , & ! coordinates of left corner point   ! LCOV_EXCL_LINE
    1786             :                           ! (relative to midpoint of edge)
    1787       11520 :          xdl, ydl     , & ! left departure point
    1788             :          xil, yil     , & ! left intersection point   ! LCOV_EXCL_LINE
    1789             :          xcr, ycr     , & ! right corner point   ! LCOV_EXCL_LINE
    1790             :          xdr, ydr     , & ! right departure point   ! LCOV_EXCL_LINE
    1791             :          xir, yir     , & ! right intersection point   ! LCOV_EXCL_LINE
    1792             :          xic, yic     , & ! x-axis intersection point   ! LCOV_EXCL_LINE
    1793             :          xicl, yicl   , & ! left-hand x-axis intersection point   ! LCOV_EXCL_LINE
    1794             :          xicr, yicr   , & ! right-hand x-axis intersection point   ! LCOV_EXCL_LINE
    1795             :          xdm, ydm     , & ! midpoint of segment connecting DL and DR;   ! LCOV_EXCL_LINE
    1796             :                           ! shifted if l_fixed_area = T
    1797       11520 :          md           , & ! slope of line connecting DL and DR
    1798             :          mdl          , & ! slope of line connecting DL and DM   ! LCOV_EXCL_LINE
    1799             :          mdr          , & ! slope of line connecting DR and DM   ! LCOV_EXCL_LINE
    1800             :          area1, area2 , & ! temporary triangle areas   ! LCOV_EXCL_LINE
    1801             :          area3, area4 , & !   ! LCOV_EXCL_LINE
    1802             :          area_c       , & ! center polygon area   ! LCOV_EXCL_LINE
    1803             :          puny         , & !   ! LCOV_EXCL_LINE
    1804       11520 :          w1, w2           ! work variables
    1805             : 
    1806             :       real (kind=dbl_kind), dimension (nx_block,ny_block,ngroups) ::   &
    1807    60145536 :          areafact         ! = 1 for positive flux, -1 for negative
    1808             : 
    1809             :       real (kind=dbl_kind), dimension(nx_block,ny_block) ::   &
    1810    10091136 :          areasum          ! sum of triangle areas for a given edge
    1811             : 
    1812             :       character(len=*), parameter :: subname = '(locate_triangles)'
    1813             : 
    1814             :       !-------------------------------------------------------------------
    1815             :       ! Triangle notation:
    1816             :       ! For each edge, there are 20 triangles that can contribute,
    1817             :       ! but many of these are mutually exclusive.  It turns out that
    1818             :       ! at most 5 triangles can contribute to transport integrals at once.
    1819             :       !
    1820             :       ! See Figure 3 in DB for pictures of these triangles.
    1821             :       ! See Table 1 in DB for logical conditions.
    1822             :       !
    1823             :       ! For the north edge, DB refer to these triangles as:
    1824             :       ! (1) NW, NW1, W, W2
    1825             :       ! (2) NE, NE1, E, E2
    1826             :       ! (3) NW2, W1, NE2, E1
    1827             :       ! (4) H1a, H1b, N1a, N1b
    1828             :       ! (5) H2a, H2b, N2a, N2b
    1829             :       !
    1830             :       ! For the east edge, DB refer to these triangles as:
    1831             :       ! (1) NE, NE1, N, N2
    1832             :       ! (2) SE, SE1, S, S2
    1833             :       ! (3) NE2, N1, SE2, S1
    1834             :       ! (4) H1a, H1b, E1a, E2b
    1835             :       ! (5) H2a, H2b, E2a, E2b
    1836             :       !
    1837             :       ! The code below works for either north or east edges.
    1838             :       ! The respective triangle labels are:
    1839             :       ! (1) TL,  TL1, BL,  BL2
    1840             :       ! (2) TR,  TR1, BR,  BR2
    1841             :       ! (3) TL2, BL1, TR2, BR1
    1842             :       ! (4) BC1a, BC1b, TC1a, TC2b
    1843             :       ! (5) BC2a, BC2b, TC2a, TC2b
    1844             :       !
    1845             :       ! where the cell labels are:
    1846             :       !
    1847             :       !          |        |
    1848             :       !     TL   |   TC   |   TR     (top left, center, right)
    1849             :       !          |        |
    1850             :       !   ------------------------
    1851             :       !          |        |
    1852             :       !     BL   |   BC   |   BR     (bottom left, center, right)
    1853             :       !          |        |
    1854             :       !
    1855             :       ! and the transport is across the edge between cells TC and BC.
    1856             :       !
    1857             :       ! Departure points are scaled to a local coordinate system
    1858             :       !  whose origin is at the midpoint of the edge.
    1859             :       ! In this coordinate system, the lefthand corner CL = (-0.5,0)
    1860             :       !  and the righthand corner CR = (0.5, 0).
    1861             :       !-------------------------------------------------------------------
    1862             : 
    1863             :       !-------------------------------------------------------------------
    1864             :       ! Initialize
    1865             :       !-------------------------------------------------------------------
    1866             : 
    1867       45888 :       call icepack_query_parameters(puny_out=puny)
    1868       45888 :       call icepack_warnings_flush(nu_diag)
    1869       45888 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    1870           0 :          file=__FILE__, line=__LINE__)
    1871             : 
    1872    32372640 :       areafac_c(:,:)  = c0
    1873    32372640 :       areafac_ce(:,:) = c0
    1874             :       
    1875      321216 :       do ng = 1, ngroups
    1876     9042912 :          do j = 1, ny_block
    1877   194235840 :          do i = 1, nx_block
    1878   185192928 :             triarea (i,j,ng) = c0
    1879   185192928 :             areafact(i,j,ng) = c0
    1880   185192928 :             iflux   (i,j,ng) = i
    1881   193960512 :             jflux   (i,j,ng) = j
    1882             :          enddo
    1883             :          enddo
    1884     1422528 :          do nv = 0, nvert
    1885    36446976 :             do j = 1, ny_block
    1886   776943360 :             do i = 1, nx_block
    1887   740771712 :                xp(i,j,nv,ng) = c0
    1888   775842048 :                yp(i,j,nv,ng) = c0
    1889             :             enddo
    1890             :             enddo
    1891             :          enddo
    1892             :       enddo
    1893             : 
    1894       45888 :       if (trim(edge) == 'north') then
    1895             : 
    1896             :          ! index shifts for neighbor cells
    1897             : 
    1898       22944 :          ishift_tl = -1
    1899       22944 :          jshift_tl =  1
    1900       22944 :          ishift_bl = -1
    1901       22944 :          jshift_bl =  0
    1902       22944 :          ishift_tr =  1
    1903       22944 :          jshift_tr =  1
    1904       22944 :          ishift_br =  1
    1905       22944 :          jshift_br =  0
    1906       22944 :          ishift_tc =  0
    1907       22944 :          jshift_tc =  1
    1908       22944 :          ishift_bc =  0
    1909       22944 :          jshift_bc =  0
    1910             : 
    1911             :          ! index shifts for TL1, BL2, TR1 and BR2 for area consistency 
    1912             : 
    1913       22944 :          is_l = -1
    1914       22944 :          js_l =  0
    1915       22944 :          is_r =  1
    1916       22944 :          js_r =  0
    1917             : 
    1918             :          ! index shifts for neighbor east edges
    1919             : 
    1920       22944 :          ise_tl = -1
    1921       22944 :          jse_tl =  1
    1922       22944 :          ise_bl = -1
    1923       22944 :          jse_bl =  0
    1924       22944 :          ise_tr =  0
    1925       22944 :          jse_tr =  1
    1926       22944 :          ise_br =  0
    1927       22944 :          jse_br =  0
    1928             : 
    1929             :          ! area scale factor
    1930             :          ! earea, narea valid on halo
    1931             : 
    1932      753576 :          do j = 1, ny_block
    1933    16186320 :          do i = 1, nx_block
    1934    16163376 :             areafac_c(i,j) = narea(i,j)
    1935             :          enddo
    1936             :          enddo
    1937             : 
    1938             :          ! area scale factor for other edge (east)
    1939             :          
    1940      753576 :          do j = 1, ny_block
    1941    16186320 :          do i = 1, nx_block
    1942    16163376 :             areafac_ce(i,j) = earea(i,j)
    1943             :          enddo
    1944             :          enddo
    1945             : 
    1946             :       else                      ! east edge
    1947             : 
    1948             :          ! index shifts for neighbor cells
    1949             : 
    1950       22944 :          ishift_tl =  1
    1951       22944 :          jshift_tl =  1
    1952       22944 :          ishift_bl =  0
    1953       22944 :          jshift_bl =  1
    1954       22944 :          ishift_tr =  1
    1955       22944 :          jshift_tr = -1
    1956       22944 :          ishift_br =  0
    1957       22944 :          jshift_br = -1
    1958       22944 :          ishift_tc =  1
    1959       22944 :          jshift_tc =  0
    1960       22944 :          ishift_bc =  0
    1961       22944 :          jshift_bc =  0
    1962             : 
    1963             :          ! index shifts for TL1, BL2, TR1 and BR2 for area consistency 
    1964             : 
    1965       22944 :          is_l =  0
    1966       22944 :          js_l =  1
    1967       22944 :          is_r =  0
    1968       22944 :          js_r = -1
    1969             : 
    1970             :          ! index shifts for neighbor north edges
    1971             : 
    1972       22944 :          ise_tl =  1
    1973       22944 :          jse_tl =  0
    1974       22944 :          ise_bl =  0
    1975       22944 :          jse_bl =  0
    1976       22944 :          ise_tr =  1
    1977       22944 :          jse_tr = -1
    1978       22944 :          ise_br =  0
    1979       22944 :          jse_br = -1
    1980             : 
    1981             :          ! area scale factors
    1982             :          ! earea, narea valid on halo
    1983             : 
    1984      753576 :          do j = 1, ny_block
    1985    16186320 :          do i = 1, nx_block
    1986    16163376 :             areafac_c(i,j) = earea(i,j)
    1987             :          enddo
    1988             :          enddo
    1989             : 
    1990             :          ! area scale factor for other edge (north)
    1991             : 
    1992      753576 :          do j = 1, ny_block
    1993    16186320 :          do i = 1, nx_block
    1994    16163376 :             areafac_ce(i,j) = narea(i,j)
    1995             :          enddo
    1996             :          enddo
    1997             : 
    1998             :       endif
    1999             : 
    2000             :       !-------------------------------------------------------------------
    2001             :       ! Compute mask for edges with nonzero departure areas and for
    2002             :       ! one grid-cell wide channels
    2003             :       !-------------------------------------------------------------------
    2004             : 
    2005       45888 :       icellsd = 0
    2006       45888 :       if (trim(edge) == 'north') then
    2007      730632 :          do j = jlo-1, jhi
    2008    14275992 :          do i = ilo, ihi
    2009    12960000 :             if (dpx(i-1,j)/=c0 .or. dpy(i-1,j)/=c0   &
    2010             :                                .or.                  &   ! LCOV_EXCL_LINE
    2011    22893048 :                   dpx(i,j)/=c0 .or.   dpy(i,j)/=c0) then
    2012     6691810 :                icellsd = icellsd + 1
    2013     6691810 :                indxid(icellsd) = i
    2014     6691810 :                indxjd(icellsd) = j
    2015             :             else
    2016     6853550 :                if ( abs(edgearea(i,j)) > c0 ) then ! 1 grid-cell wide channel: dpx,y = 0, edgearea /= 0
    2017           0 :                   icellsd = icellsd + 1
    2018           0 :                   indxid(icellsd) = i
    2019           0 :                   indxjd(icellsd) = j
    2020             :                endif
    2021             :             endif
    2022             :          enddo
    2023             :          enddo
    2024             :       else       ! east edge
    2025      707688 :          do j = jlo, jhi
    2026    14511672 :          do i = ilo-1, ihi
    2027     8686080 :             if (dpx(i,j-1)/=c0 .or. dpy(i,j-1)/=c0   &
    2028             :                                .or.                  &   ! LCOV_EXCL_LINE
    2029    23174808 :                   dpx(i,j)/=c0 .or.   dpy(i,j)/=c0) then
    2030     6844823 :                icellsd = icellsd + 1
    2031     6844823 :                indxid(icellsd) = i
    2032     6844823 :                indxjd(icellsd) = j
    2033             :             else
    2034     6959161 :                if ( abs(edgearea(i,j)) > c0 ) then ! 1 grid-cell wide channel: dpx,y = 0, edgearea /= 0
    2035           0 :                   icellsd = icellsd + 1
    2036           0 :                   indxid(icellsd) = i
    2037           0 :                   indxjd(icellsd) = j
    2038             :                endif
    2039             :             endif
    2040             :          enddo
    2041             :          enddo
    2042             :       endif       ! edge = north/east
    2043             : 
    2044             :       !-------------------------------------------------------------------
    2045             :       ! Scale the departure points
    2046             :       !-------------------------------------------------------------------
    2047             : 
    2048     1461264 :       do j = 1, jhi
    2049    29967360 :       do i = 1, ihi
    2050    28506096 :          dx(i,j) = dpx(i,j) / dxu(i,j)
    2051    29921472 :          dy(i,j) = dpy(i,j) / dyu(i,j)
    2052             :       enddo
    2053             :       enddo
    2054             : 
    2055             :       !-------------------------------------------------------------------
    2056             :       ! Compute departure regions, divide into triangles, and locate
    2057             :       !  vertices of each triangle.
    2058             :       ! Work in a nondimensional coordinate system in which lengths are
    2059             :       !  scaled by the local metric coefficients (dxu and dyu).
    2060             :       ! Note: The do loop includes north faces of the j = 1 ghost cells
    2061             :       !       when edge = 'north'.  The loop includes east faces of i = 1
    2062             :       !       ghost cells when edge = 'east'.
    2063             :       !-------------------------------------------------------------------
    2064             : 
    2065    13582521 :       do ij = 1, icellsd
    2066    13536633 :          i = indxid(ij)
    2067    13536633 :          j = indxjd(ij)
    2068             : 
    2069    13536633 :          xcl = -p5
    2070    13536633 :          ycl =  c0
    2071             : 
    2072    13536633 :          xcr =  p5
    2073    13536633 :          ycr =  c0
    2074             : 
    2075             :          ! Departure points
    2076             : 
    2077    13536633 :          if (trim(edge) == 'north') then ! north edge
    2078     6691810 :             xdl = xcl + dx(i-1,j  )
    2079     6691810 :             ydl = ycl + dy(i-1,j  )
    2080     6691810 :             xdr = xcr + dx(i  ,j  )
    2081     6691810 :             ydr = ycr + dy(i  ,j  )
    2082             :          else                   ! east edge; rotate trajectory by pi/2
    2083     6844823 :             xdl = xcl - dy(i  ,j  )
    2084     6844823 :             ydl = ycl + dx(i  ,j  )
    2085     6844823 :             xdr = xcr - dy(i  ,j-1)
    2086     6844823 :             ydr = ycr + dx(i  ,j-1)
    2087             :          endif
    2088             : 
    2089    13536633 :          xdm = p5 * (xdr + xdl)
    2090    13536633 :          ydm = p5 * (ydr + ydl)
    2091             : 
    2092             :          ! Intersection points
    2093             : 
    2094    13536633 :          xil = xcl
    2095    13536633 :          yil = (xcl*(ydm-ydl) + xdm*ydl - xdl*ydm) / (xdm - xdl)
    2096             : 
    2097    13536633 :          xir = xcr
    2098    13536633 :          yir = (xcr*(ydr-ydm) - xdm*ydr + xdr*ydm) / (xdr - xdm)
    2099             : 
    2100    13536633 :          md = (ydr - ydl) / (xdr - xdl)
    2101             : 
    2102    13536633 :          if (abs(md) > puny) then
    2103    13536631 :             xic = xdl - ydl/md
    2104             :          else
    2105           2 :             xic = c0
    2106             :          endif
    2107    13536633 :          yic = c0
    2108             : 
    2109    13536633 :          xicl = xic
    2110    13536633 :          yicl = yic
    2111    13536633 :          xicr = xic
    2112    13536633 :          yicr = yic
    2113             : 
    2114             :          !-------------------------------------------------------------------
    2115             :          ! Locate triangles in TL cell (NW for north edge, NE for east edge)
    2116             :          ! and BL cell (W for north edge, N for east edge).
    2117             :          ! 
    2118             :          ! areafact_c or areafac_ce (areafact_c for the other edge) are used
    2119             :          ! (with shifted indices) to make sure that a flux area on one edge 
    2120             :          ! is consistent with the analogous area on the other edge and to 
    2121             :          ! ensure that areas add up when using l_fixed_area = T. See PR #849 
    2122             :          ! for details.
    2123             :          !
    2124             :          !-------------------------------------------------------------------
    2125             : 
    2126    13536633 :          if (yil > c0 .and. xdl < xcl .and. ydl >= c0) then
    2127             : 
    2128             :             ! TL (group 1)
    2129             : 
    2130     1055992 :             ng = 1
    2131     1055992 :             xp    (i,j,1,ng) = xcl
    2132     1055992 :             yp    (i,j,1,ng) = ycl
    2133     1055992 :             xp    (i,j,2,ng) = xil
    2134     1055992 :             yp    (i,j,2,ng) = yil
    2135     1055992 :             xp    (i,j,3,ng) = xdl
    2136     1055992 :             yp    (i,j,3,ng) = ydl
    2137     1055992 :             iflux   (i,j,ng) = i + ishift_tl
    2138     1055992 :             jflux   (i,j,ng) = j + jshift_tl
    2139     1055992 :             areafact(i,j,ng) = -areafac_ce(i+ise_tl,j+jse_tl)
    2140             : 
    2141    12480641 :          elseif (yil < c0 .and. xdl < xcl .and. ydl < c0) then
    2142             : 
    2143             :             ! BL (group 1)
    2144             : 
    2145     6163929 :             ng = 1
    2146     6163929 :             xp    (i,j,1,ng) = xcl
    2147     6163929 :             yp    (i,j,1,ng) = ycl
    2148     6163929 :             xp    (i,j,2,ng) = xdl
    2149     6163929 :             yp    (i,j,2,ng) = ydl
    2150     6163929 :             xp    (i,j,3,ng) = xil
    2151     6163929 :             yp    (i,j,3,ng) = yil
    2152     6163929 :             iflux   (i,j,ng) = i + ishift_bl
    2153     6163929 :             jflux   (i,j,ng) = j + jshift_bl
    2154     6163929 :             areafact(i,j,ng) = areafac_ce(i+ise_bl,j+jse_bl)
    2155             : 
    2156     6316712 :          elseif (yil < c0 .and. xdl < xcl .and. ydl >= c0) then
    2157             : 
    2158             :             ! TL1 (group 1)
    2159             : 
    2160         172 :             ng = 1
    2161         172 :             xp    (i,j,1,ng) = xcl
    2162         172 :             yp    (i,j,1,ng) = ycl
    2163         172 :             xp    (i,j,2,ng) = xdl
    2164         172 :             yp    (i,j,2,ng) = ydl
    2165         172 :             xp    (i,j,3,ng) = xic
    2166         172 :             yp    (i,j,3,ng) = yic
    2167         172 :             iflux   (i,j,ng) = i + ishift_tl
    2168         172 :             jflux   (i,j,ng) = j + jshift_tl
    2169         172 :             areafact(i,j,ng) = areafac_c(i+is_l,j+js_l)
    2170             : 
    2171             :             ! BL1 (group 3)
    2172             : 
    2173         172 :             ng = 3
    2174         172 :             xp    (i,j,1,ng) = xcl
    2175         172 :             yp    (i,j,1,ng) = ycl
    2176         172 :             xp    (i,j,2,ng) = xic
    2177         172 :             yp    (i,j,2,ng) = yic
    2178         172 :             xp    (i,j,3,ng) = xil
    2179         172 :             yp    (i,j,3,ng) = yil
    2180         172 :             iflux   (i,j,ng) = i + ishift_bl
    2181         172 :             jflux   (i,j,ng) = j + jshift_bl
    2182         172 :             areafact(i,j,ng) = areafac_ce(i+ise_bl,j+jse_bl)
    2183             : 
    2184     6316540 :          elseif (yil > c0 .and. xdl < xcl .and. ydl < c0) then
    2185             : 
    2186             :             ! TL2 (group 3)
    2187             : 
    2188         217 :             ng = 3
    2189         217 :             xp    (i,j,1,ng) = xcl
    2190         217 :             yp    (i,j,1,ng) = ycl
    2191         217 :             xp    (i,j,2,ng) = xil
    2192         217 :             yp    (i,j,2,ng) = yil
    2193         217 :             xp    (i,j,3,ng) = xic
    2194         217 :             yp    (i,j,3,ng) = yic
    2195         217 :             iflux   (i,j,ng) = i + ishift_tl
    2196         217 :             jflux   (i,j,ng) = j + jshift_tl
    2197         217 :             areafact(i,j,ng) = -areafac_ce(i+ise_tl,j+jse_tl)
    2198             : 
    2199             :             ! BL2 (group 1)
    2200             : 
    2201         217 :             ng = 1
    2202         217 :             xp    (i,j,1,ng) = xcl
    2203         217 :             yp    (i,j,1,ng) = ycl
    2204         217 :             xp    (i,j,2,ng) = xic
    2205         217 :             yp    (i,j,2,ng) = yic
    2206         217 :             xp    (i,j,3,ng) = xdl
    2207         217 :             yp    (i,j,3,ng) = ydl
    2208         217 :             iflux   (i,j,ng) = i + ishift_bl
    2209         217 :             jflux   (i,j,ng) = j + jshift_bl
    2210         217 :             areafact(i,j,ng) = -areafac_c(i+is_l,j+js_l)
    2211             : 
    2212             :          endif                  ! TL and BL triangles
    2213             : 
    2214             :          !-------------------------------------------------------------------
    2215             :          ! Locate triangles in TR cell (NE for north edge, SE for east edge)
    2216             :          ! and in BR cell (E for north edge, S for east edge).
    2217             :          !-------------------------------------------------------------------
    2218             : 
    2219    13536633 :          if (yir > c0 .and. xdr >= xcr .and. ydr >= c0) then
    2220             : 
    2221             :             ! TR (group 2)
    2222             : 
    2223      455946 :             ng = 2
    2224      455946 :             xp    (i,j,1,ng) = xcr
    2225      455946 :             yp    (i,j,1,ng) = ycr
    2226      455946 :             xp    (i,j,2,ng) = xdr
    2227      455946 :             yp    (i,j,2,ng) = ydr
    2228      455946 :             xp    (i,j,3,ng) = xir
    2229      455946 :             yp    (i,j,3,ng) = yir
    2230      455946 :             iflux   (i,j,ng) = i + ishift_tr
    2231      455946 :             jflux   (i,j,ng) = j + jshift_tr
    2232      455946 :             areafact(i,j,ng) = -areafac_ce(i+ise_tr,j+jse_tr)
    2233             : 
    2234    13080687 :          elseif (yir < c0 .and. xdr >= xcr .and. ydr < c0) then
    2235             : 
    2236             :             ! BR (group 2)
    2237             : 
    2238     5555742 :             ng = 2
    2239     5555742 :             xp    (i,j,1,ng) = xcr
    2240     5555742 :             yp    (i,j,1,ng) = ycr
    2241     5555742 :             xp    (i,j,2,ng) = xir
    2242     5555742 :             yp    (i,j,2,ng) = yir
    2243     5555742 :             xp    (i,j,3,ng) = xdr
    2244     5555742 :             yp    (i,j,3,ng) = ydr
    2245     5555742 :             iflux   (i,j,ng) = i + ishift_br
    2246     5555742 :             jflux   (i,j,ng) = j + jshift_br
    2247     5555742 :             areafact(i,j,ng) = areafac_ce(i+ise_br,j+jse_br)
    2248             : 
    2249     7524945 :          elseif (yir < c0 .and. xdr >= xcr  .and. ydr >= c0) then
    2250             : 
    2251             :             ! TR1 (group 2)
    2252             : 
    2253         212 :             ng = 2
    2254         212 :             xp    (i,j,1,ng) = xcr
    2255         212 :             yp    (i,j,1,ng) = ycr
    2256         212 :             xp    (i,j,2,ng) = xic
    2257         212 :             yp    (i,j,2,ng) = yic
    2258         212 :             xp    (i,j,3,ng) = xdr
    2259         212 :             yp    (i,j,3,ng) = ydr
    2260         212 :             iflux   (i,j,ng) = i + ishift_tr
    2261         212 :             jflux   (i,j,ng) = j + jshift_tr
    2262         212 :             areafact(i,j,ng) = areafac_c(i+is_r,j+js_r)
    2263             : 
    2264             :             ! BR1 (group 3)
    2265             : 
    2266         212 :             ng = 3
    2267         212 :             xp    (i,j,1,ng) = xcr
    2268         212 :             yp    (i,j,1,ng) = ycr
    2269         212 :             xp    (i,j,2,ng) = xir
    2270         212 :             yp    (i,j,2,ng) = yir
    2271         212 :             xp    (i,j,3,ng) = xic
    2272         212 :             yp    (i,j,3,ng) = yic
    2273         212 :             iflux   (i,j,ng) = i + ishift_br
    2274         212 :             jflux   (i,j,ng) = j + jshift_br
    2275         212 :             areafact(i,j,ng) = areafac_ce(i+ise_br,j+jse_br)
    2276             : 
    2277     7524733 :          elseif (yir > c0 .and. xdr >= xcr .and. ydr < c0) then
    2278             : 
    2279             :             ! TR2 (group 3)
    2280             : 
    2281          85 :             ng = 3
    2282          85 :             xp    (i,j,1,ng) = xcr
    2283          85 :             yp    (i,j,1,ng) = ycr
    2284          85 :             xp    (i,j,2,ng) = xic
    2285          85 :             yp    (i,j,2,ng) = yic
    2286          85 :             xp    (i,j,3,ng) = xir
    2287          85 :             yp    (i,j,3,ng) = yir
    2288          85 :             iflux   (i,j,ng) = i + ishift_tr
    2289          85 :             jflux   (i,j,ng) = j + jshift_tr
    2290          85 :             areafact(i,j,ng) = -areafac_ce(i+ise_tr,j+jse_tr)
    2291             : 
    2292             :             ! BR2 (group 2)
    2293             : 
    2294          85 :             ng = 2
    2295          85 :             xp    (i,j,1,ng) = xcr
    2296          85 :             yp    (i,j,1,ng) = ycr
    2297          85 :             xp    (i,j,2,ng) = xdr
    2298          85 :             yp    (i,j,2,ng) = ydr
    2299          85 :             xp    (i,j,3,ng) = xic
    2300          85 :             yp    (i,j,3,ng) = yic
    2301          85 :             iflux   (i,j,ng) = i + ishift_br
    2302          85 :             jflux   (i,j,ng) = j + jshift_br
    2303          85 :             areafact(i,j,ng) = -areafac_c(i+is_r,j+js_r)
    2304             : 
    2305             :          endif                  ! TR and BR triangles
    2306             : 
    2307             :          !-------------------------------------------------------------------
    2308             :          ! Redefine departure points if not located in central cells (TC or BC)
    2309             :          !-------------------------------------------------------------------
    2310             : 
    2311    13536633 :          if (xdl < xcl) then
    2312     7220310 :             xdl = xil
    2313     7220310 :             ydl = yil
    2314             :          endif
    2315             : 
    2316    13536633 :          if (xdr > xcr) then
    2317     6011985 :             xdr = xir
    2318     6011985 :             ydr = yir
    2319             :          endif
    2320             : 
    2321             :          !-------------------------------------------------------------------
    2322             :          ! For l_fixed_area = T, shift the midpoint so that the departure
    2323             :          ! region has the prescribed area
    2324             :          !-------------------------------------------------------------------
    2325             : 
    2326    13536633 :          if (l_fixed_area) then
    2327             : 
    2328             :             ! Sum the areas of the left and right triangles.
    2329             :             ! Note that yp(i,j,1,ng) = 0 for all triangles, so we can
    2330             :             !  drop those terms from the area formula.
    2331             : 
    2332           0 :             ng = 1
    2333           0 :             area1 = p5 * ( (xp(i,j,2,ng)-xp(i,j,1,ng)) *   &
    2334             :                             yp(i,j,3,ng)                   &   ! LCOV_EXCL_LINE
    2335             :                          -  yp(i,j,2,ng) *                 &   ! LCOV_EXCL_LINE
    2336             :                            (xp(i,j,3,ng)-xp(i,j,1,ng)) )   &   ! LCOV_EXCL_LINE
    2337           0 :                          * areafact(i,j,ng)
    2338             : 
    2339           0 :             ng = 2
    2340           0 :             area2 = p5 * ( (xp(i,j,2,ng)-xp(i,j,1,ng)) *   &
    2341             :                             yp(i,j,3,ng)                   &   ! LCOV_EXCL_LINE
    2342             :                          -  yp(i,j,2,ng) *                 &   ! LCOV_EXCL_LINE
    2343             :                            (xp(i,j,3,ng)-xp(i,j,1,ng)) )   &   ! LCOV_EXCL_LINE
    2344           0 :                          * areafact(i,j,ng)
    2345             : 
    2346           0 :             ng = 3
    2347           0 :             area3 = p5 * ( (xp(i,j,2,ng)-xp(i,j,1,ng)) *   &
    2348             :                             yp(i,j,3,ng)                   &   ! LCOV_EXCL_LINE
    2349             :                          -  yp(i,j,2,ng) *                 &   ! LCOV_EXCL_LINE
    2350             :                            (xp(i,j,3,ng)-xp(i,j,1,ng)) )   &   ! LCOV_EXCL_LINE
    2351           0 :                          * areafact(i,j,ng)
    2352             : 
    2353             :             !-----------------------------------------------------------
    2354             :             ! Check whether the central triangles lie in one grid cell or two.
    2355             :             ! If all are in one grid cell, then adjust the area of the central
    2356             :             !  region so that the sum of all triangle areas is equal to the
    2357             :             !  prescribed value.
    2358             :             ! If two triangles are in one grid cell and one is in the other,
    2359             :             !  then compute the area of the lone triangle. Then adjust
    2360             :             !  the area of the remaining two-triangle region so that the sum of
    2361             :             !  all triangle areas has the prescribed value.
    2362             :             !-----------------------------------------------------------
    2363             : 
    2364           0 :             if (ydl*ydr >= c0) then   ! Both DPs lie on same side of x-axis
    2365             : 
    2366             :                ! compute required area of central departure region
    2367           0 :                area_c  = edgearea(i,j) - area1 - area2 - area3
    2368             : 
    2369             :                ! shift midpoint so that the area of remaining triangles = area_c
    2370           0 :                w1 = c2*area_c/areafac_c(i,j)    &
    2371           0 :                     + (xdr-xcl)*ydl + (xcr-xdl)*ydr
    2372           0 :                w2 = (xdr-xdl)**2 + (ydr-ydl)**2
    2373           0 :                w1 = w1/w2
    2374           0 :                xdm = xdm + (ydr - ydl) * w1
    2375           0 :                ydm = ydm - (xdr - xdl) * w1
    2376             : 
    2377             :                ! compute left and right intersection points
    2378           0 :                mdl = (ydm - ydl) / (xdm - xdl)
    2379           0 :                mdr = (ydr - ydm) / (xdr - xdm)
    2380             : 
    2381           0 :                if (abs(mdl) > puny) then
    2382           0 :                   xicl = xdl - ydl/mdl
    2383             :                else
    2384           0 :                   xicl = c0
    2385             :                endif
    2386           0 :                yicl = c0
    2387             : 
    2388           0 :                if (abs(mdr) > puny) then
    2389           0 :                   xicr = xdr - ydr/mdr
    2390             :                else
    2391           0 :                   xicr = c0
    2392             :                endif
    2393           0 :                yicr = c0
    2394             : 
    2395           0 :             elseif (xic < c0 .and. xic > xcl) then  ! fix ICL = IC
    2396             : 
    2397           0 :                xicl = xic
    2398           0 :                yicl = yic
    2399             : 
    2400             :                ! compute midpoint between ICL and DR
    2401           0 :                xdm = p5 * (xdr + xicl)
    2402           0 :                ydm = p5 *  ydr
    2403             : 
    2404             :                ! compute area of (lone) triangle adjacent to left corner
    2405           0 :                area4 = p5 * (xcl - xic) * ydl * areafac_c(i,j)
    2406           0 :                area_c  = edgearea(i,j) - area1 - area2 - area3 - area4
    2407             : 
    2408             :                ! shift midpoint so that area of remaining triangles = area_c
    2409           0 :                w1 = c2*area_c/areafac_c(i,j) + (xcr-xic)*ydr
    2410           0 :                w2 = (xdr-xic)**2 + ydr**2
    2411           0 :                w1 = w1/w2
    2412           0 :                xdm = xdm + ydr*w1
    2413           0 :                ydm = ydm - (xdr - xic) * w1
    2414             : 
    2415             :                ! compute ICR
    2416           0 :                mdr = (ydr - ydm) / (xdr - xdm)
    2417           0 :                if (abs(mdr) > puny) then
    2418           0 :                   xicr = xdr - ydr/mdr
    2419             :                else
    2420           0 :                   xicr = c0
    2421             :                endif
    2422           0 :                yicr = c0
    2423             : 
    2424           0 :             elseif (xic >= c0 .and. xic < xcr) then  ! fix ICR = IR
    2425             : 
    2426           0 :                xicr = xic
    2427           0 :                yicr = yic
    2428             : 
    2429             :                ! compute midpoint between ICR and DL
    2430           0 :                xdm = p5 * (xicr + xdl)
    2431           0 :                ydm = p5 *  ydl
    2432             : 
    2433             :                ! compute area of (lone) triangle adjacent to right corner
    2434           0 :                area4 = p5 * (xic - xcr) * ydr * areafac_c(i,j)
    2435           0 :                area_c  = edgearea(i,j) - area1 - area2 - area3 - area4
    2436             : 
    2437             :                ! shift midpoint so that area of remaining triangles = area_c
    2438           0 :                w1 = c2*area_c/areafac_c(i,j) + (xic-xcl)*ydl
    2439           0 :                w2 = (xic-xdl)**2 + ydl**2
    2440           0 :                w1 = w1/w2
    2441           0 :                xdm = xdm - ydl*w1
    2442           0 :                ydm = ydm - (xic - xdl) * w1
    2443             : 
    2444             :                ! compute ICL
    2445             : 
    2446           0 :                mdl = (ydm - ydl) / (xdm - xdl)
    2447           0 :                if (abs(mdl) > puny) then
    2448           0 :                   xicl = xdl - ydl/mdl
    2449             :                else
    2450           0 :                   xicl = c0
    2451             :                endif
    2452           0 :                yicl = c0
    2453             : 
    2454             :             endif   ! ydl*ydr >= c0
    2455             : 
    2456             :          endif  ! l_fixed_area
    2457             : 
    2458             :          !-------------------------------------------------------------------
    2459             :          ! Locate triangles in BC cell (H for both north and east edges)
    2460             :          ! and TC cell (N for north edge and E for east edge).
    2461             :          !-------------------------------------------------------------------
    2462             : 
    2463             :          ! Start with cases where both DPs lie in the same grid cell
    2464             : 
    2465    13582521 :          if (ydl >= c0 .and. ydr >= c0 .and. ydm >= c0) then
    2466             : 
    2467             :             ! TC1a (group 4)
    2468             : 
    2469     1497825 :             ng = 4
    2470     1497825 :             xp    (i,j,1,ng) = xcl
    2471     1497825 :             yp    (i,j,1,ng) = ycl
    2472     1497825 :             xp    (i,j,2,ng) = xcr
    2473     1497825 :             yp    (i,j,2,ng) = ycr
    2474     1497825 :             xp    (i,j,3,ng) = xdl
    2475     1497825 :             yp    (i,j,3,ng) = ydl
    2476     1497825 :             iflux   (i,j,ng) = i + ishift_tc
    2477     1497825 :             jflux   (i,j,ng) = j + jshift_tc
    2478     1497825 :             areafact(i,j,ng) = -areafac_c(i,j)
    2479             :  
    2480             :             ! TC2a (group 5)
    2481             : 
    2482     1497825 :             ng = 5
    2483     1497825 :             xp    (i,j,1,ng) = xcr
    2484     1497825 :             yp    (i,j,1,ng) = ycr
    2485     1497825 :             xp    (i,j,2,ng) = xdr
    2486     1497825 :             yp    (i,j,2,ng) = ydr
    2487     1497825 :             xp    (i,j,3,ng) = xdl
    2488     1497825 :             yp    (i,j,3,ng) = ydl
    2489     1497825 :             iflux   (i,j,ng) = i + ishift_tc
    2490     1497825 :             jflux   (i,j,ng) = j + jshift_tc
    2491     1497825 :             areafact(i,j,ng) = -areafac_c(i,j)
    2492             :  
    2493             :             ! TC3a (group 6)
    2494             : 
    2495     1497825 :             ng = 6
    2496     1497825 :             xp    (i,j,1,ng) = xdl
    2497     1497825 :             yp    (i,j,1,ng) = ydl
    2498     1497825 :             xp    (i,j,2,ng) = xdr
    2499     1497825 :             yp    (i,j,2,ng) = ydr
    2500     1497825 :             xp    (i,j,3,ng) = xdm
    2501     1497825 :             yp    (i,j,3,ng) = ydm
    2502     1497825 :             iflux   (i,j,ng) = i + ishift_tc
    2503     1497825 :             jflux   (i,j,ng) = j + jshift_tc
    2504     1497825 :             areafact(i,j,ng) = -areafac_c(i,j)
    2505             : 
    2506    12038808 :          elseif (ydl >= c0 .and. ydr >= c0 .and. ydm < c0) then  ! rare
    2507             : 
    2508             :             ! TC1b (group 4)
    2509             : 
    2510           0 :             ng = 4
    2511           0 :             xp    (i,j,1,ng) = xcl
    2512           0 :             yp    (i,j,1,ng) = ycl
    2513           0 :             xp    (i,j,2,ng) = xicl
    2514           0 :             yp    (i,j,2,ng) = yicl
    2515           0 :             xp    (i,j,3,ng) = xdl
    2516           0 :             yp    (i,j,3,ng) = ydl
    2517           0 :             iflux   (i,j,ng) = i + ishift_tc
    2518           0 :             jflux   (i,j,ng) = j + jshift_tc
    2519           0 :             areafact(i,j,ng) = -areafac_c(i,j)
    2520             : 
    2521             :             ! TC2b (group 5)
    2522             : 
    2523           0 :             ng = 5
    2524           0 :             xp    (i,j,1,ng) = xcr
    2525           0 :             yp    (i,j,1,ng) = ycr
    2526           0 :             xp    (i,j,2,ng) = xdr
    2527           0 :             yp    (i,j,2,ng) = ydr
    2528           0 :             xp    (i,j,3,ng) = xicr
    2529           0 :             yp    (i,j,3,ng) = yicr
    2530           0 :             iflux   (i,j,ng) = i + ishift_tc
    2531           0 :             jflux   (i,j,ng) = j + jshift_tc
    2532           0 :             areafact(i,j,ng) = -areafac_c(i,j)
    2533             : 
    2534             :             ! BC3b (group 6)
    2535             : 
    2536           0 :             ng = 6
    2537           0 :             xp    (i,j,1,ng) = xicr
    2538           0 :             yp    (i,j,1,ng) = yicr
    2539           0 :             xp    (i,j,2,ng) = xicl
    2540           0 :             yp    (i,j,2,ng) = yicl
    2541           0 :             xp    (i,j,3,ng) = xdm
    2542           0 :             yp    (i,j,3,ng) = ydm
    2543           0 :             iflux   (i,j,ng) = i + ishift_bc
    2544           0 :             jflux   (i,j,ng) = j + jshift_bc
    2545           0 :             areafact(i,j,ng) = areafac_c(i,j)
    2546             : 
    2547    12038808 :          elseif (ydl <= c0 .and. ydr <= c0 .and. ydm <= c0) then
    2548             : 
    2549             :             ! BC1a (group 4)
    2550             : 
    2551    11777113 :             ng = 4
    2552    11777113 :             xp    (i,j,1,ng) = xcl
    2553    11777113 :             yp    (i,j,1,ng) = ycl
    2554    11777113 :             xp    (i,j,2,ng) = xdl
    2555    11777113 :             yp    (i,j,2,ng) = ydl
    2556    11777113 :             xp    (i,j,3,ng) = xcr
    2557    11777113 :             yp    (i,j,3,ng) = ycr
    2558    11777113 :             iflux   (i,j,ng) = i + ishift_bc
    2559    11777113 :             jflux   (i,j,ng) = j + jshift_bc
    2560    11777113 :             areafact(i,j,ng) = areafac_c(i,j)
    2561             : 
    2562             :             ! BC2a (group 5)
    2563             : 
    2564    11777113 :             ng = 5
    2565    11777113 :             xp    (i,j,1,ng) = xcr
    2566    11777113 :             yp    (i,j,1,ng) = ycr
    2567    11777113 :             xp    (i,j,2,ng) = xdl
    2568    11777113 :             yp    (i,j,2,ng) = ydl
    2569    11777113 :             xp    (i,j,3,ng) = xdr
    2570    11777113 :             yp    (i,j,3,ng) = ydr
    2571    11777113 :             iflux   (i,j,ng) = i + ishift_bc
    2572    11777113 :             jflux   (i,j,ng) = j + jshift_bc
    2573    11777113 :             areafact(i,j,ng) = areafac_c(i,j)
    2574             : 
    2575             :             ! BC3a (group 6)
    2576             : 
    2577    11777113 :             ng = 6
    2578    11777113 :             xp    (i,j,1,ng) = xdl
    2579    11777113 :             yp    (i,j,1,ng) = ydl
    2580    11777113 :             xp    (i,j,2,ng) = xdm
    2581    11777113 :             yp    (i,j,2,ng) = ydm
    2582    11777113 :             xp    (i,j,3,ng) = xdr
    2583    11777113 :             yp    (i,j,3,ng) = ydr
    2584    11777113 :             iflux   (i,j,ng) = i + ishift_bc
    2585    11777113 :             jflux   (i,j,ng) = j + jshift_bc
    2586    11777113 :             areafact(i,j,ng) = areafac_c(i,j)
    2587             : 
    2588      261695 :          elseif (ydl <= c0 .and. ydr <= c0 .and. ydm > c0) then  ! rare
    2589             : 
    2590             :             ! BC1b (group 4)
    2591             : 
    2592           0 :             ng = 4
    2593           0 :             xp    (i,j,1,ng) = xcl
    2594           0 :             yp    (i,j,1,ng) = ycl
    2595           0 :             xp    (i,j,2,ng) = xdl
    2596           0 :             yp    (i,j,2,ng) = ydl
    2597           0 :             xp    (i,j,3,ng) = xicl
    2598           0 :             yp    (i,j,3,ng) = yicl
    2599           0 :             iflux   (i,j,ng) = i + ishift_bc
    2600           0 :             jflux   (i,j,ng) = j + jshift_bc
    2601           0 :             areafact(i,j,ng) = areafac_c(i,j)
    2602             : 
    2603             :             ! BC2b (group 5)
    2604             : 
    2605           0 :             ng = 5
    2606           0 :             xp    (i,j,1,ng) = xcr
    2607           0 :             yp    (i,j,1,ng) = ycr
    2608           0 :             xp    (i,j,2,ng) = xicr
    2609           0 :             yp    (i,j,2,ng) = yicr
    2610           0 :             xp    (i,j,3,ng) = xdr
    2611           0 :             yp    (i,j,3,ng) = ydr
    2612           0 :             iflux   (i,j,ng) = i + ishift_bc
    2613           0 :             jflux   (i,j,ng) = j + jshift_bc
    2614           0 :             areafact(i,j,ng) = areafac_c(i,j)
    2615             : 
    2616             :             ! TC3b (group 6)
    2617             : 
    2618           0 :             ng = 6
    2619           0 :             xp    (i,j,1,ng) = xicl
    2620           0 :             yp    (i,j,1,ng) = yicl
    2621           0 :             xp    (i,j,2,ng) = xicr
    2622           0 :             yp    (i,j,2,ng) = yicr
    2623           0 :             xp    (i,j,3,ng) = xdm
    2624           0 :             yp    (i,j,3,ng) = ydm
    2625           0 :             iflux   (i,j,ng) = i + ishift_tc
    2626           0 :             jflux   (i,j,ng) = j + jshift_tc
    2627           0 :             areafact(i,j,ng) = -areafac_c(i,j)
    2628             : 
    2629             :          ! Now consider cases where the two DPs lie in different grid cells
    2630             : 
    2631             :          elseif (ydl > c0 .and. ydr < c0 .and. xic >= c0  &
    2632      261695 :                                          .and. ydm >= c0) then
    2633             : 
    2634             :             ! TC1b (group 4)
    2635             : 
    2636       57424 :             ng = 4
    2637       57424 :             xp    (i,j,1,ng) = xcl
    2638       57424 :             yp    (i,j,1,ng) = ycl
    2639       57424 :             xp    (i,j,2,ng) = xicr
    2640       57424 :             yp    (i,j,2,ng) = yicr
    2641       57424 :             xp    (i,j,3,ng) = xdl
    2642       57424 :             yp    (i,j,3,ng) = ydl
    2643       57424 :             iflux   (i,j,ng) = i + ishift_tc
    2644       57424 :             jflux   (i,j,ng) = j + jshift_tc
    2645       57424 :             areafact(i,j,ng) = -areafac_c(i,j)
    2646             : 
    2647             :             ! BC2b (group 5) lone triangle
    2648             : 
    2649       57424 :             ng = 5
    2650       57424 :             xp    (i,j,1,ng) = xcr
    2651       57424 :             yp    (i,j,1,ng) = ycr
    2652       57424 :             xp    (i,j,2,ng) = xicr
    2653       57424 :             yp    (i,j,2,ng) = yicr
    2654       57424 :             xp    (i,j,3,ng) = xdr
    2655       57424 :             yp    (i,j,3,ng) = ydr
    2656       57424 :             iflux   (i,j,ng) = i + ishift_bc
    2657       57424 :             jflux   (i,j,ng) = j + jshift_bc
    2658       57424 :             areafact(i,j,ng) = areafac_c(i,j)
    2659             : 
    2660             :             ! TC3b (group 6)
    2661             : 
    2662       57424 :             ng = 6
    2663       57424 :             xp    (i,j,1,ng) = xdl
    2664       57424 :             yp    (i,j,1,ng) = ydl
    2665       57424 :             xp    (i,j,2,ng) = xicr
    2666       57424 :             yp    (i,j,2,ng) = yicr
    2667       57424 :             xp    (i,j,3,ng) = xdm
    2668       57424 :             yp    (i,j,3,ng) = ydm
    2669       57424 :             iflux   (i,j,ng) = i + ishift_tc
    2670       57424 :             jflux   (i,j,ng) = j + jshift_tc
    2671       57424 :             areafact(i,j,ng) = -areafac_c(i,j)
    2672             : 
    2673             :          elseif (ydl > c0 .and. ydr < c0 .and. xic >= c0  &
    2674      204271 :                                          .and. ydm < c0 ) then  ! less common
    2675             : 
    2676             :             ! TC1b (group 4)
    2677             : 
    2678          94 :             ng = 4
    2679          94 :             xp    (i,j,1,ng) = xcl
    2680          94 :             yp    (i,j,1,ng) = ycl
    2681          94 :             xp    (i,j,2,ng) = xicl
    2682          94 :             yp    (i,j,2,ng) = yicl
    2683          94 :             xp    (i,j,3,ng) = xdl
    2684          94 :             yp    (i,j,3,ng) = ydl
    2685          94 :             iflux   (i,j,ng) = i + ishift_tc
    2686          94 :             jflux   (i,j,ng) = j + jshift_tc
    2687          94 :             areafact(i,j,ng) = -areafac_c(i,j)
    2688             : 
    2689             :             ! BC2b (group 5) lone triangle
    2690             : 
    2691          94 :             ng = 5
    2692          94 :             xp    (i,j,1,ng) = xcr
    2693          94 :             yp    (i,j,1,ng) = ycr
    2694          94 :             xp    (i,j,2,ng) = xicr
    2695          94 :             yp    (i,j,2,ng) = yicr
    2696          94 :             xp    (i,j,3,ng) = xdr
    2697          94 :             yp    (i,j,3,ng) = ydr
    2698          94 :             iflux   (i,j,ng) = i + ishift_bc
    2699          94 :             jflux   (i,j,ng) = j + jshift_bc
    2700          94 :             areafact(i,j,ng) = areafac_c(i,j)
    2701             : 
    2702             :             ! BC3b (group 6)
    2703             : 
    2704          94 :             ng = 6
    2705          94 :             xp    (i,j,1,ng) = xicr
    2706          94 :             yp    (i,j,1,ng) = yicr
    2707          94 :             xp    (i,j,2,ng) = xicl
    2708          94 :             yp    (i,j,2,ng) = yicl
    2709          94 :             xp    (i,j,3,ng) = xdm
    2710          94 :             yp    (i,j,3,ng) = ydm
    2711          94 :             iflux   (i,j,ng) = i + ishift_bc
    2712          94 :             jflux   (i,j,ng) = j + jshift_bc
    2713          94 :             areafact(i,j,ng) = areafac_c(i,j)
    2714             : 
    2715             :          elseif (ydl > c0 .and. ydr < c0 .and. xic < c0   &
    2716      204177 :                                          .and. ydm < c0) then
    2717             : 
    2718             :             ! TC1b (group 4) lone triangle
    2719             : 
    2720       51291 :             ng = 4
    2721       51291 :             xp    (i,j,1,ng) = xcl
    2722       51291 :             yp    (i,j,1,ng) = ycl
    2723       51291 :             xp    (i,j,2,ng) = xicl
    2724       51291 :             yp    (i,j,2,ng) = yicl
    2725       51291 :             xp    (i,j,3,ng) = xdl
    2726       51291 :             yp    (i,j,3,ng) = ydl
    2727       51291 :             iflux   (i,j,ng) = i + ishift_tc
    2728       51291 :             jflux   (i,j,ng) = j + jshift_tc
    2729       51291 :             areafact(i,j,ng) = -areafac_c(i,j)
    2730             : 
    2731             :             ! BC2b (group 5)
    2732             : 
    2733       51291 :             ng = 5
    2734       51291 :             xp    (i,j,1,ng) = xcr
    2735       51291 :             yp    (i,j,1,ng) = ycr
    2736       51291 :             xp    (i,j,2,ng) = xicl
    2737       51291 :             yp    (i,j,2,ng) = yicl
    2738       51291 :             xp    (i,j,3,ng) = xdr
    2739       51291 :             yp    (i,j,3,ng) = ydr
    2740       51291 :             iflux   (i,j,ng) = i + ishift_bc
    2741       51291 :             jflux   (i,j,ng) = j + jshift_bc
    2742       51291 :             areafact(i,j,ng) = areafac_c(i,j)
    2743             : 
    2744             :             ! BC3b (group 6)
    2745             : 
    2746       51291 :             ng = 6
    2747       51291 :             xp    (i,j,1,ng) = xdr
    2748       51291 :             yp    (i,j,1,ng) = ydr
    2749       51291 :             xp    (i,j,2,ng) = xicl
    2750       51291 :             yp    (i,j,2,ng) = yicl
    2751       51291 :             xp    (i,j,3,ng) = xdm
    2752       51291 :             yp    (i,j,3,ng) = ydm
    2753       51291 :             iflux   (i,j,ng) = i + ishift_bc
    2754       51291 :             jflux   (i,j,ng) = j + jshift_bc
    2755       51291 :             areafact(i,j,ng) = areafac_c(i,j)
    2756             : 
    2757             :          elseif (ydl > c0 .and. ydr < c0 .and. xic <  c0  &
    2758      152886 :                                          .and. ydm >= c0) then  ! less common
    2759             : 
    2760             :             ! TC1b (group 4) lone triangle
    2761             : 
    2762         138 :             ng = 4
    2763         138 :             xp    (i,j,1,ng) = xcl
    2764         138 :             yp    (i,j,1,ng) = ycl
    2765         138 :             xp    (i,j,2,ng) = xicl
    2766         138 :             yp    (i,j,2,ng) = yicl
    2767         138 :             xp    (i,j,3,ng) = xdl
    2768         138 :             yp    (i,j,3,ng) = ydl
    2769         138 :             iflux   (i,j,ng) = i + ishift_tc
    2770         138 :             jflux   (i,j,ng) = j + jshift_tc
    2771         138 :             areafact(i,j,ng) = -areafac_c(i,j)
    2772             : 
    2773             :             ! BC2b (group 5)
    2774             : 
    2775         138 :             ng = 5
    2776         138 :             xp    (i,j,1,ng) = xcr
    2777         138 :             yp    (i,j,1,ng) = ycr
    2778         138 :             xp    (i,j,2,ng) = xicr
    2779         138 :             yp    (i,j,2,ng) = yicr
    2780         138 :             xp    (i,j,3,ng) = xdr
    2781         138 :             yp    (i,j,3,ng) = ydr
    2782         138 :             iflux   (i,j,ng) = i + ishift_bc
    2783         138 :             jflux   (i,j,ng) = j + jshift_bc
    2784         138 :             areafact(i,j,ng) = areafac_c(i,j)
    2785             : 
    2786             :             ! TC3b (group 6)
    2787             : 
    2788         138 :             ng = 6
    2789         138 :             xp    (i,j,1,ng) = xicl
    2790         138 :             yp    (i,j,1,ng) = yicl
    2791         138 :             xp    (i,j,2,ng) = xicr
    2792         138 :             yp    (i,j,2,ng) = yicr
    2793         138 :             xp    (i,j,3,ng) = xdm
    2794         138 :             yp    (i,j,3,ng) = ydm
    2795         138 :             iflux   (i,j,ng) = i + ishift_tc
    2796         138 :             jflux   (i,j,ng) = j + jshift_tc
    2797         138 :             areafact(i,j,ng) = -areafac_c(i,j)
    2798             : 
    2799             :          elseif (ydl < c0 .and. ydr > c0 .and. xic <  c0  &
    2800      152748 :                                          .and. ydm >= c0) then
    2801             : 
    2802             :             ! BC1b (group 4) lone triangle
    2803             : 
    2804       74220 :             ng = 4
    2805       74220 :             xp    (i,j,1,ng) = xcl
    2806       74220 :             yp    (i,j,1,ng) = ycl
    2807       74220 :             xp    (i,j,2,ng) = xdl
    2808       74220 :             yp    (i,j,2,ng) = ydl
    2809       74220 :             xp    (i,j,3,ng) = xicl
    2810       74220 :             yp    (i,j,3,ng) = yicl
    2811       74220 :             iflux   (i,j,ng) = i + ishift_bc
    2812       74220 :             jflux   (i,j,ng) = j + jshift_bc
    2813       74220 :             areafact(i,j,ng) = areafac_c(i,j)
    2814             : 
    2815             :             ! TC2b (group 5)
    2816             : 
    2817       74220 :             ng = 5
    2818       74220 :             xp    (i,j,1,ng) = xcr
    2819       74220 :             yp    (i,j,1,ng) = ycr
    2820       74220 :             xp    (i,j,2,ng) = xdr
    2821       74220 :             yp    (i,j,2,ng) = ydr
    2822       74220 :             xp    (i,j,3,ng) = xicl
    2823       74220 :             yp    (i,j,3,ng) = yicl
    2824       74220 :             iflux   (i,j,ng) = i + ishift_tc
    2825       74220 :             jflux   (i,j,ng) = j + jshift_tc
    2826       74220 :             areafact(i,j,ng) = -areafac_c(i,j)
    2827             : 
    2828             :             ! TC3b (group 6)
    2829             : 
    2830       74220 :             ng = 6
    2831       74220 :             xp    (i,j,1,ng) = xicl
    2832       74220 :             yp    (i,j,1,ng) = yicl
    2833       74220 :             xp    (i,j,2,ng) = xdr
    2834       74220 :             yp    (i,j,2,ng) = ydr
    2835       74220 :             xp    (i,j,3,ng) = xdm
    2836       74220 :             yp    (i,j,3,ng) = ydm
    2837       74220 :             iflux   (i,j,ng) = i + ishift_tc
    2838       74220 :             jflux   (i,j,ng) = j + jshift_tc
    2839       74220 :             areafact(i,j,ng) = -areafac_c(i,j)
    2840             : 
    2841             :          elseif (ydl < c0 .and. ydr > c0 .and. xic < c0  &
    2842       78528 :                                          .and. ydm < c0) then ! less common
    2843             : 
    2844             :             ! BC1b (group 4) lone triangle
    2845             : 
    2846         271 :             ng = 4
    2847         271 :             xp    (i,j,1,ng) = xcl
    2848         271 :             yp    (i,j,1,ng) = ycl
    2849         271 :             xp    (i,j,2,ng) = xdl
    2850         271 :             yp    (i,j,2,ng) = ydl
    2851         271 :             xp    (i,j,3,ng) = xicl
    2852         271 :             yp    (i,j,3,ng) = yicl
    2853         271 :             iflux   (i,j,ng) = i + ishift_bc
    2854         271 :             jflux   (i,j,ng) = j + jshift_bc
    2855         271 :             areafact(i,j,ng) = areafac_c(i,j)
    2856             : 
    2857             :             ! TC2b (group 5)
    2858             : 
    2859         271 :             ng = 5
    2860         271 :             xp    (i,j,1,ng) = xcr
    2861         271 :             yp    (i,j,1,ng) = ycr
    2862         271 :             xp    (i,j,2,ng) = xdr
    2863         271 :             yp    (i,j,2,ng) = ydr
    2864         271 :             xp    (i,j,3,ng) = xicr
    2865         271 :             yp    (i,j,3,ng) = yicr
    2866         271 :             iflux   (i,j,ng) = i + ishift_tc
    2867         271 :             jflux   (i,j,ng) = j + jshift_tc
    2868         271 :             areafact(i,j,ng) = -areafac_c(i,j)
    2869             : 
    2870             :             ! BC3b (group 6)
    2871             : 
    2872         271 :             ng = 6
    2873         271 :             xp    (i,j,1,ng) = xicr
    2874         271 :             yp    (i,j,1,ng) = yicr
    2875         271 :             xp    (i,j,2,ng) = xicl
    2876         271 :             yp    (i,j,2,ng) = yicl
    2877         271 :             xp    (i,j,3,ng) = xdm
    2878         271 :             yp    (i,j,3,ng) = ydm
    2879         271 :             iflux   (i,j,ng) = i + ishift_bc
    2880         271 :             jflux   (i,j,ng) = j + jshift_bc
    2881         271 :             areafact(i,j,ng) = areafac_c(i,j)
    2882             : 
    2883             :          elseif (ydl < c0 .and. ydr > c0 .and. xic >= c0  &
    2884       78257 :                                          .and. ydm <  c0) then
    2885             : 
    2886             :             ! BC1b (group 4)
    2887             : 
    2888       78115 :             ng = 4
    2889       78115 :             xp    (i,j,1,ng) = xcl
    2890       78115 :             yp    (i,j,1,ng) = ycl
    2891       78115 :             xp    (i,j,2,ng) = xdl
    2892       78115 :             yp    (i,j,2,ng) = ydl
    2893       78115 :             xp    (i,j,3,ng) = xicr
    2894       78115 :             yp    (i,j,3,ng) = yicr
    2895       78115 :             iflux   (i,j,ng) = i + ishift_bc
    2896       78115 :             jflux   (i,j,ng) = j + jshift_bc
    2897       78115 :             areafact(i,j,ng) = areafac_c(i,j)
    2898             : 
    2899             :             ! TC2b (group 5) lone triangle
    2900             : 
    2901       78115 :             ng = 5
    2902       78115 :             xp    (i,j,1,ng) = xcr
    2903       78115 :             yp    (i,j,1,ng) = ycr
    2904       78115 :             xp    (i,j,2,ng) = xdr
    2905       78115 :             yp    (i,j,2,ng) = ydr
    2906       78115 :             xp    (i,j,3,ng) = xicr
    2907       78115 :             yp    (i,j,3,ng) = yicr
    2908       78115 :             iflux   (i,j,ng) = i + ishift_tc
    2909       78115 :             jflux   (i,j,ng) = j + jshift_tc
    2910       78115 :             areafact(i,j,ng) = -areafac_c(i,j)
    2911             : 
    2912             :             ! BC3b (group 6)
    2913             : 
    2914       78115 :             ng = 6
    2915       78115 :             xp    (i,j,1,ng) = xicr
    2916       78115 :             yp    (i,j,1,ng) = yicr
    2917       78115 :             xp    (i,j,2,ng) = xdl
    2918       78115 :             yp    (i,j,2,ng) = ydl
    2919       78115 :             xp    (i,j,3,ng) = xdm
    2920       78115 :             yp    (i,j,3,ng) = ydm
    2921       78115 :             iflux   (i,j,ng) = i + ishift_bc
    2922       78115 :             jflux   (i,j,ng) = j + jshift_bc
    2923       78115 :             areafact(i,j,ng) = areafac_c(i,j)
    2924             : 
    2925             :          elseif (ydl < c0 .and. ydr > c0 .and. xic >= c0   &
    2926         142 :                                          .and. ydm >= c0) then  ! less common
    2927             : 
    2928             :             ! BC1b (group 4)
    2929             : 
    2930         142 :             ng = 4
    2931         142 :             xp    (i,j,1,ng) = xcl
    2932         142 :             yp    (i,j,1,ng) = ycl
    2933         142 :             xp    (i,j,2,ng) = xdl
    2934         142 :             yp    (i,j,2,ng) = ydl
    2935         142 :             xp    (i,j,3,ng) = xicl
    2936         142 :             yp    (i,j,3,ng) = yicl
    2937         142 :             iflux   (i,j,ng) = i + ishift_bc
    2938         142 :             jflux   (i,j,ng) = j + jshift_bc
    2939         142 :             areafact(i,j,ng) = areafac_c(i,j)
    2940             : 
    2941             :             ! TC2b (group 5) lone triangle
    2942             : 
    2943         142 :             ng = 5
    2944         142 :             xp    (i,j,1,ng) = xcr
    2945         142 :             yp    (i,j,1,ng) = ycr
    2946         142 :             xp    (i,j,2,ng) = xdr
    2947         142 :             yp    (i,j,2,ng) = ydr
    2948         142 :             xp    (i,j,3,ng) = xicr
    2949         142 :             yp    (i,j,3,ng) = yicr
    2950         142 :             iflux   (i,j,ng) = i + ishift_tc
    2951         142 :             jflux   (i,j,ng) = j + jshift_tc
    2952         142 :             areafact(i,j,ng) = -areafac_c(i,j)
    2953             : 
    2954             :             ! TC3b (group 6)
    2955             : 
    2956         142 :             ng = 6
    2957         142 :             xp    (i,j,1,ng) = xicl
    2958         142 :             yp    (i,j,1,ng) = yicl
    2959         142 :             xp    (i,j,2,ng) = xicr
    2960         142 :             yp    (i,j,2,ng) = yicr
    2961         142 :             xp    (i,j,3,ng) = xdm
    2962         142 :             yp    (i,j,3,ng) = ydm
    2963         142 :             iflux   (i,j,ng) = i + ishift_tc
    2964         142 :             jflux   (i,j,ng) = j + jshift_tc
    2965         142 :             areafact(i,j,ng) = -areafac_c(i,j)
    2966             : 
    2967             :          endif                  ! TC and BC triangles
    2968             : 
    2969             :       enddo                     ! ij
    2970             : 
    2971             :       !-------------------------------------------------------------------
    2972             :       ! Compute triangle areas with appropriate sign.
    2973             :       ! These are found by computing the area in scaled coordinates and
    2974             :       !  multiplying by a scale factor (areafact).
    2975             :       ! Note that the scale factor is positive for fluxes out of the cell
    2976             :       !  and negative for fluxes into the cell.
    2977             :       !
    2978             :       ! Note: The triangle area formula below gives A >=0 iff the triangle
    2979             :       !        points x1, x2, and x3 are taken in counterclockwise order.
    2980             :       !       These points are defined above in such a way that the
    2981             :       !        order is nearly always CCW.
    2982             :       !       In rare cases, we may compute A < 0.  In this case,
    2983             :       !        the quadrilateral departure area is equal to the
    2984             :       !        difference of two triangle areas instead of the sum.
    2985             :       !        The fluxes work out correctly in the end.
    2986             :       !
    2987             :       ! Also compute the cumulative area transported across each edge.
    2988             :       ! If l_fixed_area = T, this area is compared to edgearea as a bug check.
    2989             :       ! If l_fixed_area = F, this area is passed as an output array.
    2990             :       !-------------------------------------------------------------------
    2991             : 
    2992    32372640 :       areasum(:,:) = c0
    2993             : 
    2994      321216 :       do ng = 1, ngroups
    2995      275328 :          icells(ng) = 0
    2996             : 
    2997    81541014 :          do ij = 1, icellsd
    2998    81219798 :             i = indxid(ij)
    2999    81219798 :             j = indxjd(ij)
    3000             : 
    3001     6488196 :             triarea(i,j,ng) = p5 * ( (xp(i,j,2,ng)-xp(i,j,1,ng)) *   &
    3002             :                                      (yp(i,j,3,ng)-yp(i,j,1,ng))   &   ! LCOV_EXCL_LINE
    3003             :                                    - (yp(i,j,2,ng)-yp(i,j,1,ng)) *   &   ! LCOV_EXCL_LINE
    3004             :                                      (xp(i,j,3,ng)-xp(i,j,1,ng)) )   &   ! LCOV_EXCL_LINE
    3005    81219798 :                                    * areafact(i,j,ng)
    3006             : 
    3007    81219798 :             if (abs(triarea(i,j,ng)) < eps16*areafac_c(i,j)) then
    3008    41522255 :                triarea(i,j,ng) = c0
    3009             :             else
    3010    39697543 :                icells(ng) = icells(ng) + 1
    3011    39697543 :                ic = icells(ng)
    3012    39697543 :                indxi(ic,ng) = i
    3013    39697543 :                indxj(ic,ng) = j
    3014             :             endif
    3015             : 
    3016    81495126 :             areasum(i,j) = areasum(i,j) + triarea(i,j,ng)
    3017             : 
    3018             :          enddo                  ! ij
    3019             :       enddo                     ! ng
    3020             : 
    3021       45888 :       if (l_fixed_area) then
    3022             :          if (bugcheck) then   ! set bugcheck = F to speed up code
    3023             :             do ij = 1, icellsd
    3024             :                i = indxid(ij)
    3025             :                j = indxjd(ij)
    3026             :                if ( abs(areasum(i,j) - edgearea(i,j)) > eps13*areafac_c(i,j) .and. abs(edgearea(i,j)) > c0 ) then
    3027             :                   write(nu_diag,*) ''
    3028             :                   write(nu_diag,*) 'Areas do not add up: m, i, j, edge =',   &
    3029             :                            my_task, i, j, trim(edge)
    3030             :                   write(nu_diag,*) 'edgearea =', edgearea(i,j)
    3031             :                   write(nu_diag,*) 'areasum =', areasum(i,j)
    3032             :                   write(nu_diag,*) 'areafac_c =', areafac_c(i,j)
    3033             :                   write(nu_diag,*) ''
    3034             :                   write(nu_diag,*) 'Triangle areas:'
    3035             :                   do ng = 1, ngroups   ! not vector friendly
    3036             :                      if (abs(triarea(i,j,ng)) > eps16*abs(areafact(i,j,ng))) then
    3037             :                         write(nu_diag,*) ng, triarea(i,j,ng)
    3038             :                      endif
    3039             :                  enddo
    3040             :                endif
    3041             :             enddo
    3042             :          endif          ! bugcheck
    3043             : 
    3044             :       else            ! l_fixed_area = F
    3045    13582521 :          do ij = 1, icellsd
    3046    13536633 :             i = indxid(ij)
    3047    13536633 :             j = indxjd(ij)
    3048    13582521 :             edgearea(i,j) = areasum(i,j)
    3049             :          enddo
    3050             :       endif     ! l_fixed_area
    3051             : 
    3052             :       !-------------------------------------------------------------------
    3053             :       ! Transform triangle vertices to a scaled coordinate system centered
    3054             :       !  in the cell containing the triangle.
    3055             :       !-------------------------------------------------------------------
    3056             : 
    3057       45888 :       if (trim(edge) == 'north') then
    3058      160608 :          do ng = 1, ngroups
    3059      573600 :             do nv = 1, nvert
    3060    59849262 :                do ij = 1, icells(ng)
    3061    59298606 :                   i = indxi(ij,ng)
    3062    59298606 :                   j = indxj(ij,ng)
    3063    59298606 :                   ishift = iflux(i,j,ng) - i
    3064    59298606 :                   jshift = jflux(i,j,ng) - j
    3065    59298606 :                   xp(i,j,nv,ng) = xp(i,j,nv,ng) - c1*ishift
    3066    59711598 :                   yp(i,j,nv,ng) = yp(i,j,nv,ng) + p5 - c1*jshift
    3067             :                enddo            ! ij
    3068             :             enddo               ! nv
    3069             :          enddo                  ! ng
    3070             :       else                      ! east edge
    3071      160608 :          do ng = 1, ngroups
    3072      573600 :             do nv = 1, nvert
    3073    60344679 :                do ij = 1, icells(ng)
    3074    59794023 :                   i = indxi(ij,ng)
    3075    59794023 :                   j = indxj(ij,ng)
    3076    59794023 :                   ishift = iflux(i,j,ng) - i
    3077    59794023 :                   jshift = jflux(i,j,ng) - j
    3078             :                   ! Note rotation of pi/2 here
    3079    59794023 :                   w1 = xp(i,j,nv,ng)
    3080    59794023 :                   xp(i,j,nv,ng) =  yp(i,j,nv,ng) + p5 - c1*ishift
    3081    60207015 :                   yp(i,j,nv,ng) = -w1 - c1*jshift
    3082             :                enddo            ! ij
    3083             :             enddo               ! nv
    3084             :          enddo                  ! ng
    3085             :       endif
    3086             : 
    3087             :       if (bugcheck) then
    3088             :          if (trim(edge) == 'north') then
    3089             :             ib = ilo
    3090             :             jb = jlo-1
    3091             :          else ! east edge
    3092             :             ib = ilo-1
    3093             :             jb = jlo
    3094             :          endif
    3095             :          do ng = 1, ngroups
    3096             :          do nv = 1, nvert
    3097             :             do j = jb, jhi
    3098             :             do i = ib, ihi
    3099             :                if (abs(triarea(i,j,ng)) > puny) then
    3100             :                   if (abs(xp(i,j,nv,ng)) > p5+puny) then
    3101             :                      write(nu_diag,*) ''
    3102             :                      write(nu_diag,*) 'WARNING: xp =', xp(i,j,nv,ng)
    3103             :                      write(nu_diag,*) 'm, i, j, ng, nv =', my_task, i, j, ng, nv
    3104             : !                     write(nu_diag,*) 'yil,xdl,xcl,ydl=',yil,xdl,xcl,ydl
    3105             : !                     write(nu_diag,*) 'yir,xdr,xcr,ydr=',yir,xdr,xcr,ydr
    3106             : !                     write(nu_diag,*) 'ydm=',ydm
    3107             : !                      stop
    3108             :                   endif
    3109             :                   if (abs(yp(i,j,nv,ng)) > p5+puny) then
    3110             :                      write(nu_diag,*) ''
    3111             :                      write(nu_diag,*) 'WARNING: yp =', yp(i,j,nv,ng)
    3112             :                      write(nu_diag,*) 'm, i, j, ng, nv =', my_task, i, j, ng, nv
    3113             :                   endif
    3114             :                endif   ! triarea
    3115             :             enddo
    3116             :             enddo
    3117             :          enddo
    3118             :          enddo
    3119             :       endif  ! bugcheck
    3120             : 
    3121       45888 :       end subroutine locate_triangles
    3122             : 
    3123             : !=======================================================================
    3124             : !
    3125             : ! For each triangle, find the coordinates of the quadrature points needed
    3126             : !  to compute integrals of linear, quadratic, or cubic polynomials,
    3127             : !  using formulas from A.H. Stroud, Approximate Calculation of Multiple
    3128             : !  Integrals, Prentice-Hall, 1971.  (Section 8.8, formula 3.1.)
    3129             : ! Linear functions can be integrated exactly by evaluating the function
    3130             : !  at just one point (the midpoint).  Quadratic functions require
    3131             : !  3 points, and cubics require 4 points.
    3132             : ! The default is cubic, but the code can be sped up slightly using
    3133             : !  linear or quadratic integrals, usually with little loss of accuracy.
    3134             : !
    3135             : ! The formulas are as follows:
    3136             : !
    3137             : ! I1 = integral of f(x,y)*dA
    3138             : !    = A * f(x0,y0)
    3139             : ! where A is the traingle area and (x0,y0) is the midpoint.
    3140             : !
    3141             : ! I2 = A * (f(x1,y1) + f(x2,y2) + f(x3,y3))
    3142             : ! where these three points are located halfway between the midpoint
    3143             : ! and the three vertics of the triangle.
    3144             : !
    3145             : ! I3 = A * [ -9/16 *  f(x0,y0)
    3146             : !           + 25/48 * (f(x1,y1) + f(x2,y2) + f(x3,y3))]
    3147             : ! where (x0,y0) is the midpoint, and the other three points are
    3148             : ! located 2/5 of the way from the midpoint to the three vertices.
    3149             : !
    3150             : ! author William H. Lipscomb, LANL
    3151             : 
    3152       45888 :       subroutine triangle_coordinates (nx_block,       ny_block,  &
    3153             :                                        integral_order, icells,    &   ! LCOV_EXCL_LINE
    3154             :                                        indxi,          indxj,     &   ! LCOV_EXCL_LINE
    3155       45888 :                                        xp,             yp)
    3156             : 
    3157             :       integer (kind=int_kind), intent(in) ::   &
    3158             :          nx_block, ny_block, & ! block dimensions   ! LCOV_EXCL_LINE
    3159             :          integral_order      ! polynomial order for quadrature integrals
    3160             : 
    3161             :       integer (kind=int_kind), dimension (ngroups), intent(in) ::     &
    3162             :          icells              ! number of cells where triarea > puny
    3163             : 
    3164             :       integer (kind=int_kind), dimension (nx_block*ny_block,ngroups), intent(in) :: &
    3165             :          indxi , & ! compressed index in i-direction   ! LCOV_EXCL_LINE
    3166             :          indxj   ! compressed index in j-direction
    3167             : 
    3168             :       real (kind=dbl_kind), intent(inout), dimension (nx_block, ny_block, 0:nvert, ngroups) :: &
    3169             :          xp, yp          ! coordinates of triangle points
    3170             : 
    3171             :       ! local variables
    3172             : 
    3173             :       integer (kind=int_kind) ::   &
    3174             :          i, j, ij          , & ! horizontal indices   ! LCOV_EXCL_LINE
    3175             :          ng                  ! triangle index
    3176             : 
    3177             :       character(len=*), parameter :: subname = '(triangle_coordinates)'
    3178             : 
    3179       45888 :       if (integral_order == 1) then ! linear (1-point formula)
    3180             : 
    3181           0 :          do ng = 1, ngroups
    3182           0 :          do ij = 1, icells(ng)
    3183           0 :             i = indxi(ij,ng)
    3184           0 :             j = indxj(ij,ng)
    3185             : 
    3186             :             ! coordinates of midpoint
    3187           0 :             xp(i,j,0,ng) = p333   &
    3188           0 :                         * (xp(i,j,1,ng) + xp(i,j,2,ng) + xp(i,j,3,ng))
    3189           0 :             yp(i,j,0,ng) = p333   &
    3190           0 :                         * (yp(i,j,1,ng) + yp(i,j,2,ng) + yp(i,j,3,ng))
    3191             : 
    3192             :          enddo                  ! ij
    3193             :          enddo                  ! ng
    3194             : 
    3195       45888 :       elseif (integral_order == 2) then ! quadratic (3-point formula)
    3196             : 
    3197           0 :          do ng = 1, ngroups
    3198           0 :          do ij = 1, icells(ng)
    3199           0 :             i = indxi(ij,ng)
    3200           0 :             j = indxj(ij,ng)
    3201             : 
    3202             :             ! coordinates of midpoint
    3203           0 :             xp(i,j,0,ng) = p333   &
    3204           0 :                         * (xp(i,j,1,ng) + xp(i,j,2,ng) + xp(i,j,3,ng))
    3205           0 :             yp(i,j,0,ng) = p333   &
    3206           0 :                         * (yp(i,j,1,ng) + yp(i,j,2,ng) + yp(i,j,3,ng))
    3207             : 
    3208             :             ! coordinates of the 3 points needed for integrals
    3209             : 
    3210           0 :             xp(i,j,1,ng) = p5*xp(i,j,1,ng) + p5*xp(i,j,0,ng)
    3211           0 :             yp(i,j,1,ng) = p5*yp(i,j,1,ng) + p5*yp(i,j,0,ng)
    3212             : 
    3213           0 :             xp(i,j,2,ng) = p5*xp(i,j,2,ng) + p5*xp(i,j,0,ng)
    3214           0 :             yp(i,j,2,ng) = p5*yp(i,j,2,ng) + p5*yp(i,j,0,ng)
    3215             : 
    3216           0 :             xp(i,j,3,ng) = p5*xp(i,j,3,ng) + p5*xp(i,j,0,ng)
    3217           0 :             yp(i,j,3,ng) = p5*yp(i,j,3,ng) + p5*yp(i,j,0,ng)
    3218             : 
    3219             :          enddo                  ! ij
    3220             :          enddo                  ! ng
    3221             : 
    3222             :       else                      ! cubic (4-point formula)
    3223             : 
    3224      321216 :          do ng = 1, ngroups
    3225    40018759 :          do ij = 1, icells(ng)
    3226    39697543 :             i = indxi(ij,ng)
    3227    39697543 :             j = indxj(ij,ng)
    3228             : 
    3229             :             ! coordinates of midpoint
    3230     2884556 :             xp(i,j,0,ng) = p333   &
    3231    39697543 :                         * (xp(i,j,1,ng) + xp(i,j,2,ng) + xp(i,j,3,ng))
    3232     2884556 :             yp(i,j,0,ng) = p333   &
    3233    39697543 :                         * (yp(i,j,1,ng) + yp(i,j,2,ng) + yp(i,j,3,ng))
    3234             : 
    3235             :             ! coordinates of the other 3 points needed for integrals
    3236             : 
    3237    39697543 :             xp(i,j,1,ng) = p4*xp(i,j,1,ng) + p6*xp(i,j,0,ng)
    3238    39697543 :             yp(i,j,1,ng) = p4*yp(i,j,1,ng) + p6*yp(i,j,0,ng)
    3239             : 
    3240    39697543 :             xp(i,j,2,ng) = p4*xp(i,j,2,ng) + p6*xp(i,j,0,ng)
    3241    39697543 :             yp(i,j,2,ng) = p4*yp(i,j,2,ng) + p6*yp(i,j,0,ng)
    3242             : 
    3243    39697543 :             xp(i,j,3,ng) = p4*xp(i,j,3,ng) + p6*xp(i,j,0,ng)
    3244    39972871 :             yp(i,j,3,ng) = p4*yp(i,j,3,ng) + p6*yp(i,j,0,ng)
    3245             : 
    3246             :          enddo                  ! ij
    3247             :          enddo                  ! ng
    3248             : 
    3249             :       endif
    3250             : 
    3251       45888 :       end subroutine triangle_coordinates
    3252             : 
    3253             : !=======================================================================
    3254             : !
    3255             : ! Compute the transports across each edge by integrating the mass
    3256             : ! and tracers over each departure triangle.
    3257             : ! Input variables have the same meanings as in the main subroutine.
    3258             : ! Repeated use of certain sums makes the calculation more efficient.
    3259             : ! Integral formulas are described in triangle_coordinates subroutine.
    3260             : !
    3261             : ! author William H. Lipscomb, LANL
    3262             : 
    3263      275328 :       subroutine transport_integrals (nx_block,       ny_block,    &
    3264             :                                       ntrace,         icells,      &   ! LCOV_EXCL_LINE
    3265             :                                       indxi,          indxj,       &   ! LCOV_EXCL_LINE
    3266             :                                       tracer_type,    depend,      &   ! LCOV_EXCL_LINE
    3267             :                                       integral_order, triarea,     &   ! LCOV_EXCL_LINE
    3268             :                                       iflux,          jflux,       &   ! LCOV_EXCL_LINE
    3269             :                                       xp,             yp,          &   ! LCOV_EXCL_LINE
    3270             :                                       mc,             mx,          &   ! LCOV_EXCL_LINE
    3271             :                                       my,             mflx,        &   ! LCOV_EXCL_LINE
    3272             :                                       tc,             tx,          &   ! LCOV_EXCL_LINE
    3273      458880 :                                       ty,             mtflx)
    3274             : 
    3275             :       integer (kind=int_kind), intent(in) ::   &
    3276             :          nx_block, ny_block  , & ! block dimensions   ! LCOV_EXCL_LINE
    3277             :          ntrace              , & ! number of tracers in use   ! LCOV_EXCL_LINE
    3278             :          integral_order   ! polynomial order for quadrature integrals
    3279             : 
    3280             :       integer (kind=int_kind), dimension (ntrace), intent(in) ::     &
    3281             :          tracer_type       , & ! = 1, 2, or 3 (see comments above)   ! LCOV_EXCL_LINE
    3282             :          depend              ! tracer dependencies (see above)
    3283             : 
    3284             :       integer (kind=int_kind), dimension (ngroups), intent(in) ::     &
    3285             :          icells           ! number of cells where triarea > puny
    3286             : 
    3287             :       integer (kind=int_kind), dimension (nx_block*ny_block,ngroups), intent(in) :: &
    3288             :          indxi , & ! compressed index in i-direction   ! LCOV_EXCL_LINE
    3289             :          indxj   ! compressed index in j-direction
    3290             : 
    3291             :       real (kind=dbl_kind), intent(in), dimension (nx_block, ny_block, 0:nvert, ngroups) :: &
    3292             :          xp, yp           ! coordinates of triangle points
    3293             : 
    3294             :       real (kind=dbl_kind), intent(in), dimension (nx_block, ny_block, ngroups) :: &
    3295             :          triarea          ! triangle area
    3296             : 
    3297             :       integer (kind=int_kind), intent(in), dimension (nx_block, ny_block, ngroups) :: &
    3298             :          iflux     ,&   ! LCOV_EXCL_LINE
    3299             :          jflux
    3300             : 
    3301             :       real (kind=dbl_kind), intent(in), dimension (nx_block, ny_block) :: &
    3302             :          mc, mx, my
    3303             : 
    3304             :       real (kind=dbl_kind), intent(out), dimension (nx_block, ny_block) :: &
    3305             :          mflx
    3306             : 
    3307             :       real (kind=dbl_kind), intent(in), dimension (nx_block, ny_block, ntrace), optional :: &
    3308             :          tc, tx, ty
    3309             : 
    3310             :       real (kind=dbl_kind), intent(out), dimension (nx_block, ny_block, ntrace), optional :: &
    3311             :          mtflx
    3312             : 
    3313             :       ! local variables
    3314             : 
    3315             :       integer (kind=int_kind) ::   &
    3316             :          i, j, ij      , & ! horizontal indices of edge   ! LCOV_EXCL_LINE
    3317             :          i2, j2        , & ! horizontal indices of cell contributing transport   ! LCOV_EXCL_LINE
    3318             :          ng            , & ! triangle index   ! LCOV_EXCL_LINE
    3319             :          nt, nt1         ! tracer indices
    3320             : 
    3321             :       real (kind=dbl_kind) ::   &
    3322             :          m0, m1, m2, m3         , & ! mass field at internal points   ! LCOV_EXCL_LINE
    3323       69120 :          w0, w1, w2, w3           ! work variables
    3324             : 
    3325             :       real (kind=dbl_kind), dimension (nx_block, ny_block) ::   &
    3326             :          msum, mxsum, mysum     , & ! sum of mass, mass*x, and mass*y   ! LCOV_EXCL_LINE
    3327   180539136 :          mxxsum, mxysum, myysum   ! sum of mass*x*x, mass*x*y, mass*y*y
    3328             : 
    3329             :       real (kind=dbl_kind), dimension (nx_block, ny_block, ntrace) ::   &
    3330             :          mtsum            , & ! sum of mass*tracer   ! LCOV_EXCL_LINE
    3331             :          mtxsum           , & ! sum of mass*tracer*x   ! LCOV_EXCL_LINE
    3332  1562247936 :          mtysum             ! sum of mass*tracer*y
    3333             : 
    3334             :       character(len=*), parameter :: subname = '(transport_integrals)'
    3335             : 
    3336             :       !-------------------------------------------------------------------
    3337             :       ! Initialize
    3338             :       !-------------------------------------------------------------------
    3339             : 
    3340   194235840 :       mflx(:,:) = c0
    3341      275328 :       if (present(mtflx)) then
    3342     6194880 :          do nt = 1, ntrace
    3343  4208672640 :             mtflx(:,:,nt) = c0
    3344             :          enddo
    3345             :       endif
    3346             : 
    3347             :       !-------------------------------------------------------------------
    3348             :       ! Main loop
    3349             :       !-------------------------------------------------------------------
    3350             : 
    3351     1927296 :       do ng = 1, ngroups
    3352             : 
    3353     1651968 :          if (integral_order == 1) then  ! linear (1-point formula)
    3354             : 
    3355           0 :             do ij = 1, icells(ng)
    3356           0 :                i = indxi(ij,ng)
    3357           0 :                j = indxj(ij,ng)
    3358             : 
    3359           0 :                i2 = iflux(i,j,ng)
    3360           0 :                j2 = jflux(i,j,ng)
    3361             : 
    3362             :                ! mass transports
    3363             : 
    3364           0 :                m0 = mc(i2,j2) + xp(i,j,0,ng)*mx(i2,j2)   &
    3365           0 :                               + yp(i,j,0,ng)*my(i2,j2)
    3366           0 :                msum(i,j) = m0
    3367             : 
    3368           0 :                mflx(i,j) = mflx(i,j) + triarea(i,j,ng)*msum(i,j)
    3369             : 
    3370             :                ! quantities needed for tracer transports
    3371           0 :                mxsum(i,j)  =         m0*xp(i,j,0,ng)
    3372           0 :                mxxsum(i,j) = mxsum(i,j)*xp(i,j,0,ng)
    3373           0 :                mxysum(i,j) = mxsum(i,j)*yp(i,j,0,ng)
    3374           0 :                mysum(i,j)  =         m0*yp(i,j,0,ng)
    3375           0 :                myysum(i,j) = mysum(i,j)*yp(i,j,0,ng)
    3376             :             enddo               ! ij
    3377             : 
    3378     1651968 :          elseif (integral_order == 2) then  ! quadratic (3-point formula)
    3379             : 
    3380           0 :             do ij = 1, icells(ng)
    3381           0 :                i = indxi(ij,ng)
    3382           0 :                j = indxj(ij,ng)
    3383             : 
    3384           0 :                i2 = iflux(i,j,ng)
    3385           0 :                j2 = jflux(i,j,ng)
    3386             : 
    3387             :                ! mass transports
    3388             :                ! Weighting factor of 1/3 is incorporated into the ice
    3389             :                ! area terms m1, m2, and m3.
    3390           0 :                m1 = p333 * (mc(i2,j2) + xp(i,j,1,ng)*mx(i2,j2)   &
    3391           0 :                                       + yp(i,j,1,ng)*my(i2,j2))
    3392           0 :                m2 = p333 * (mc(i2,j2) + xp(i,j,2,ng)*mx(i2,j2)   &
    3393           0 :                                       + yp(i,j,2,ng)*my(i2,j2))
    3394           0 :                m3 = p333 * (mc(i2,j2) + xp(i,j,3,ng)*mx(i2,j2)   &
    3395           0 :                                       + yp(i,j,3,ng)*my(i2,j2))
    3396           0 :                msum(i,j) = m1 + m2 + m3
    3397           0 :                mflx(i,j) = mflx(i,j) + triarea(i,j,ng)*msum(i,j)
    3398             : 
    3399             :                ! quantities needed for mass_tracer transports
    3400           0 :                w1 = m1 * xp(i,j,1,ng)
    3401           0 :                w2 = m2 * xp(i,j,2,ng)
    3402           0 :                w3 = m3 * xp(i,j,3,ng)
    3403             : 
    3404           0 :                mxsum(i,j) = w1 + w2 + w3
    3405             : 
    3406           0 :                mxxsum(i,j) = w1*xp(i,j,1,ng) + w2*xp(i,j,2,ng)   &
    3407           0 :                            + w3*xp(i,j,3,ng)
    3408             : 
    3409           0 :                mxysum(i,j) = w1*yp(i,j,1,ng) + w2*yp(i,j,2,ng)   &
    3410           0 :                            + w3*yp(i,j,3,ng)
    3411             : 
    3412           0 :                w1 = m1 * yp(i,j,1,ng)
    3413           0 :                w2 = m2 * yp(i,j,2,ng)
    3414           0 :                w3 = m3 * yp(i,j,3,ng)
    3415             : 
    3416           0 :                mysum(i,j) = w1 + w2 + w3
    3417             : 
    3418           0 :                myysum(i,j) = w1*yp(i,j,1,ng) + w2*yp(i,j,2,ng)   &
    3419           0 :                            + w3*yp(i,j,3,ng)
    3420             :             enddo               ! ij
    3421             : 
    3422             :          else                   ! cubic (4-point formula)
    3423             : 
    3424   239837226 :             do ij = 1, icells(ng)
    3425   238185258 :                i = indxi(ij,ng)
    3426   238185258 :                j = indxj(ij,ng)
    3427             : 
    3428   238185258 :                i2 = iflux(i,j,ng)
    3429   238185258 :                j2 = jflux(i,j,ng)
    3430             : 
    3431             :                ! mass transports
    3432             : 
    3433             :                ! Weighting factors are incorporated into the
    3434             :                ! terms m0, m1, m2, and m3.
    3435    17307336 :                m0 = p5625m * (mc(i2,j2) + xp(i,j,0,ng)*mx(i2,j2)   &
    3436   238185258 :                                         + yp(i,j,0,ng)*my(i2,j2))
    3437    17307336 :                m1 = p52083 * (mc(i2,j2) + xp(i,j,1,ng)*mx(i2,j2)   &
    3438   238185258 :                                         + yp(i,j,1,ng)*my(i2,j2))
    3439    17307336 :                m2 = p52083 * (mc(i2,j2) + xp(i,j,2,ng)*mx(i2,j2)   &
    3440   238185258 :                                         + yp(i,j,2,ng)*my(i2,j2))
    3441    17307336 :                m3 = p52083 * (mc(i2,j2) + xp(i,j,3,ng)*mx(i2,j2)   &
    3442   238185258 :                                         + yp(i,j,3,ng)*my(i2,j2))
    3443   238185258 :                msum(i,j) = m0 + m1 + m2 + m3
    3444   238185258 :                mflx(i,j) = mflx(i,j) + triarea(i,j,ng)*msum(i,j)
    3445             : 
    3446             :                ! quantities needed for tracer transports
    3447   238185258 :                w0 = m0 * xp(i,j,0,ng)
    3448   238185258 :                w1 = m1 * xp(i,j,1,ng)
    3449   238185258 :                w2 = m2 * xp(i,j,2,ng)
    3450   238185258 :                w3 = m3 * xp(i,j,3,ng)
    3451             : 
    3452   238185258 :                mxsum(i,j) = w0 + w1 + w2 + w3
    3453             : 
    3454    17307336 :                mxxsum(i,j) = w0*xp(i,j,0,ng) + w1*xp(i,j,1,ng)   &
    3455   238185258 :                            + w2*xp(i,j,2,ng) + w3*xp(i,j,3,ng)
    3456             : 
    3457    17307336 :                mxysum(i,j) = w0*yp(i,j,0,ng) + w1*yp(i,j,1,ng)   &
    3458   238185258 :                            + w2*yp(i,j,2,ng) + w3*yp(i,j,3,ng)
    3459             : 
    3460   238185258 :                w0 = m0 * yp(i,j,0,ng)
    3461   238185258 :                w1 = m1 * yp(i,j,1,ng)
    3462   238185258 :                w2 = m2 * yp(i,j,2,ng)
    3463   238185258 :                w3 = m3 * yp(i,j,3,ng)
    3464             : 
    3465   238185258 :                mysum(i,j) = w0 + w1 + w2 + w3
    3466             : 
    3467    17307336 :                myysum(i,j) = w0*yp(i,j,0,ng) + w1*yp(i,j,1,ng)   &
    3468   239837226 :                            + w2*yp(i,j,2,ng) + w3*yp(i,j,3,ng)
    3469             : 
    3470             :             enddo               ! ij
    3471             : 
    3472             :          endif                  ! integral_order
    3473             : 
    3474             :          ! mass * tracer transports
    3475             : 
    3476     1927296 :          if (present(mtflx)) then
    3477             : 
    3478    37169280 :             do nt = 1, ntrace
    3479    37169280 :                if (tracer_type(nt)==1) then ! does not depend on another tracer
    3480             : 
    3481  1199186130 :                   do ij = 1, icells(ng)
    3482  1190926290 :                      i = indxi(ij,ng)
    3483  1190926290 :                      j = indxj(ij,ng)
    3484             : 
    3485  1190926290 :                      i2 = iflux(i,j,ng)
    3486  1190926290 :                      j2 = jflux(i,j,ng)
    3487             : 
    3488    86536680 :                      mtsum(i,j,nt) =  msum(i,j) * tc(i2,j2,nt)   &
    3489             :                                    + mxsum(i,j) * tx(i2,j2,nt)   &   ! LCOV_EXCL_LINE
    3490  1190926290 :                                    + mysum(i,j) * ty(i2,j2,nt)
    3491             : 
    3492    86536680 :                      mtflx(i,j,nt) = mtflx(i,j,nt)   &
    3493  1190926290 :                                  + triarea(i,j,ng) * mtsum(i,j,nt)
    3494             : 
    3495             :                      ! quantities needed for dependent tracers
    3496             : 
    3497    86536680 :                      mtxsum(i,j,nt) =  mxsum(i,j) * tc(i2,j2,nt)   &
    3498             :                                     + mxxsum(i,j) * tx(i2,j2,nt)   &   ! LCOV_EXCL_LINE
    3499  1190926290 :                                     + mxysum(i,j) * ty(i2,j2,nt)
    3500             : 
    3501    86536680 :                      mtysum(i,j,nt) =  mysum(i,j) * tc(i2,j2,nt)   &
    3502             :                                     + mxysum(i,j) * tx(i2,j2,nt)   &   ! LCOV_EXCL_LINE
    3503  1199186130 :                                     + myysum(i,j) * ty(i2,j2,nt)
    3504             :                   enddo         ! ij
    3505             : 
    3506    27532800 :                elseif (tracer_type(nt)==2) then ! depends on another tracer
    3507    24779520 :                   nt1 = depend(nt)
    3508             : 
    3509  3597558390 :                   do ij = 1, icells(ng)
    3510  3572778870 :                      i = indxi(ij,ng)
    3511  3572778870 :                      j = indxj(ij,ng)
    3512             : 
    3513  3572778870 :                      i2 = iflux(i,j,ng)
    3514  3572778870 :                      j2 = jflux(i,j,ng)
    3515             : 
    3516   259610040 :                      mtsum(i,j,nt) =  mtsum(i,j,nt1) * tc(i2,j2,nt)   &
    3517             :                                    + mtxsum(i,j,nt1) * tx(i2,j2,nt)   &   ! LCOV_EXCL_LINE
    3518  3572778870 :                                    + mtysum(i,j,nt1) * ty(i2,j2,nt)
    3519             : 
    3520   259610040 :                      mtflx(i,j,nt) = mtflx(i,j,nt)   &
    3521  3597558390 :                                    + triarea(i,j,ng) * mtsum(i,j,nt)
    3522             :                   enddo         ! ij
    3523             : 
    3524             : 
    3525     2753280 :                elseif (tracer_type(nt)==3) then ! depends on two tracers
    3526     2753280 :                   nt1 = depend(nt)
    3527             : 
    3528   399728710 :                   do ij = 1, icells(ng)
    3529   396975430 :                      i = indxi(ij,ng)
    3530   396975430 :                      j = indxj(ij,ng)
    3531             : 
    3532   396975430 :                      i2 = iflux(i,j,ng)
    3533   396975430 :                      j2 = jflux(i,j,ng)
    3534             : 
    3535             :                      ! upwind approx (tx=ty=0) for type 3 tracers
    3536   396975430 :                      mtsum(i,j,nt) =  mtsum(i,j,nt1) * tc(i2,j2,nt)
    3537             : 
    3538    28845560 :                      mtflx(i,j,nt) = mtflx(i,j,nt)   &
    3539   399728710 :                                    + triarea(i,j,ng) * mtsum(i,j,nt)
    3540             :                   enddo         ! ij
    3541             : 
    3542             :                endif            ! tracer type
    3543             :             enddo               ! ntrace
    3544             :          endif                  ! present(mtflx)
    3545             :       enddo                     ! ng
    3546             : 
    3547      963648 :       end subroutine transport_integrals
    3548             : 
    3549             : !=======================================================================
    3550             : !
    3551             : ! Given transports through cell edges, compute new area and tracers.
    3552             : !
    3553             : ! author William H. Lipscomb, LANL
    3554             : 
    3555      137664 :       subroutine update_fields (nx_block,    ny_block,   &
    3556             :                                 ilo, ihi,    jlo, jhi,   &   ! LCOV_EXCL_LINE
    3557             :                                 ntrace,                  &   ! LCOV_EXCL_LINE
    3558             :                                 tracer_type, depend,     &   ! LCOV_EXCL_LINE
    3559             :                                 tarear,      l_stop,     &   ! LCOV_EXCL_LINE
    3560             :                                 istop,       jstop,      &   ! LCOV_EXCL_LINE
    3561             :                                 mflxe,       mflxn,      &   ! LCOV_EXCL_LINE
    3562             :                                 mm,                      &   ! LCOV_EXCL_LINE
    3563             :                                 mtflxe,      mtflxn,     &   ! LCOV_EXCL_LINE
    3564      114720 :                                 tm)
    3565             : 
    3566             :       integer (kind=int_kind), intent(in) ::   &
    3567             :          nx_block, ny_block, & ! block dimensions   ! LCOV_EXCL_LINE
    3568             :          ilo,ihi,jlo,jhi   , & ! beginning and end of physical domain   ! LCOV_EXCL_LINE
    3569             :          ntrace              ! number of tracers in use
    3570             : 
    3571             :       integer (kind=int_kind), dimension (ntrace), intent(in) ::     &
    3572             :          tracer_type       , & ! = 1, 2, or 3 (see comments above)   ! LCOV_EXCL_LINE
    3573             :          depend              ! tracer dependencies (see above)
    3574             : 
    3575             :       real (kind=dbl_kind), dimension (nx_block, ny_block), intent(in) ::   &
    3576             :          mflxe, mflxn   , & ! mass transport across east and north cell edges   ! LCOV_EXCL_LINE
    3577             :          tarear           ! 1/tarea
    3578             : 
    3579             :       real (kind=dbl_kind), dimension (nx_block, ny_block), intent(inout) ::   &
    3580             :          mm               ! mass field (mean)
    3581             : 
    3582             :       real (kind=dbl_kind), dimension (nx_block, ny_block, ntrace), intent(in), optional ::   &
    3583             :          mtflxe, mtflxn   ! mass*tracer transport across E and N cell edges
    3584             : 
    3585             :       real (kind=dbl_kind), dimension (nx_block, ny_block, ntrace), intent(inout), optional ::   &
    3586             :          tm               ! tracer fields
    3587             : 
    3588             :       logical (kind=log_kind), intent(inout) ::   &
    3589             :          l_stop           ! if true, abort on return
    3590             : 
    3591             :       integer (kind=int_kind), intent(inout) ::   &
    3592             :          istop, jstop     ! indices of grid cell where model aborts
    3593             : 
    3594             :       ! local variables
    3595             : 
    3596             :       integer (kind=int_kind) ::   &
    3597             :          i, j           , & ! horizontal indices   ! LCOV_EXCL_LINE
    3598             :          nt, nt1, nt2     ! tracer indices
    3599             : 
    3600             :       real (kind=dbl_kind), dimension(nx_block,ny_block,ntrace) ::   &
    3601   781089408 :          mtold            ! old mass*tracer
    3602             : 
    3603             :       real (kind=dbl_kind) ::   &
    3604             :          puny, &          !   ! LCOV_EXCL_LINE
    3605       34560 :          w1               ! work variable
    3606             : 
    3607             :       integer (kind=int_kind), dimension(nx_block*ny_block) ::   &
    3608             :          indxi          , & ! compressed indices in i and j directions   ! LCOV_EXCL_LINE
    3609      172224 :          indxj
    3610             : 
    3611             :       integer (kind=int_kind) ::   &
    3612             :          icells         , & !  number of cells with mm > 0.   ! LCOV_EXCL_LINE
    3613             :          ij               ! combined i/j horizontal index
    3614             : 
    3615             :       character(len=*), parameter :: subname = '(update_fields)'
    3616             : 
    3617             :       !-------------------------------------------------------------------
    3618             :       ! Save starting values of mass*tracer
    3619             :       !-------------------------------------------------------------------
    3620             : 
    3621      137664 :       call icepack_query_parameters(puny_out=puny)
    3622      137664 :       call icepack_warnings_flush(nu_diag)
    3623      137664 :       if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
    3624           0 :          file=__FILE__, line=__LINE__)
    3625             : 
    3626      137664 :       if (present(tm)) then
    3627     3097440 :          do nt = 1, ntrace
    3628     3097440 :             if (tracer_type(nt)==1) then ! does not depend on other tracers
    3629    21230640 :                do j = jlo, jhi
    3630   414807840 :                do i = ilo, ihi
    3631   414119520 :                   mtold(i,j,nt) = mm(i,j) * tm(i,j,nt)
    3632             :                enddo            ! i
    3633             :                enddo              ! j
    3634     2294400 :             elseif (tracer_type(nt)==2) then  ! depends on another tracer
    3635     2064960 :                nt1 = depend(nt)
    3636    63691920 :                do j = jlo, jhi
    3637  1244423520 :                do i = ilo, ihi
    3638  1242358560 :                   mtold(i,j,nt) = mm(i,j) * tm(i,j,nt1) * tm(i,j,nt)
    3639             :                enddo            ! i
    3640             :                enddo            ! j
    3641      229440 :             elseif (tracer_type(nt)==3) then  ! depends on two tracers
    3642      229440 :                nt1 = depend(nt)
    3643      229440 :                nt2 = depend(nt1)
    3644     7076880 :                do j = jlo, jhi
    3645   138269280 :                do i = ilo, ihi
    3646    41760000 :                   mtold(i,j,nt) = mm(i,j)    &
    3647   138039840 :                             * tm(i,j,nt2) * tm(i,j,nt1) * tm(i,j,nt)
    3648             :                enddo            ! i
    3649             :                enddo            ! j
    3650             :             endif               ! depend(nt) = 0
    3651             :          enddo                  ! nt
    3652             :       endif                     ! present(tm)
    3653             : 
    3654             :       !-------------------------------------------------------------------
    3655             :       ! Update mass field
    3656             :       !-------------------------------------------------------------------
    3657             : 
    3658     4246128 :       do j = jlo, jhi
    3659    82961568 :       do i = ilo, ihi
    3660             : 
    3661    50112000 :          w1 = mflxe(i,j) - mflxe(i-1,j  )   &
    3662   103771440 :             + mflxn(i,j) - mflxn(i  ,j-1)
    3663    78715440 :          mm(i,j) = mm(i,j) - w1*tarear(i,j)
    3664             : 
    3665    82823904 :          if (mm(i,j) < -puny) then    ! abort with negative value
    3666           0 :             l_stop = .true.
    3667           0 :             istop = i
    3668           0 :             jstop = j
    3669    78715440 :          elseif (mm(i,j) < c0) then   ! set to zero
    3670       86196 :             mm(i,j) = c0
    3671             :          endif
    3672             : 
    3673             :       enddo
    3674             :       enddo
    3675             : 
    3676      137664 :       if (l_stop) then
    3677           0 :          i = istop
    3678           0 :          j = jstop
    3679           0 :          w1 = mflxe(i,j) - mflxe(i-1,j  )   &
    3680           0 :             + mflxn(i,j) - mflxn(i  ,j-1)
    3681           0 :          write (nu_diag,*) ' '
    3682           0 :          write (nu_diag,*) 'New mass < 0, i, j =', i, j
    3683           0 :          write (nu_diag,*) 'Old mass =', mm(i,j) + w1*tarear(i,j)
    3684           0 :          write (nu_diag,*) 'New mass =', mm(i,j)
    3685           0 :          write (nu_diag,*) 'Net transport =', -w1*tarear(i,j)
    3686           0 :          return
    3687             :       endif
    3688             : 
    3689             :       !-------------------------------------------------------------------
    3690             :       ! Update tracers
    3691             :       !-------------------------------------------------------------------
    3692             : 
    3693      137664 :       if (present(tm)) then
    3694             : 
    3695      114720 :          icells = 0
    3696     3538440 :          do j = jlo, jhi
    3697    69134640 :          do i = ilo, ihi
    3698    69019920 :             if (mm(i,j) > c0) then ! grid cells with positive areas
    3699    33892021 :                icells = icells + 1
    3700    33892021 :                indxi(icells) = i
    3701    33892021 :                indxj(icells) = j
    3702             :             endif
    3703             :          enddo                  ! i
    3704             :          enddo                  ! j
    3705             : 
    3706     3097440 :          do nt = 1, ntrace
    3707             : 
    3708    91999440 :             do j = jlo, jhi
    3709  1797500640 :             do i = ilo, ihi
    3710  1794517920 :                tm(i,j,nt) = c0
    3711             :             enddo
    3712             :             enddo
    3713             : 
    3714     3097440 :             if (tracer_type(nt)==1) then ! does not depend on other tracers
    3715             : 
    3716   204040446 :                do ij = 1, icells
    3717   203352126 :                   i = indxi(ij)
    3718   203352126 :                   j = indxj(ij)
    3719             : 
    3720    37080468 :                   w1  = mtflxe(i,j,nt) - mtflxe(i-1,j  ,nt)   &
    3721   221892360 :                       + mtflxn(i,j,nt) - mtflxn(i  ,j-1,nt)
    3722    18540234 :                   tm(i,j,nt) = (mtold(i,j,nt) - w1*tarear(i,j))   &
    3723   204040446 :                                 / mm(i,j)
    3724             :                enddo            ! ij
    3725             : 
    3726     2294400 :             elseif (tracer_type(nt)==2) then ! depends on another tracer
    3727     2064960 :                nt1 = depend(nt)
    3728             : 
    3729   612121338 :                do ij = 1, icells
    3730   610056378 :                   i = indxi(ij)
    3731   610056378 :                   j = indxj(ij)
    3732             : 
    3733   612121338 :                   if (abs(tm(i,j,nt1)) > c0) then
    3734   110928632 :                      w1  = mtflxe(i,j,nt) - mtflxe(i-1,j  ,nt)   &
    3735   648459748 :                          + mtflxn(i,j,nt) - mtflxn(i  ,j-1,nt)
    3736    55464316 :                      tm(i,j,nt) = (mtold(i,j,nt) - w1*tarear(i,j))   &
    3737   592995432 :                                  / (mm(i,j) * tm(i,j,nt1))
    3738             :                   endif
    3739             : 
    3740             :                enddo            ! ij
    3741             : 
    3742      229440 :             elseif (tracer_type(nt)==3) then ! depends on two tracers
    3743      229440 :                nt1 = depend(nt)
    3744      229440 :                nt2 = depend(nt1)
    3745             : 
    3746    68013482 :                do ij = 1, icells
    3747    67784042 :                   i = indxi(ij)
    3748    67784042 :                   j = indxj(ij)
    3749             : 
    3750    73964120 :                   if (abs(tm(i,j,nt1)) > c0 .and.   &
    3751     6409518 :                       abs(tm(i,j,nt2)) > c0) then
    3752     9344144 :                      w1  = mtflxe(i,j,nt) - mtflxe(i-1,j  ,nt)   &
    3753    46485216 :                          + mtflxn(i,j,nt) - mtflxn(i  ,j-1,nt)
    3754     4672072 :                      tm(i,j,nt) = (mtold(i,j,nt) - w1*tarear(i,j))   &
    3755    41813144 :                               / (mm(i,j) * tm(i,j,nt2) * tm(i,j,nt1))
    3756             :                   endif
    3757             :                enddo            ! ij
    3758             : 
    3759             :             endif               ! tracer_type
    3760             :          enddo                  ! nt
    3761             :       endif                     ! present(tm)
    3762             : 
    3763      367104 :       end subroutine update_fields
    3764             : 
    3765             : !=======================================================================
    3766             : 
    3767             :       end module ice_transport_remap
    3768             : 
    3769             : !=======================================================================

Generated by: LCOV version 1.14-6-g40580cd