Skip to content

Commit

Permalink
(*)Avoid using RHO_0 in non-Boussinesq averaging
Browse files Browse the repository at this point in the history
  Use GV%H_to_MKS instead of GV%H_to_m when undoing the dimensional rescaling of
thicknesses when taking weighted averages in horizontally_average_diag_field,
global_layer_mean and global_volume_mean.  In Boussinesq mode, these are
identical, but in non-Boussinesq mode using GV%H_to_m introduced a
multiplication and then division by the Boussinesq reference density, whereas
GV%H_to_MKS avoids this by rescaling to a volume or mass-based coordinate
depending on the mode.  Several comments were also updated to reflect these
conditional changes in the units of some internal variables.  All expressions
are mathematically equivalent, and this does not impact any solutions, but there
can be changes in the last bits in some non-Boussinesq averaged diagnostics.
  • Loading branch information
Hallberg-NOAA authored and marshallward committed Feb 2, 2024
1 parent 541c2f4 commit 76f0668
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 14 deletions.
20 changes: 11 additions & 9 deletions src/diagnostics/MOM_spatial_means.F90
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,13 @@ function global_layer_mean(var, h, G, GV, scale, tmp_scale)
! Local variables
! In the following comments, [A] is used to indicate the arbitrary, possibly rescaled units of the
! input array while [a] indicates the unscaled (e.g., mks) units that can be used with the reproducing sums
real, dimension(G%isc:G%iec,G%jsc:G%jec,SZK_(GV)) :: tmpForSumming ! An unscaled cell integral [a m3]
real, dimension(G%isc:G%iec,G%jsc:G%jec,SZK_(GV)) :: weight ! The volume of each cell, used as a weight [m3]
real, dimension(G%isc:G%iec,G%jsc:G%jec,SZK_(GV)) :: tmpForSumming ! An unscaled cell integral [a m3] or [a kg]
real, dimension(G%isc:G%iec,G%jsc:G%jec,SZK_(GV)) :: weight ! The volume or mass of each cell, depending on
! whether the model is Boussinesq, used as a weight [m3] or [kg]
type(EFP_type), dimension(2*SZK_(GV)) :: laysums
real, dimension(SZK_(GV)) :: global_temp_scalar ! The global integral of the tracer in each layer [a m3]
real, dimension(SZK_(GV)) :: global_weight_scalar ! The global integral of the volume of each layer [m3]
real, dimension(SZK_(GV)) :: global_temp_scalar ! The global integral of the tracer in each layer [a m3] or [a kg]
real, dimension(SZK_(GV)) :: global_weight_scalar ! The global integral of the volume or mass of each
! layer [m3] or [kg]
real :: temp_scale ! A temporary scaling factor [a A-1 ~> 1] or [1]
real :: scalefac ! A scaling factor for the variable [a A-1 ~> 1]
integer :: i, j, k, is, ie, js, je, nz
Expand All @@ -226,7 +228,7 @@ function global_layer_mean(var, h, G, GV, scale, tmp_scale)
tmpForSumming(:,:,:) = 0. ; weight(:,:,:) = 0.

do k=1,nz ; do j=js,je ; do i=is,ie
weight(i,j,k) = (GV%H_to_m * h(i,j,k)) * (G%US%L_to_m**2*G%areaT(i,j) * G%mask2dT(i,j))
weight(i,j,k) = (GV%H_to_MKS * h(i,j,k)) * (G%US%L_to_m**2*G%areaT(i,j) * G%mask2dT(i,j))
tmpForSumming(i,j,k) = scalefac * var(i,j,k) * weight(i,j,k)
enddo ; enddo ; enddo

Expand Down Expand Up @@ -262,9 +264,9 @@ function global_volume_mean(var, h, G, GV, scale, tmp_scale)
! input array while [a] indicates the unscaled (e.g., mks) units that can be used with the reproducing sums
real :: temp_scale ! A temporary scaling factor [a A-1 ~> 1] or [1]
real :: scalefac ! A scaling factor for the variable [a A-1 ~> 1]
real :: weight_here ! The volume of a grid cell [m3]
real, dimension(SZI_(G),SZJ_(G)) :: tmpForSumming ! The volume integral of the variable in a column [a m3]
real, dimension(SZI_(G),SZJ_(G)) :: sum_weight ! The volume of each column of water [m3]
real :: weight_here ! The volume or mass of a grid cell [m3] or [kg]
real, dimension(SZI_(G),SZJ_(G)) :: tmpForSumming ! The volume integral of the variable in a column [a m3] or [a kg]
real, dimension(SZI_(G),SZJ_(G)) :: sum_weight ! The volume or mass of each column of water [m3] or [kg]
integer :: i, j, k, is, ie, js, je, nz
is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke

Expand All @@ -273,7 +275,7 @@ function global_volume_mean(var, h, G, GV, scale, tmp_scale)
tmpForSumming(:,:) = 0. ; sum_weight(:,:) = 0.

do k=1,nz ; do j=js,je ; do i=is,ie
weight_here = (GV%H_to_m * h(i,j,k)) * (G%US%L_to_m**2*G%areaT(i,j) * G%mask2dT(i,j))
weight_here = (GV%H_to_MKS * h(i,j,k)) * (G%US%L_to_m**2*G%areaT(i,j) * G%mask2dT(i,j))
tmpForSumming(i,j) = tmpForSumming(i,j) + scalefac * var(i,j,k) * weight_here
sum_weight(i,j) = sum_weight(i,j) + weight_here
enddo ; enddo ; enddo
Expand Down
17 changes: 12 additions & 5 deletions src/framework/MOM_diag_remap.F90
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,15 @@ subroutine horizontally_average_diag_field(G, GV, h, staggered_in_x, staggered_i
logical, dimension(:), intent(inout) :: averaged_mask !< Mask for horizontally averaged field [nondim]

! Local variables
real, dimension(G%isc:G%iec, G%jsc:G%jec, size(field,3)) :: volume, stuff
real, dimension(size(field, 3)) :: vol_sum, stuff_sum ! nz+1 is needed for interface averages
real :: volume(G%isc:G%iec, G%jsc:G%jec, size(field,3)) ! The area [m2], volume [m3] or mass [kg] of each cell.
real :: stuff(G%isc:G%iec, G%jsc:G%jec, size(field,3)) ! The area, volume or mass-weighted integral of the
! field being averaged in each cell, in [m2 A], [m3 A] or [kg A],
! depending on the weighting for the averages and whether the
! model makes the Boussinesq approximation.
real, dimension(size(field, 3)) :: vol_sum ! The global sum of the areas [m2], volumes [m3] or mass [kg]
! in the cells that used in the weighted averages.
real, dimension(size(field, 3)) :: stuff_sum ! The global sum of the weighted field in all cells, in
! [A m2], [A m3] or [A kg]
type(EFP_type), dimension(2*size(field,3)) :: sums_EFP ! Sums of volume or stuff by layer
real :: height ! An average thickness attributed to an velocity point [H ~> m or kg m-2]
integer :: i, j, k, nz
Expand Down Expand Up @@ -688,7 +695,7 @@ subroutine horizontally_average_diag_field(G, GV, h, staggered_in_x, staggered_i
I1 = i - G%isdB + 1
height = 0.5 * (h(i,j,k) + h(i+1,j,k))
volume(I,j,k) = (G%US%L_to_m**2 * G%areaCu(I,j)) &
* (GV%H_to_m * height) * G%mask2dCu(I,j)
* (GV%H_to_MKS * height) * G%mask2dCu(I,j)
stuff(I,j,k) = volume(I,j,k) * field(I1,j,k)
enddo ; enddo
endif
Expand Down Expand Up @@ -717,7 +724,7 @@ subroutine horizontally_average_diag_field(G, GV, h, staggered_in_x, staggered_i
J1 = J - G%jsdB + 1
height = 0.5 * (h(i,j,k) + h(i,j+1,k))
volume(i,J,k) = (G%US%L_to_m**2 * G%areaCv(i,J)) &
* (GV%H_to_m * height) * G%mask2dCv(i,J)
* (GV%H_to_MKS * height) * G%mask2dCv(i,J)
stuff(i,J,k) = volume(i,J,k) * field(i,J1,k)
enddo ; enddo
endif
Expand Down Expand Up @@ -748,7 +755,7 @@ subroutine horizontally_average_diag_field(G, GV, h, staggered_in_x, staggered_i
else ! Intensive
do j=G%jsc, G%jec ; do i=G%isc, G%iec
volume(i,j,k) = (G%US%L_to_m**2 * G%areaT(i,j)) &
* (GV%H_to_m * h(i,j,k)) * G%mask2dT(i,j)
* (GV%H_to_MKS * h(i,j,k)) * G%mask2dT(i,j)
stuff(i,j,k) = volume(i,j,k) * field(i,j,k)
enddo ; enddo
endif
Expand Down

0 comments on commit 76f0668

Please sign in to comment.