pure subroutine meke_source(nx, ny, bgsrc, gmcoeff, frcoeff, sdt, i_mass, &
gm_src, ke_diss, src, meke)
!! Aggregate source `src = bgsrc + gmcoeff*I_mass*gm_src
!! - frcoeff*I_mass*ke_diss` and the explicit bump `E += sdt*src`.
!! `gmcoeff<0` ⇒ GM source off; `frcoeff<0` ⇒ frictional source off.
!! `ke_diss` is the lateral-viscosity KE dissipation rate (≤0), so
!! `-frcoeff*I_mass*ke_diss ≥ 0` is a mean→eddy source (0 ⇒ inert).
integer, intent(in) :: nx, ny
real(wp), intent(in) :: bgsrc, gmcoeff, frcoeff, sdt
real(wp), intent(in) :: i_mass(nx, ny)
real(wp), intent(in) :: gm_src(nx, ny)
real(wp), intent(in) :: ke_diss(nx, ny)
real(wp), intent(inout) :: src(nx, ny)
real(wp), intent(inout) :: meke(nx, ny)
integer :: i, j
real(wp) :: s
do concurrent(j=1:ny, i=1:nx) local(s)
s = bgsrc
if (gmcoeff >= 0.0_wp) s = s + gmcoeff*i_mass(i, j)*gm_src(i, j)
if (frcoeff >= 0.0_wp) s = s - frcoeff*i_mass(i, j)*ke_diss(i, j)
src(i, j) = s
meke(i, j) = meke(i, j) + sdt*s
end do
end subroutine meke_source