horizontal_diffusion.f90 Source File


This file depends on

sourcefile~~horizontal_diffusion.f90~~EfferentGraph sourcefile~horizontal_diffusion.f90 horizontal_diffusion.f90 sourcefile~params.f90 params.f90 sourcefile~horizontal_diffusion.f90->sourcefile~params.f90 sourcefile~physical_constants.f90 physical_constants.f90 sourcefile~horizontal_diffusion.f90->sourcefile~physical_constants.f90 sourcefile~dynamical_constants.f90 dynamical_constants.f90 sourcefile~horizontal_diffusion.f90->sourcefile~dynamical_constants.f90 sourcefile~geometry.f90 geometry.f90 sourcefile~horizontal_diffusion.f90->sourcefile~geometry.f90 sourcefile~physical_constants.f90->sourcefile~params.f90 sourcefile~geometry.f90->sourcefile~params.f90 sourcefile~geometry.f90->sourcefile~physical_constants.f90

Files dependent on this one

sourcefile~~horizontal_diffusion.f90~~AfferentGraph sourcefile~horizontal_diffusion.f90 horizontal_diffusion.f90 sourcefile~implicit.f90 implicit.f90 sourcefile~implicit.f90->sourcefile~horizontal_diffusion.f90 sourcefile~time_stepping.f90 time_stepping.f90 sourcefile~time_stepping.f90->sourcefile~horizontal_diffusion.f90 sourcefile~time_stepping.f90->sourcefile~implicit.f90 sourcefile~tendencies.f90 tendencies.f90 sourcefile~time_stepping.f90->sourcefile~tendencies.f90 sourcefile~forcing.f90 forcing.f90 sourcefile~forcing.f90->sourcefile~horizontal_diffusion.f90 sourcefile~initialization.f90 initialization.f90 sourcefile~initialization.f90->sourcefile~horizontal_diffusion.f90 sourcefile~initialization.f90->sourcefile~time_stepping.f90 sourcefile~initialization.f90->sourcefile~forcing.f90 sourcefile~speedy.f90 speedy.f90 sourcefile~speedy.f90->sourcefile~time_stepping.f90 sourcefile~speedy.f90->sourcefile~forcing.f90 sourcefile~speedy.f90->sourcefile~initialization.f90 sourcefile~tendencies.f90->sourcefile~implicit.f90

Contents


Source Code

!> author: Sam Hatfield, Fred Kucharski, Franco Molteni
!  date: 07/05/2019
!  For performing horizontal diffusion.
module horizontal_diffusion
    use params

    implicit none

    private
    public initialize_horizontal_diffusion, do_horizontal_diffusion
    public dmp, dmpd, dmps, dmp1, dmp1d, dmp1s, tcorv, qcorv, tcorh, qcorh

    interface do_horizontal_diffusion
        module procedure do_horizontal_diffusion_2d
        module procedure do_horizontal_diffusion_3d
    end interface

    real :: dmp(mx,nx)  !! Damping coefficient for temperature and vorticity (explicit)
    real :: dmpd(mx,nx) !! Damping coefficient for divergence (explicit)
    real :: dmps(mx,nx) !! Damping coefficient for extra diffusion in the stratosphere (explicit)

    real :: dmp1(mx,nx)  !! Damping coefficient for temperature and vorticity (implicit)
    real :: dmp1d(mx,nx) !! Damping coefficient for divergence (implicit)
    real :: dmp1s(mx,nx) !! Damping coefficient for extra diffusion in the stratosphere (implicit)

    real :: tcorv(kx) !! Vertical component of orographic correction for temperature
    real :: qcorv(kx) !! Vertical component of orographic correction for humidity

    complex :: tcorh(mx,nx) !! Horizontal component of orographic correction for temperature
    complex :: qcorh(mx,nx) !! Horizontal component of orographic correction for humidity

contains
    !> Initializes the arrays used for horizontal diffusion.
    subroutine initialize_horizontal_diffusion
        use dynamical_constants, only: thd, thdd, thds, gamma, hscale, hshum
        use physical_constants, only: grav, rgas
        use geometry, only: fsg

        integer :: j, k, npowhd
        real :: elap, elapn, hdifd, hdiff, hdifs, qexp, rgam, rlap, twn

        ! 1. Definition of constants
        if (mod(nsteps,2) /= 0) stop ' Invalid no. of time steps'

        ! Power of Laplacian in horizontal diffusion
        npowhd = 4

        ! Coefficients for horizontal diffusion
        ! Spectral damping coefficients
        hdiff = 1./(thd *3600.)
        hdifd = 1./(thdd*3600.)
        hdifs = 1./(thds*3600.)
        rlap  = 1./float(trunc*(trunc+1))

        do j = 1, nx
            do k = 1, mx
                twn = float(k +j - 2)
                elap = (twn*(twn+1.)*rlap)
                elapn = elap**npowhd
                dmp(k,j)  = hdiff*elapn
                dmpd(k,j) = hdifd*elapn
                dmps(k,j) = hdifs*elap
            end do
            ! dmps(1,j)=0.
        end do

        ! 5.2 Orographic correction terms for temperature and humidity
        !     (vertical component)
        rgam = rgas*gamma/(1000.*grav)
        qexp = hscale/hshum

        tcorv(1)=0.
        qcorv(1)=0.
        qcorv(2)=0.

        do k = 2, kx
            tcorv(k) = fsg(k)**rgam
            if (k.gt.2) qcorv(k) = fsg(k)**qexp
        end do
    end subroutine

    !> Adds horizontal diffusion tendency of field to spectral tendency fdt
    !  using damping coefficients dmp and dmp1.
    function do_horizontal_diffusion_2d(field, fdt_in, dmp, dmp1) result(fdt_out)
        complex, intent(in) :: field(mx,nx), fdt_in(mx,nx)
        complex :: fdt_out(mx,nx)
        real, intent(in) :: dmp(mx,nx), dmp1(mx,nx)

        fdt_out = (fdt_in - dmp*field)*dmp1
    end function

    !> Adds horizontal diffusion tendency of field to spectral tendency fdt
    !  at all model levels using damping coefficients dmp and dmp1.
    function do_horizontal_diffusion_3d(field, fdt_in, dmp, dmp1) result(fdt_out)
        complex, intent(in) :: field(mx,nx,kx), fdt_in(mx,nx,kx)
        complex :: fdt_out(mx,nx,kx)
        real, intent(in) :: dmp(mx,nx), dmp1(mx,nx)
        integer :: k

        do k = 1, kx
            fdt_out(:,:,k) = do_horizontal_diffusion_2d(field(:,:,k), fdt_in(:,:,k), dmp, dmp1)
        end do
    end function
end module