Skip to content

Commit 9096116

Browse files
committed
Merge branch 'hotfix-v7.2'
This merge addresses several issues in the MPAS-Atmosphere model. Specifically, this merge introduces the following fixes: - Correct the use of uninitialized memory in the init_atm_case_squall_line routine by initializing the qvb array to zero before its first use. - Fix a bug in the vertical extrapolation of relative humidity and specific humidity to model levels below the lowest first-guess level when first-guess levels are given in top-to-bottom order in the input intermediate file. - Fix reproducibility issues in several fields within the Noah LSM over land-ice points when running with different MPI task counts; however, only one of these fields -- smstav, the surface moisture availability field -- persists outside of the physics driver and is written to MPAS-Atmosphere restart files. - Correct the units and description attributes for the GWDO fields var2d, con, oa1, oa2, oa3, oa4, ol1, ol2, ol3, and ol4 in both the init_atmosphere and atmosphere core Registry.xml files. - Add code that had inadvertently been omitted for computing dtheta_dt_mp, the potential temperature heating rate from microphysics. Prior to this change, the dtheta_dt_mp field would always contain a constant zero value when written to model output files. - Correct a check on the availability of the dtheta_dt_mix variable when computing depv_dt_mix in the PV diagnostics module. - Correct the parallel computation of iLev_DT (and other fields that depend on it, including u_pv, v_pv, theta_pv, vort_pv, depv_dt_diab_pv, and depv_dt_fric_pv) in the PV diagnostics module. * hotfix-v7.2: Correct units and descriptions for GWDO fields var2d, con, oa[1-4], ol[1-4] Halo exchange inTropo in flood fill to find DT. Fix parallel reproducibility error in 'smstav' field Correct check on availability of dtheta_dt_mix when computing depv_dt_mix Fix bug in vertical interp of r.h. and s.h. when levels are given top-to-bottom Initialize qvb to zero before its first use in init_atm_case_squall_line Remove redundant mpas_pool_get_array calls for dtheta_dt_mp computation Use dt_dyn rather than dt_microp when computing dtheta_dt_mp Remove trailing whitespace and adjust indentation of dtheta_dt_mp computation Obtain 'rvord' from mpas_constants for computation of dtheta_dt_mp Increment version number to 7.2 Calculate dtheta_dt_mp by finite difference around microphysics call.
2 parents 7557b47 + 0206851 commit 9096116

13 files changed

Lines changed: 176 additions & 107 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
MPAS-v7.1
1+
MPAS-v7.2
22
====
33

44
The Model for Prediction Across Scales (MPAS) is a collaborative project for

src/core_atmosphere/Registry.xml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0"?>
2-
<registry model="mpas" core="atmosphere" core_abbrev="atm" version="7.1">
2+
<registry model="mpas" core="atmosphere" core_abbrev="atm" version="7.2">
33

44
<!-- **************************************************************************************** -->
55
<!-- ************************************** Dimensions ************************************** -->
@@ -3067,35 +3067,35 @@
30673067
<!-- ... PARAMETERIZATION OF GRAVITY WAVE DRAG OVER OROGRAPHY: -->
30683068
<!-- ================================================================================================== -->
30693069

3070-
<var name="var2d" type="real" dimensions="nCells" units="m^{2}"
3071-
description="variance of orography"/>
3070+
<var name="var2d" type="real" dimensions="nCells" units="m"
3071+
description="standard deviation of subgrid-scale orography"/>
30723072

3073-
<var name="con" type="real" dimensions="nCells" units="m^{2}"
3074-
description="convexity of orography"/>
3073+
<var name="con" type="real" dimensions="nCells" units="unitless"
3074+
description="orographic convexity"/>
30753075

30763076
<var name="oa1" type="real" dimensions="nCells" units="unitless"
3077-
description="directional asymmetry function of orography"/>
3077+
description="asymmetry of subgrid-scale orography for westerly flow"/>
30783078

30793079
<var name="oa2" type="real" dimensions="nCells" units="unitless"
3080-
description="directional asymmetry function of orography"/>
3080+
description="asymmetry of subgrid-scale orography for southerly flow"/>
30813081

30823082
<var name="oa3" type="real" dimensions="nCells" units="unitless"
3083-
description="directional asymmetry function of orography"/>
3083+
description="asymmetry of subgrid-scale orography for south-westerly flow"/>
30843084

30853085
<var name="oa4" type="real" dimensions="nCells" units="unitless"
3086-
description="directional asymmetry function of orography"/>
3086+
description="asymmetry of subgrid-scale orography for north-westerly flow"/>
30873087

30883088
<var name="ol1" type="real" dimensions="nCells" units="unitless"
3089-
description="directional asymmetry function of orography"/>
3089+
description="effective orographic length for westerly flow"/>
30903090

30913091
<var name="ol2" type="real" dimensions="nCells" units="unitless"
3092-
description="directional asymmetry function of orography"/>
3092+
description="effective orographic length for southerly flow"/>
30933093

30943094
<var name="ol3" type="real" dimensions="nCells" units="unitles"
3095-
description="directional asymmetry function of orography"/>
3095+
description="effective orographic length for south-westerly flow"/>
30963096

30973097
<var name="ol4" type="real" dimensions="nCells" units="unitless"
3098-
description="directional asymmetry function of orography"/>
3098+
description="effective orographic length for north-westerly flow"/>
30993099
</var_struct>
31003100

31013101
<var_struct name="tend_iau" time_levs="1" packages="iau">

src/core_atmosphere/diagnostics/Registry_pv.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,8 @@
6262
<var name="iLev_DT" type="integer" dimensions="nCells Time" units="-"
6363
description="Lowest vertical level at or above dynamic tropopause (.lt.1 if 2 PVU below column; .gt.nLevels if 2PVU above column)"/>
6464

65+
<var name="inTropo" type="integer" dimensions="nVertLevels nCells Time" units="0/1"
66+
description="1 if within troposphere based on EPV flood fill"/>
67+
6568
</var_struct>
6669

src/core_atmosphere/diagnostics/pv_diagnostics.F

Lines changed: 77 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -591,29 +591,41 @@ subroutine floodFill_tropo(mesh, diag, pvuVal)
591591
! (2) flood fill troposphere (<2pvu) from troposphere seeds near surface.
592592
!Somewhat paradoxically, the bottom of the stratosphere is lower than the top of the troposphere.
593593
594+
!Originally, it was assumed that each (MPI) domain would have >0 cells with "right" DT found by flood filling.
595+
!However, for "small" domains over the Arctic say during winter, the entire surface can be capped by high PV.
596+
!So, we need to communicate between domains during the flood fill or else we find the DT at the surface.
597+
!The extreme limiting case is if we had every cell as its own domain; then, it's clear that there has to be communication.
598+
594599
!The "output" is iLev_DT, which is the vertical index for the level >= pvuVal. If >nVertLevels, pvuVal above column. If <2, pvuVal below column.
595600
!Communication between blocks during the flood fill may be needed to treat some edge cases appropriately.
596601

597-
use mpas_pool_routines, only : mpas_pool_get_dimension, mpas_pool_get_array
602+
use mpas_pool_routines, only : mpas_pool_get_dimension, mpas_pool_get_array, mpas_pool_get_field
603+
use mpas_dmpar, only : mpas_dmpar_max_int,mpas_dmpar_exch_halo_field
604+
use mpas_derived_types, only : dm_info, field2DInteger
598605

599606
implicit none
600607

601608
type (mpas_pool_type), intent(in) :: mesh
602609
type (mpas_pool_type), intent(inout) :: diag
603610
real(kind=RKIND), intent(in) :: pvuVal
604-
605-
integer :: iCell, k, nChanged, iNbr, iCellNbr, levInd
606-
integer, pointer :: nCells, nVertLevels
611+
612+
integer :: iCell, k, nChanged, iNbr, iCellNbr, levInd, haloChanged, global_haloChanged
613+
integer, pointer :: nCells, nVertLevels, nCellsSolve
607614
integer, dimension(:), pointer :: nEdgesOnCell, iLev_DT
608-
integer, dimension(:,:), pointer :: cellsOnCell
609-
615+
integer, dimension(:,:), pointer :: cellsOnCell, inTropo
616+
617+
type (field2DInteger), pointer :: inTropo_f
618+
610619
real(kind=RKIND) :: sgnHemi, sgn
611620
real(kind=RKIND),dimension(:),pointer:: latCell
612621
real(kind=RKIND), dimension(:,:), pointer :: ertel_pv
613622

614-
integer, dimension(:,:), allocatable :: candInTropo, inTropo !whether in troposphere
623+
type (dm_info), pointer :: dminfo
624+
625+
integer, dimension(:,:), allocatable :: candInTropo !whether in troposphere
615626

616627
call mpas_pool_get_dimension(mesh, 'nCells', nCells)
628+
call mpas_pool_get_dimension(mesh, 'nCellsSolve', nCellsSolve)
617629
call mpas_pool_get_dimension(mesh, 'nVertLevels', nVertLevels)
618630
call mpas_pool_get_array(mesh, 'nEdgesOnCell', nEdgesOnCell)
619631
call mpas_pool_get_array(mesh, 'cellsOnCell', cellsOnCell)
@@ -622,9 +634,9 @@ subroutine floodFill_tropo(mesh, diag, pvuVal)
622634
call mpas_pool_get_array(diag, 'ertel_pv', ertel_pv)
623635
!call mpas_pool_get_array(diag, 'iLev_DT_trop', iLev_DT)
624636
call mpas_pool_get_array(diag, 'iLev_DT', iLev_DT)
637+
call mpas_pool_get_array(diag, 'inTropo', inTropo)
625638

626639
allocate(candInTropo(nVertLevels, nCells+1))
627-
allocate(inTropo(nVertLevels, nCells+1))
628640
candInTropo(:,:) = 0
629641
inTropo(:,:) = 0
630642
!store whether each level above DT to avoid repeating logic. we'll use cand as a isVisited marker further below.
@@ -645,56 +657,71 @@ subroutine floodFill_tropo(mesh, diag, pvuVal)
645657
do k=1,levInd
646658
if (candInTropo(k,iCell) .GT. 0) then
647659
inTropo(k,iCell) = 1
648-
candInTropo(k,iCell) = 0
660+
!candInTropo(k,iCell) = 0
649661
nChanged = nChanged+1
650662
end if
651663
end do
652664
end do
653665

654666
!flood fill from the given seeds. since I don't know enough fortran,
655667
!we'll just brute force a continuing loop rather than queue.
656-
do while(nChanged .GT. 0)
657-
nChanged = 0
658-
do iCell=1,nCells
659-
do k=1,nVertLevels
660-
!update if candidate and neighbor in troposphere
661-
if (candInTropo(k,iCell) .GT. 0) then
662-
!nbr below
663-
if (k .GT. 1) then
664-
if (inTropo(k-1,iCell) .GT. 0) then
665-
inTropo(k,iCell) = 1
666-
candInTropo(k,iCell) = 0
667-
nChanged = nChanged+1
668-
cycle
669-
end if
670-
end if
671-
672-
!side nbrs
673-
do iNbr = 1, nEdgesOnCell(iCell)
674-
iCellNbr = cellsOnCell(iNbr,iCell)
675-
if (inTropo(k,iCellNbr) .GT. 0) then
676-
inTropo(k,iCell) = 1
677-
candInTropo(k,iCell) = 0
678-
nChanged = nChanged+1
679-
cycle
668+
call mpas_pool_get_field(diag, 'inTropo', inTropo_f)
669+
dminfo => inTropo_f % block % domain % dminfo
670+
global_haloChanged = 1
671+
do while(global_haloChanged .GT. 0) !any cell in a halo has changed, to propagate to other domains
672+
global_haloChanged = 0 !aggregate the number of changed cells w/in the loop below
673+
do while(nChanged .GT. 0)
674+
nChanged = 0
675+
do iCell=1,nCells !should we look for neighbors of hallo cells?
676+
!do iCell=1,nCellsSolve !should we look for neighbors of hallo cells?
677+
do k=1,nVertLevels
678+
!update if candidate and neighbor in troposphere
679+
if ((candInTropo(k,iCell) .GT. 0) .AND. (inTropo(k,iCell).LT.1) ) then
680+
!nbr below
681+
if (k .GT. 1) then
682+
if (inTropo(k-1,iCell) .GT. 0) then
683+
inTropo(k,iCell) = 1
684+
!candInTropo(k,iCell) = 0
685+
nChanged = nChanged+1
686+
cycle
687+
end if
680688
end if
681-
end do
682-
683-
!nbr above
684-
if (k .LT. nVertLevels) then
685-
if (inTropo(k+1,iCell) .GT. 0) then
686-
inTropo(k,iCell) = 1
687-
candInTropo(k,iCell) = 0
688-
nChanged = nChanged+1
689-
cycle
689+
690+
!side nbrs
691+
do iNbr = 1, nEdgesOnCell(iCell)
692+
iCellNbr = cellsOnCell(iNbr,iCell)
693+
if (inTropo(k,iCellNbr) .GT. 0) then
694+
inTropo(k,iCell) = 1
695+
!candInTropo(k,iCell) = 0
696+
nChanged = nChanged+1
697+
exit
698+
end if
699+
end do
700+
701+
!nbr above
702+
if (k .LT. nVertLevels) then
703+
if (inTropo(k+1,iCell) .GT. 0) then
704+
inTropo(k,iCell) = 1
705+
!candInTropo(k,iCell) = 0
706+
nChanged = nChanged+1
707+
cycle
708+
end if
690709
end if
691-
end if
692-
693-
end if !candIn
694-
end do !levels
695-
end do !cells
696-
!here's where a communication would be needed for edge cases !!!
697-
end do !while
710+
711+
end if !candIn
712+
end do !levels
713+
end do !cells
714+
global_haloChanged = global_haloChanged+nChanged
715+
end do !while w/in domain
716+
!communicate to other domains for edge case where a chunk of a block hasn't gotten to fill
717+
nChanged = global_haloChanged
718+
call mpas_dmpar_max_int(dminfo, nChanged, global_haloChanged)
719+
if (global_haloChanged .GT. 0) then !communicate inTropo everywhere
720+
call mpas_dmpar_exch_halo_field(inTropo_f)
721+
end if
722+
nChanged = global_haloChanged !so each block will iterate again if anything changed
723+
end do !while haloChanged
724+
deallocate(candInTropo)
698725
699726
!Fill iLev_DT with the lowest level above the tropopause (If DT above column, iLev>nVertLevels. If DT below column, iLev=0.
700727
do iCell=1,nCells
@@ -1457,7 +1484,7 @@ subroutine calc_pvBudget(state, time_lev, diag, mesh, tend, tend_physics)
14571484
depv_dt_mp(k,iCell) = 0.0_RKIND
14581485
end if
14591486
1460-
if (associated(dtheta_dt_mp)) then
1487+
if (associated(dtheta_dt_mix)) then
14611488
call calc_grad_cell(gradtheta, &
14621489
iCell, k, nVertLevels, nEdgesOnCell(iCell), verticesOnCell, kiteAreasOnVertex, &
14631490
cellsOnCell, edgesOnCell, cellsOnEdge, dvEdge, edgeNormalVectors, &

0 commit comments

Comments
 (0)