Several diagnostic issues in branch_4.2
Context
-
Branches impacted: branch_4.2 -
Reference configuration/test case: ORCA2 -
Computing architecture -
Dependencies: - Any diagnostic activating the
l_ar5
conditional india_ar5_init
(e.g.masscello
) - Any turbulent closure activating the
l_zdfsh2
conditional inzdf_phy
(e.g.ln_zdftke = .TRUE.
),ln_tile = .TRUE.
-
ln_zdftke = .TRUE.
,ln_tile = .TRUE.
-
ln_tile = .TRUE.
,iom_put
called for tiled array without halo points
- Any diagnostic activating the
Analysis
-
z3d
is not allocated in dia_ar5. XIOS fails with an 'unexpected array shape' error (SHAPE(z3d)
returns 0). -
The
eshear_k
diagnostic in zdf_phy is calculated in a way that causes a conformance error when the tiling is active (arrayszsh2
andwmask
have different shapes), leading to different results. -
The
ediss_k
diagnostic in zdf_tke is calculated prior to the addition of thenn_etau
contribution toen
. Because this is calculated on halo points, thenn_etau
contribution is added to the internal parts of adjacent tiles and is therefore included in theediss_k
diagnostic for those tiles. The tiling therefore gives different results for this diagnostic. -
The definition of the 'inner'-type XIOS grids (those without halo points in the source data) in set_grid is incorrect for tile-sized arrays-
tile_data*
should not include halo points. For diagnostics defined on these grids, the tiling will give different results.
Fix
These issues were all resolved (directly or indirectly) by 16443a0b; we just need fixes for branch_4.2.
-
Allocate the array!
-
Define
eshear_k
on thegrid_W_3D_inner
grid in field_def.xml and calculate the diagnostic only on the inner domain, i.e.
- CALL iom_put( 'eshear_k', zsh2 * wmask )
+ CALL iom_put( 'eshear_k', zsh2(A2D(0),:) * wmask(A2D(0),:) )
All halo points must be excluded, as there is no support in branch_4.2 for diagnostic arrays with 1 row of halo points when nn_hls = 2
(but this is in the main).
- Define
ztmp
on the MPI domain (usingSAVE
to preserve the result) and populate the array with each tile, then send the array to XIOS when all tiles are finished. This method is used to solve a similar issue inzdf_evd
.
IF( iom_use('ediss_k') ) THEN
IF( .NOT. l_istiled .OR. ntile == 1 ) THEN
ALLOCATE( ztmp(jpi,jpj,jpk) )
ztmp(:,:,:) = 0._wp
ENDIF
DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
ztmp(ji,jj,jk) = zfact3 * dissl(ji,jj,jk) * en(ji,jj,jk) * wmask(ji,jj,jk)
END_3D
IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN
CALL iom_put( 'ediss_k', ztmp )
DEALLOCATE( ztmp )
ENDIF
ENDIF
Note that the array is zeroed to avoid potential 'numerical conversion' type errors in XIOS.
- Make the following change in
set_grid
iniom.F90
+ idb(:) = 0
CALL iom_set_domain_attr("grid_"//cdgrd//"_inner", ntiles=nijtile, &
- & tile_ibegin=ntsi_a(1:nijtile) + idb(:) - 1, tile_jbegin=ntsj_a(1:nijtile) + idb(:) - 1, &
+ & tile_ibegin=ntsi_a(1:nijtile) - nn_hls - 1, tile_jbegin=ntsj_a(1:nijtile) - nn_hls - 1, &
& tile_ni=ini(:), tile_nj=inj(:), &
& tile_data_ibegin=idb(:), tile_data_jbegin=idb(:), &
& tile_data_ni=ini(:) - 2 * idb(:), tile_data_nj=inj(:) - 2 * idb(:))