Using the same conventions explained in my previous post, this is the first draft for the horizontal anisotropic diffusion of momentum. The subroutine implementing the procedure requires the velocity component pcn
and the “kind” of velocity kcmp
as input.
SELECT CASE( kcmp )
!> @par U Velocity
CASE ( np_ucmp ) !For U velocity
zwuu = 0._wp
zwuv = 0._wp
zwvu = 0._wp
zwvv = 0._wp
!
DO jk = 1, jpkm1 !== First derivative (gradient) ==!
DO jj = 2, jpjm1
DO ji = 2, jpim1
! Derivative of the velocity
zwuu(ji,jj,jk) = r1_e1t(ji,jj) * ( pcn(ji ,jj ,jk) - pcn(ji-1,jj,jk) )
zwuv(ji,jj,jk) = r1_e1f(ji,jj) * ( pcn(ji ,jj+1,jk) - pcn(ji ,jj,jk) )
zwvu(ji,jj,jk) = r1_e1t(ji,jj) * ( pcn(ji ,jj ,jk) - pcn(ji-1,jj,jk) )
zwvv(ji,jj,jk) = r1_e1f(ji,jj) * ( pcn(ji ,jj+1,jk) - pcn(ji ,jj,jk) )
! Diffusive velocity in x directions
zwuu(ji,jj,jk) = a_ten(ji,jj,jk,ia11) * zwuu(ji,jj,jk) * e2t(ji,jj) * e3t_n(ji,jj,jk)
zwuv(ji,jj,jk) = a_ten(ji,jj,jk,ia12) * zwuv(ji,jj,jk)
! Masking
zwuu(ji,jj,jk) = zwuu(ji,jj,jk) * tmask(ji,jj,jk)
zwuv(ji,jj,jk) = zwuv(ji,jj,jk) * fmask(ji,jj,jk)
zwvu(ji,jj,jk) = zwvu(ji,jj,jk) * tmask(ji,jj,jk)
zwvv(ji,jj,jk) = zwvv(ji,jj,jk) * fmask(ji,jj,jk)
END DO
END DO
END DO
!
CALL lbc_lnk_multi( 'new_hhdiff', zwuu, 'T', 1., &
& zwuv, 'F', 1., &
& zwvu, 'T', 1., &
& zwvv, 'F', 1. )
!
DO jk = 1, jpkm1 !== First derivative (gradient) ==!
DO jj = 1, jpjm1
DO ji = 1, jpim1
!
! Interpolation of zwuv from f-point to T-point
!
zw0(ji,jj,jk) = 0.25_wp * ( zwuv(ji-1,jj ,jk) + zwuv(ji ,jj ,jk) &
& + zwuv(ji-1,jj-1,jk) + zwuv(ji ,jj-1,jk) ) &
& * tmask(ji ,jj ,jk) * e2t(ji,jj) * e3t_n(ji,jj,jk)
!
! Interpolation of \partial_{x}u from T-point to f-point and multiplication by a_{12}
!
zw1(ji,jj,jk) = 0.25_wp * ( zwvu(ji ,jj+1,jk) + zwvu(ji+1,jj+1,jk) &
& + zwvu(ji ,jj ,jk) + zwvu(ji+1,jj ,jk) ) &
& * e1f(ji,jj) * e3f_n(ji,jj,jk) &
& * var_ten(ji,jj,jk,ia12) * fmask(ji,jj,jk)
!
! Interpolation of a_{22} from T-point to f-point and multiplication by \partial_{y}u
!
zw2(ji,jj,jk) = 0.25_wp * ( a_ten(ji ,jj+1,jk,ia22) + a_ten(ji+1,jj+1,jk,ia22) &
& + a_ten(ji ,jj ,jk,ia22) + a_ten(ji+1,jj ,jk,ia22) ) &
& * e1f(ji,jj) * e3f_n(ji,jj,jk) &
& * zwvv(ji,jj,jk) * fmask(ji,jj,jk)
!
END DO
END DO
END DO
!
CALL lbc_lnk_multi( 'new_hhdiff', zw0, 'T', 1., &
& zw1, 'F', 1., &
& zw2, 'F', 1. )
!
!
!
DO jk = 1, jpkm1 !== Second derivative (divergence) added to the general tracer trends ==!
DO jj = 2, jpjm1
DO ji = 2, jpim1
pca(ji,jj,jk) = pca(ji,jj,jk) + &
& ( zwuu(ji+1,jj ,jk) - zwuu(ji ,jj ,jk) &
& + zw0(ji+1,jj ,jk) - zw0(ji ,jj ,jk) &
& + zw1(ji ,jj ,jk) - zw1(ji-1,jj ,jk) &
& + zw2(ji ,jj ,jk) - zw2(ji-1,jj ,jk) ) &
& * umask(ji,jj,jk) / ( e1e2u(ji,jj) * e3u_n(ji,jj,jk) )
!
END DO
END DO
END DO
!> @par V Velocity
CASE ( np_vcmp ) !For V velocity
zwuu = 0._wp
zwuv = 0._wp
zwvu = 0._wp
zwvv = 0._wp
!
DO jk = 1, jpkm1 !== First derivative (gradient) ==!
DO jj = 1, jpjm1
DO ji = 1, jpim1
! Derivative of the velocity
zwuu(ji,jj,jk) = r1_e1f(ji,jj) * ( pcn(ji+1,jj,jk) - pcn(ji,jj ,jk) )
zwuv(ji,jj,jk) = r1_e1t(ji,jj) * ( pcn(ji ,jj,jk) - pcn(ji,jj-1,jk) )
zwvu(ji,jj,jk) = r1_e1f(ji,jj) * ( pcn(ji+1,jj,jk) - pcn(ji,jj ,jk) )
zwvv(ji,jj,jk) = r1_e1t(ji,jj) * ( pcn(ji ,jj,jk) - pcn(ji,jj-1,jk) )
! Diffusive velocity in x directions
zwvu(ji,jj,jk) = a_ten(ji,jj,jk,ia12) * zwvu(ji,jj,jk)
zwvv(ji,jj,jk) = a_ten(ji,jj,jk,ia22) * zwvv(ji,jj,jk) * e1f(ji,jj) * e3f_n(ji,jj,jk)
! Masking
zwuu(ji,jj,jk) = zwuu(ji,jj,jk) * fmask(ji,jj,jk)
zwuv(ji,jj,jk) = zwuv(ji,jj,jk) * tmask(ji,jj,jk)
zwvu(ji,jj,jk) = zwvu(ji,jj,jk) * fmask(ji,jj,jk)
zwvv(ji,jj,jk) = zwvv(ji,jj,jk) * tmask(ji,jj,jk)
END DO
END DO
END DO
!
CALL lbc_lnk_multi( 'new_hhdiff', zwuu, 'F', 1., &
& zwuv, 'T', 1., &
& zwvu, 'F', 1., &
& zwvv, 'T', 1. )
!
DO jk = 1, jpkm1 !== First derivative (gradient) ==!
DO jj = 2, jpjm1
DO ji = 2, jpim1
!
! Interpolation of a_{11} from T-point to f-point and multiplication by \partial_{x}v
!
zw0(ji,jj,jk) = 0.25_wp * ( a_ten(ji ,jj+1,jk,ia11) + a_ten(ji+1,jj+1,jk,ia11) &
& + a_ten(ji ,jj ,jk,ia11) + a_ten(ji+1,jj ,jk,ia11) ) &
& * e1f(ji,jj) * e3f_n(ji,jj,jk) &
& * zwuu(ji,jj,jk) * fmask(ji,jj,jk)
!
! Interpolation of \partial_{y}v from T-point to f-point and multiplication by a_{12}
!
zw1(ji,jj,jk) = 0.25_wp * ( zwuv(ji ,jj+1,jk) + zwuv(ji+1,jj+1,jk) &
& + zwuv(ji ,jj ,jk) + zwuv(ji+1,jj ,jk) ) &
& * e1f(ji,jj) * e3f_n(ji,jj,jk) &
& * a_ten(ji,jj,jk,ia12) * fmask(ji,jj,jk)
!
! Interpolation of zwvu from f-point to T-point
!
zw2(ji,jj,jk) = 0.25_wp * ( zwvu(ji-1,jj ,jk) + zwvu(ji ,jj ,jk) &
& + zwvu(ji-1,jj-1,jk) + zwvu(ji ,jj-1,jk) ) &
& * tmask(ji ,jj ,jk) * e2t(ji,jj) * e3t_n(ji,jj,jk)
!
END DO
END DO
END DO
!
CALL lbc_lnk_multi( 'new_hhdiff', zw0, 'F', 1., &
& zw1, 'F', 1., &
& zw2, 'T', 1. )
!
!
!
DO jk = 1, jpkm1 !== Second derivative (divergence) added to the general tracer trends ==!
DO jj = 2, jpjm1
DO ji = 2, jpim1
pca(ji,jj,jk) = pca(ji,jj,jk) + &
& ( zw0(ji ,jj ,jk) - zw0(ji-1,jj ,jk) &
& + zw1(ji ,jj ,jk) - zw1(ji-1,jj ,jk) &
& + zw2(ji+1,jj ,jk) - zw2(ji ,jj ,jk) &
& + zwvv(ji+1,jj ,jk) - zwvv(ji ,jj ,jk) ) &
& * vmask(ji,jj,jk) / ( e1e2v(ji,jj) * e3v_n(ji,jj,jk) )
!
END DO
END DO
END DO
CASE DEFAULT
CALL ctl_stop('STOP','new_hhdiff: wrong value for kcmp' )
END SELECT
On a side note, all these codes are not optimised, right now I am more concerned about having a functioning implementation rather than a fast and optimised implementation.
Stay tuned for purely vertical diffusion
Francesco