-
Notifications
You must be signed in to change notification settings - Fork 76
Description
Downsampled diagnostics with MMS cell methods (i.e. "xh:mean yh:mean z_l:sum) are currently bugged, because incorrect weights are used in the weighted-averaging operation.
In the following lines, the weights are the product of a 3D mask array and a 2D area array.
MOM6/src/framework/MOM_diag_mediator.F90
Lines 4444 to 4457 in 4622d6a
| elseif (method == MMP .or. method == MMS) then !e.g., T_advection_xy | |
| do k=ks,ke ; do j=jsv_d,jev_d ; do i=isv_d,iev_d | |
| i0 = isv_o+dl*(i-isv_d) | |
| j0 = jsv_o+dl*(j-jsv_d) | |
| ave = 0.0 | |
| total_weight = 0.0 | |
| do jj=j0,j0+dl-1 ; do ii=i0,i0+dl-1 | |
| ! do ii=i0,i0+dl-1 ; do jj=j0,j0+dl-1 | |
| weight = mask(ii,jj,k) * diag_cs%G%areaT(ii,jj) | |
| total_weight = total_weight + weight | |
| ave = ave+field_in(ii,jj,k)*weight | |
| enddo ; enddo | |
| field_out(i,j,k) = ave / (total_weight+eps_area) !Avoid zero mask at all aggregating cells where ave=0.0 | |
| enddo ; enddo ; enddo |
However, the 3D mask used to downsample the diagnostics seems to be a 2D wet mask that is simply projected downwards for all vertical levels:
MOM6/src/framework/MOM_diag_mediator.F90
Lines 3665 to 3705 in 4622d6a
| subroutine diag_masks_set(G, nz, diag_cs) | |
| type(ocean_grid_type), target, intent(in) :: G !< The ocean grid type. | |
| integer, intent(in) :: nz !< The number of layers in the model's native grid. | |
| type(diag_ctrl), pointer :: diag_cs !< A pointer to a type with many variables | |
| !! used for diagnostics | |
| ! Local variables | |
| integer :: k | |
| ! 2d masks point to the model masks since they are identical | |
| diag_cs%mask2dT => G%mask2dT | |
| diag_cs%mask2dBu => G%mask2dBu | |
| diag_cs%mask2dCu => G%mask2dCu | |
| diag_cs%mask2dCv => G%mask2dCv | |
| ! 3d native masks are needed by diag_manager but the native variables | |
| ! can only be masked 2d - for ocean points, all layers exists. | |
| allocate(diag_cs%mask3dTL(G%isd:G%ied,G%jsd:G%jed,1:nz)) | |
| allocate(diag_cs%mask3dBL(G%IsdB:G%IedB,G%JsdB:G%JedB,1:nz)) | |
| allocate(diag_cs%mask3dCuL(G%IsdB:G%IedB,G%jsd:G%jed,1:nz)) | |
| allocate(diag_cs%mask3dCvL(G%isd:G%ied,G%JsdB:G%JedB,1:nz)) | |
| do k=1,nz | |
| diag_cs%mask3dTL(:,:,k) = diag_cs%mask2dT(:,:) | |
| diag_cs%mask3dBL(:,:,k) = diag_cs%mask2dBu(:,:) | |
| diag_cs%mask3dCuL(:,:,k) = diag_cs%mask2dCu(:,:) | |
| diag_cs%mask3dCvL(:,:,k) = diag_cs%mask2dCv(:,:) | |
| enddo | |
| allocate(diag_cs%mask3dTi(G%isd:G%ied,G%jsd:G%jed,1:nz+1)) | |
| allocate(diag_cs%mask3dBi(G%IsdB:G%IedB,G%JsdB:G%JedB,1:nz+1)) | |
| allocate(diag_cs%mask3dCui(G%IsdB:G%IedB,G%jsd:G%jed,1:nz+1)) | |
| allocate(diag_cs%mask3dCvi(G%isd:G%ied,G%JsdB:G%JedB,1:nz+1)) | |
| do k=1,nz+1 | |
| diag_cs%mask3dTi(:,:,k) = diag_cs%mask2dT(:,:) | |
| diag_cs%mask3dBi(:,:,k) = diag_cs%mask2dBu(:,:) | |
| diag_cs%mask3dCui(:,:,k) = diag_cs%mask2dCu(:,:) | |
| diag_cs%mask3dCvi(:,:,k) = diag_cs%mask2dCv(:,:) | |
| enddo | |
| !Allocate and initialize the downsampled masks | |
| call downsample_diag_masks_set(G, nz, diag_cs) | |
| end subroutine diag_masks_set |
In vertical coordinates that include masked land cells, such as below topography in depth coordinates, however, this 3D area weight array will incorrectly have non-zero areas for any cells that are "wet" according to the 2D mask but actually should be "dry" in 3D because they are under the sea floor.
Since the numerator in the weighted average is a product of the weight with an MMS diagnostic, which should be zero under the seafloor anyways, there is no problem there. The problem arises in the total weight used in the denominator, which will erroneously include all of these sub-seafloor areas in the total.