! Conformal Cubic Atmospheric Model
! Copyright 2015 Commonwealth Scientific Industrial Research Organisation (CSIRO)
! This file is part of the Conformal Cubic Atmospheric Model (CCAM)
!
! CCAM is free software: you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
! CCAM is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with CCAM. If not, see .
!------------------------------------------------------------------------------
module height_m
implicit none
real, private, allocatable, save, dimension(:) :: bet, betm
contains
subroutine initheight(nl,sig)
use physparams
integer, intent(in) :: nl
real, intent(in), dimension(:) :: sig
integer :: k
real :: c
! MJT - Complete rewrite of this routine for compatability with CCAM
allocate( bet(nl), betm(nl) )
! lapsbot=0 option from CCAM's indata.f
do k=1,nl-1
bet(k+1)=rdry*log(sig(k)/sig(k+1))*0.5
end do
c=grav/stdlapse
bet(1)=c*(sig(1)**(-rdry/c)-1.)
betm(:)=bet(:)
return
end subroutine initheight
!-----------------------------------------------------------------
subroutine height ( tg, qg, zg, pg, sig, phistd, pstd )
! Calculate geopotential height using virtual temperature
! If the optional argument pstd is present it specifies the pressure levels
! on which to calculate the height. Otherwise return sigma level heights.
#ifdef usenc_mod
use netcdf, only : NF90_FILL_FLOAT
#else
use netcdf_m, only : NF90_FILL_FLOAT
#endif
use physparams
use s2p_m
real, intent(in), dimension(:,:,:) :: tg, qg
real, intent(in), dimension(:,:) :: zg, pg
real, intent(in), dimension(:) :: sig
real, intent(in), dimension(:), optional :: pstd
real, intent(out), dimension(:,:,:) :: phistd
real, dimension(size(tg,1),size(tg,3)) :: tv, phi
integer :: j, k, lg, mg, kstd, ii
real, dimension(size(tg,1)) :: siglev
real :: bettemp, c
integer :: nx, ny, nl, nstd
nx = size(tg,1)
ny = size(tg,2)
nl = size(sig)
if ( present ( pstd ) ) then
nstd = size(pstd)
else
nstd = nl
end if
if ( nstd /= size(phistd,3) ) then
print*, "Error, Incorrect size of array phistd in routine height"
stop
end if
! MJT - complete rewrite of this routine for compatibility with CCAM
c=grav/stdlapse
do lg=1,ny
! Calculate virtual temperature.
tv = tg(:,lg,:) * (epsil+qg(:,lg,:))/(epsil*(1.+qg(:,lg,:)))
! Calculate height on sigma levels
phi(:,1) = zg(:,lg) * grav + bet(1)*tv(:,1)
do k=2,nl
phi(:,k) = phi(:,k-1)+bet(k)*tv(:,k)+betm(k)*tv(:,k-1)
end do
! Now calculate the height at the standard pressure levels.
if ( present ( pstd ) ) then
do kstd = 1,nstd
siglev = pstd(kstd)/pg(:,lg)
do mg=1,nx
if ( siglev(mg)>sig(1) ) then
if ( vextrap == vextrap_missing ) then
phistd(mg,lg,kstd) = -NF90_FILL_FLOAT ! local missing flag
else
bettemp=c*(siglev(mg)**(-rdry/c)-1.)
phistd(mg,lg,kstd) = (zg(mg,lg)*grav+bettemp*tv(mg,1))/grav
end if
else
ii = 1
do while ( siglev(mg)