Another bespoke collection of bug fixes
Context
- Branches impacted: main
- Steps to reproduce:
key_RK3
, any DYN option innamtrd
,ln_dynadv_cen2 .OR. ln_dynadv_vec
,ln_wave .AND. ln_sdw
Analysis
-
sophtadv
andsopstadv
diagnostics are ~3x larger with RK3 than with MLFWhen using RK3, most calls to
dia_ptr_hst
are performed for all 3 stages- thel_diaptr
conditional is missing from the preceding conditional statement.There is also a typo in many of the
iom_use
calls in these conditional statements, e.g. for tra_adv_cen:IF( cdtype == 'TRA' .AND. ( iom_use( 'sophtadv' ) .OR. iom_use( 'sophtadv' ) ) ) l_ptr = .TRUE.
Generally, the second
"sophtadv"
should be replaced by"sopstadv"
. -
Some working arrays used for DYN trends diagnostics have an incorrect shape
trd_dyn has the following declaration for input arrays:
REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: putrd, pvtrd ! U and V trends
However, in dyn_keg these arrays do not have halo points:
ALLOCATE( zu_trd(A2D(0),jpk), zv_trd(A2D(0),jpk) )
This is an issue, because the starting indices for such arrays should be 3 (
ntsi
/ntsj
). However, the assumed shape declaration intrd_dyn
will mean that within this subroutine, the indices forputrd
/pvtrd
will start from 1. This will result in the wrong part of the array being accessed bytrd_dyn
and its called subroutines.dyn_adv_cen2 also has this issue, and also has a more general conformance issue where
zx_trd(1:jpkm1) = pxx(1:jpk)
:ALLOCATE( zu_trd(A2D(0),jpkm1), zv_trd(A2D(0),jpkm1) ) zu_trd(:,:,:) = puu(A2D(0),:,Krhs) zv_trd(:,:,:) = pvv(A2D(0),:,Krhs)
-
Following d0559ec8,
wAimp
is called for each RK3 stage intra_adv_trp
whenln_wave .AND. ln_sdw = .true.
This is because
ll_Fw = .true.
when this latter condition is met:IF( ln_wave .AND. ln_sdw ) THEN ll_Fw = .true. ! DO jk = 1, jpkm1 ! At all stages : Add the Stokes Drift DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1) pFu(ji,jj,jk) = pFu(ji,jj,jk) + e2u(ji,jj) * e3u(ji,jj,jk,Kmm) * usd(ji,jj,jk) pFv(ji,jj,jk) = pFv(ji,jj,jk) + e1v(ji,jj) * e3v(ji,jj,jk,Kmm) * vsd(ji,jj,jk) END_2D END DO ENDIF
so
wAimp
is called for all 3 stages:IF( ll_Fw ) THEN ! ww(:,:,jpk) = 0._wp ! CALL wzv( kt, Kbb, Kmm, Kaa, pFu, pFv, ww, np_transport ) ! ! Partition ww/wwi at stage 3 only IF( ln_zad_Aimp ) CALL wAimp( kt, Kmm, pFu, pFv, ww, wi, np_transport ) DO jk = 1, jpkm1 DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) pFw(ji,jj,jk) = e1e2t(ji,jj) * ww(ji,jj,jk) END_2D END DO ! ENDIF
This probably gives the wrong results, but also causes the wrong
wAimp
diagnostics to be output. XIOS will use data from the first call toiom_put
and ignore subsequent calls. ThewAimp
diagnostics will therefore contain data fromwAimp(k_ind=np_transport)
instead ofwAimp(k_ind=np_velocity)
.
Fix
-
Add
l_diaptr
to the preceding conditional statements fordia_ptr_hst
calls and fixiom_use
typos:- IF( cdtype == 'TRA' .AND. ( iom_use( 'sophtadv' ) .OR. iom_use( 'sophtadv' ) ) ) l_ptr = .TRUE. + IF( l_diaptr .AND. cdtype == 'TRA' .AND. ( iom_use( 'sophtadv' ) .OR. iom_use( 'sopstadv' ) ) ) l_ptr = .TRUE.
-
Declare the arrays with
A2D(2)
and resolve the conformance issues:- ALLOCATE( zu_trd(A2D(0),jpkm1), zv_trd(A2D(0),jpkm1) ) - zu_trd(:,:,:) = puu(A2D(0),:,Krhs) - zv_trd(:,:,:) = pvv(A2D(0),:,Krhs) + ALLOCATE( zu_trd(A2D(2),jpkm1), zv_trd(A2D(2),jpkm1) ) + zu_trd(A2D(0),:) = puu(A2D(0),1:jpkm1,Krhs) + zv_trd(A2D(0),:) = pvv(A2D(0),1:jpkm1,Krhs)
It would be better to implement wrapper functions as for e.g. eosbn2.F90 subroutines, which allow subroutines to handle varying input array sizes. This is a smaller and quicker fix for now.
-
Add
kstg == 3
to the conditional statement preceding thewAimp
call intra_adv_trp
- IF( ln_zad_Aimp ) CALL wAimp( kt, Kmm, pFu, pFv, ww, wi, np_transport ) + IF( ln_zad_Aimp .AND. kstg == 3 ) CALL wAimp( kt, Kmm, pFu, pFv, ww, wi, np_transport )