@@ -1378,7 +1378,6 @@ subroutine eigencalving(domain, err)
13781378 real (kind=RKIND), dimension(:), pointer :: eigencalvingParameter
13791379 real (kind=RKIND), dimension(:), pointer :: calvingVelocity
13801380 real (kind=RKIND), dimension(:), pointer :: eMax, eMin
1381- real (kind=RKIND), dimension(:), pointer :: angleEdge
13821381 real (kind=RKIND), dimension(:), pointer :: thickness
13831382 real (kind=RKIND), dimension(:), pointer :: calvingThickness
13841383 real (kind=RKIND), pointer :: calvingCFLdt
@@ -1429,7 +1428,6 @@ subroutine eigencalving(domain, err)
14291428
14301429 ! get fields
14311430 call mpas_pool_get_array(meshPool, ' deltat' , deltat)
1432- call mpas_pool_get_array(meshPool, ' angleEdge' , angleEdge)
14331431 call mpas_pool_get_array(geometryPool, ' cellMask' , cellMask)
14341432 call mpas_pool_get_array(geometryPool, ' calvingFrontMask' , calvingFrontMask)
14351433 call mpas_pool_get_array(geometryPool, ' eigencalvingParameter' , eigencalvingParameter)
@@ -1602,7 +1600,6 @@ subroutine specified_calving_velocity(domain, err)
16021600 character (len=StrKIND), pointer :: config_calving_specified_source
16031601 real (kind=RKIND), dimension(:), pointer :: calvingVelocity
16041602 real (kind=RKIND), dimension(:), pointer :: calvingVelocityData
1605- real (kind=RKIND), dimension(:), pointer :: angleEdge
16061603 real (kind=RKIND), dimension(:), pointer :: thickness
16071604 real (kind=RKIND), dimension(:), pointer :: calvingThickness
16081605 real (kind=RKIND), pointer :: calvingCFLdt
@@ -1643,7 +1640,6 @@ subroutine specified_calving_velocity(domain, err)
16431640
16441641 ! get fields
16451642 call mpas_pool_get_array(meshPool, ' deltat' , deltat)
1646- call mpas_pool_get_array(meshPool, ' angleEdge' , angleEdge)
16471643 call mpas_pool_get_array(geometryPool, ' cellMask' , cellMask)
16481644 call mpas_pool_get_array(geometryPool, ' calvingFrontMask' , calvingFrontMask)
16491645 call mpas_pool_get_array(geometryPool, ' calvingVelocity' , calvingVelocity)
@@ -2495,7 +2491,7 @@ subroutine li_apply_front_ablation_velocity(meshPool, geometryPool, velocityPool
24952491 real (kind=RKIND), pointer :: config_calving_error_threshold
24962492 logical, pointer :: config_distribute_unablatedVolumeDynCell
24972493 real (kind=RKIND), dimension(:), pointer :: dvEdge, dcEdge
2498- real (kind=RKIND), dimension(:), pointer :: angleEdge
2494+ real (kind=RKIND), dimension(:), pointer :: xCell, yCell, xEdge, yEdge
24992495 real (kind=RKIND), dimension(:), pointer :: calvingVelocity, faceMeltSpeed
25002496 real (kind=RKIND), dimension(:), pointer :: areaCell
25012497 real (kind=RKIND), dimension(:,:), pointer :: uReconstructX
@@ -2536,7 +2532,10 @@ subroutine li_apply_front_ablation_velocity(meshPool, geometryPool, velocityPool
25362532 call mpas_pool_get_array(meshPool, ' cellsOnEdge' , cellsOnEdge)
25372533 call mpas_pool_get_array(meshPool, ' dvEdge' , dvEdge)
25382534 call mpas_pool_get_array(meshPool, ' dcEdge' , dcEdge)
2539- call mpas_pool_get_array(meshPool, ' angleEdge' , angleEdge)
2535+ call mpas_pool_get_array(meshPool, ' xCell' , xCell)
2536+ call mpas_pool_get_array(meshPool, ' yCell' , yCell)
2537+ call mpas_pool_get_array(meshPool, ' xEdge' , xEdge)
2538+ call mpas_pool_get_array(meshPool, ' yEdge' , yEdge)
25402539 call mpas_pool_get_dimension(meshPool, ' nEdges' , nEdges)
25412540 call mpas_pool_get_dimension(meshPool, ' nEdgesSolve' , nEdgesSolve)
25422541 call mpas_pool_get_dimension(meshPool, ' nCells' , nCells)
@@ -2850,10 +2849,9 @@ subroutine li_apply_front_ablation_velocity(meshPool, geometryPool, velocityPool
28502849 do iNeighbor = 1, nEdgesOnCell(iCell)
28512850 iEdge = edgesOnCell(iNeighbor, iCell)
28522851 jCell = cellsOnCell(iNeighbor, iCell)
2853- if (li_mask_is_margin(edgeMask(iEdge)) .and. & !< edge is a margin
2854- .not. li_mask_is_ice(cellMask(jCell)) .and. bedTopography(jCell) < config_sea_level & ! ensure margin is w/ocn
2855- ) then
2856- edgeLengthScaling = scale_edge_length(angleEdge(iEdge), uvelForAblation(iCell), vvelForAblation(iCell))
2852+ if (li_mask_is_margin(edgeMask(iEdge)) .or. &
2853+ (li_mask_is_ice(cellMask(jCell)) .and. bedTopography(jCell) > config_sea_level)) then
2854+ edgeLengthScaling = scale_edge_length(xCell(iCell), yCell(iCell), xEdge(iEdge), yEdge(iEdge), uvelForAblation(iCell), vvelForAblation(iCell))
28572855 requiredAblationVolumeNonDynEdge(iEdge) = ablationVelocity(iCell) * &
28582856 edgeLengthScaling * dvEdge(iEdge) * thicknessForAblation(iCell) * deltat
28592857 requiredAblationVolumeNonDynCell(iCell) = requiredAblationVolumeNonDynCell(iCell) + &
@@ -2913,9 +2911,10 @@ subroutine li_apply_front_ablation_velocity(meshPool, geometryPool, velocityPool
29132911 .and. li_mask_is_margin(cellMask(iCell)) ) then ! that is at the edge of the ice
29142912 do iNeighbor = 1, nEdgesOnCell(iCell)
29152913 jCell = cellsOnCell(iNeighbor, iCell)
2916- if ((.not. li_mask_is_ice(cellMask(jCell))) .and. (bedTopography(jCell) < config_sea_level)) then
2914+ if ((.not. li_mask_is_ice(cellMask(jCell))) .and. (bedTopography(jCell) < config_sea_level) .or. &
2915+ (bedTopography(jCell) > config_sea_level) ) then
29172916 iEdge = edgesOnCell(iNeighbor, iCell)
2918- edgeLengthScaling = scale_edge_length(angleEdge (iEdge), uvelForAblation(iCell), vvelForAblation(iCell))
2917+ edgeLengthScaling = scale_edge_length(xCell(iCell), yCell(iCell), xEdge(iEdge), yEdge (iEdge), uvelForAblation(iCell), vvelForAblation(iCell))
29192918 requiredAblationVolumeDynEdge(iEdge) = ablationVelocity(iCell) * &
29202919 edgeLengthScaling * dvEdge(iEdge) * thicknessForAblation(iCell) * deltat
29212920 endif
@@ -2939,7 +2938,7 @@ subroutine li_apply_front_ablation_velocity(meshPool, geometryPool, velocityPool
29392938 do iNeighbor = 1, nEdgesOnCell(iCell)
29402939 iEdge = edgesOnCell(iNeighbor, iCell)
29412940 if (li_mask_is_dynamic_ice(edgeMask(iEdge))) then
2942- edgeLengthScaling = scale_edge_length(angleEdge (iEdge), uvelForAblation(iCell), vvelForAblation(iCell))
2941+ edgeLengthScaling = scale_edge_length(xCell(iCell), yCell(iCell), xEdge(iEdge), yEdge (iEdge), uvelForAblation(iCell), vvelForAblation(iCell))
29432942 ablateLengthEdge = edgeLengthScaling * dvEdge(iEdge)
29442943 ablateLengthCell = ablateLengthCell + ablateLengthEdge
29452944 endif
@@ -2951,7 +2950,7 @@ subroutine li_apply_front_ablation_velocity(meshPool, geometryPool, velocityPool
29512950 iEdge = edgesOnCell(iNeighbor, iCell)
29522951 jCell = cellsOnCell(iNeighbor, iCell)
29532952 if (li_mask_is_dynamic_ice(edgeMask(iEdge))) then
2954- edgeLengthScaling = scale_edge_length(angleEdge (iEdge), uvelForAblation(iCell), vvelForAblation(iCell))
2953+ edgeLengthScaling = scale_edge_length(xCell(iCell), yCell(iCell), xEdge(iEdge), yEdge (iEdge), uvelForAblation(iCell), vvelForAblation(iCell))
29552954 ablateLengthEdge = edgeLengthScaling * dvEdge(iEdge)
29562955 if (requiredAblationVolumeDynEdge(iEdge) > 0.0_RKIND) then
29572956 call mpas_log_write("Unexpectedly found a dynamic edge that already has calving assigned to it." // &
@@ -3178,18 +3177,30 @@ end subroutine li_apply_front_ablation_velocity
31783177
31793178 ! Helper function for subroutine li_apply_front_ablation_velocity
31803179 ! Calculates the amount to scale an edge length based on the orientation of the edge with the surface velocity
3181- function scale_edge_length (angleEdgeHere , u , v )
3182- real (kind= RKIND), intent (in ) :: angleEdgeHere
3183- real (kind= RKIND), intent (in ) :: u
3184- real (kind= RKIND), intent (in ) :: v
3180+ function scale_edge_length (xc , yc , xe , ye , vx , vy )
3181+ real (kind= RKIND), intent (in ) :: xc, yc ! x,y coords of cell center
3182+ real (kind= RKIND), intent (in ) :: xe, ye ! x,y coords of edge neighboring cell
3183+ real (kind= RKIND), intent (in ) :: vx, vy ! x,y components of velocity vector
31853184 real (kind= RKIND) :: scale_edge_length
31863185
3187- real (kind= RKIND) :: mag
3186+ real (kind= RKIND) :: ux, uy, umag, vmag
3187+
3188+ ! Calculate vector pointing from cell center to edge
3189+ ux = xe - xc
3190+ uy = ye - yc
3191+ umag = sqrt (ux** 2 + uy** 2 )
3192+
3193+ ! avoid divide by zero
3194+ if (umag == 0.0_RKIND ) umag = 1.0_RKIND
3195+ vmag = sqrt (vx** 2 + vy** 2 )
3196+ if (vmag == 0.0_RKIND ) vmag = 1.0_RKIND
3197+
3198+ ! dot product of unit vectors
3199+ scale_edge_length = (ux / umag) * (vx / vmag) + (uy / umag) * (vy / vmag)
3200+ ! set scale to 0 where vectors are not pointing the same way
3201+ ! (i.e. where vector to edge points away from flow direction)
3202+ scale_edge_length = max (0.0 , scale_edge_length)
31883203
3189- mag = sqrt (u** 2 + v** 2 )
3190- if (mag == 0.0_RKIND ) mag = 1.0_RKIND
3191- scale_edge_length = abs (u/ mag * cos (angleEdgeHere) + v/ mag * sin (angleEdgeHere)) ! dot product of unit vectors
3192- !scale_edge_length = abs (cos (angleEdgeHere - atan2 (v, u)))
31933204 end function scale_edge_length
31943205
31953206
0 commit comments