module berror 18,1
!$$$ module documentation block
! . . . .
! module: berror contains information pertaining to the background error
! prgmmr: kleist org: np20 date: 2004-01-01
!
! abstract: contains information pertaining to the background error
!
! program history log:
! 2004-01-01 kleist
! 2004-11-03 treadon - add horizontal scale weighting factors
! 2004-11-16 treadon - add longitude dimension to variance (dssv) array
! 2004-11-22 derber - modify horizontal table definition
! 2005-01-22 parrish - clean up code by using module balmod
! 2005-02-23 wu - add subroutine set_nrh_var
! 2005-05-24 pondeca - accommodate 2dvar only surface analysis option
! in set_predictors_var and create_berror_vars_reg
! 2005-06-06 wu - initialize logical fstat
! 2005-10-06 wu - set ozmz values in regional mode
! 2005-11-16 wgu - set nmix=nr+1+(ny-nlat)/2 to make sure
! nmix+nrmxb=nr in routine smoothrf no matter what
! number nlat is
! 2005-11-16 wgu - set ny to be odd number if nlat is odd number
! to support GMAO grid
! 2005-11-29 derber - remove set_ozone_var (included in prewgt_reg and prewgt)
! 2006-01-09 derber - remove set_nrh_var and move capability to compute_derived
! 2006-04-21 kleist - add capability to perturb background error parameters
!
! subroutines included:
! sub init_berror - initialize background error related variables
! sub create_berror_vars - allocate global background error related variables
! sub destroy_berror_vars - deallocate global background error
! related variables
! sub set_predictor_var - set background variances for bias correction coefs
! sub init_rftable - load global/global pointers and tables for
! recursive filters
! sub initable - initialize tables/pointers for recursive filters
! sub create_berror_vars_reg - allocate regional background error
! related variables
! sub destroy_berror_vars_reg - deallocate regional background error
! related variables
!
! Variable Definitions:
! def norh - order of interpolations in smoother
! def ndeg - degree of smoothing
! def nta - first dimension of table (granularity of smoothing coef)
! def nx - number longitudes for rf patches
! def ny - number latitudes for rf patches
! def mr - subdomain dimension for patches
! def nr - subdomain dimension for patches
! def nf - subdomain dimension for patches
! def nlath - half the number of latitudes
! def ii - array that point to the x location in table for smoothing
! def jj - array that point to the y location in table for smoothing
! def ii1 - array that point to the x location in table for smoothing
! - for northern pole patch
! def jj1 - array that point to the y location in table for smoothing
! - for northern pole patch
! def ii2 - array that point to the x location in table for smoothing
! - for southern pole patch
! def jj2 - array that point to the y location in table for smoothing
! - for southern pole patch
! def aw - array that point to the x location in table for smoothing
! def bw - factor in background error calculation
! def as - normalized scale factor for background error (see namelist setup)
! def vs - scale factor for background error vertical scales
! def be - smoother coefficients
! def bl - blending coefficients for lat/lon boundaries
! def bl2 - blending coefficients lat/lon boundaries
! def varprd - variance for predictors
! def wmask - not used, function of land-sea mask
! def table - table of coeffients for smoothing
! def slw - horizontal scale info for 1st patch
! def slw1 - horizontal scale info for 2nd patch
! def slw2 - horizontal scale info for 3rd patch
! def wtaxs - weights for polar-cascade interpolation
! def wtxrs - weights for the step, hybrid to polar grid
! def inaxs - index for polar-cascade interpolation
! def inxrs - index for polar-cascade interpolation
! def dssv - vertical smoother coefficients including variances
! def dssvl - variances for single level variables
! def dssv2 - variances (lat,lon) for sea surface temperature
! def alv - vertical smoother coefficients
! def hzscl - scale factor for background error horizontal scales
! def hswgt - empirical weights to apply to each horizontal scale
! def pert_berr - logical for turning on background error parameter perturbations
! def pert_berr_fct - scaling factor for randum numbers for berror perturbations
!
! attributes:
! language: f90
! machine: ibm RS/6000 SP
!
!$$$ end documentation block
use kinds
, only: r_kind,i_kind
implicit none
integer(i_kind) norh,ndeg,nta,nlath
integer(i_kind) nx,ny,mr,nr,nf
integer(i_kind),allocatable,dimension(:,:):: inaxs,inxrs
integer(i_kind),allocatable,dimension(:,:,:,:):: ii,jj,ii1,jj1,ii2,jj2
real(r_kind) bw,vs
real(r_kind),dimension(10):: as
real(r_kind),dimension(3):: hzscl,hswgt
real(r_kind),allocatable,dimension(:):: be,bl,bl2,varprd
real(r_kind),allocatable,dimension(:,:):: table,&
slw,slw1,slw2
real(r_kind),allocatable,dimension(:,:):: dssvl,dssv2
real(r_kind),allocatable,dimension(:,:,:):: wtaxs,wtxrs
real(r_kind),allocatable,dimension(:,:,:,:):: alv,dssv
logical pert_berr
real(r_kind) pert_berr_fct
contains
subroutine init_berror 1,3
!$$$ subprogram documentation block
! . . . .
! subprogram: init_berror initializes constants for the background error
! prgmmr: kleist org: np20 date: 2004-01-01
!
! abstract: intializes constants for the background error
!
! program history log:
! 2004-01-01 kleist
! 2004-11-03 treadon - add default definition for horizontal scale weighting factors
! 2005-06-06 wu - add logical fstat
!
! input argument list:
!
! output argument list:
!
! attributes:
! language: f90
! machine: ibm RS/6000 SP
!
!$$$
use kinds
, only: i_kind
use constants
, only: zero,one,three
use balmod
, only: fstat
implicit none
integer(i_kind) i
fstat = .false.
pert_berr = .false.
pert_berr_fct = zero
norh=2
ndeg=4
nta=50000
nlath=48
bw=zero
do i=1,10
as(i)=0.60_r_kind
end do
do i=1,3
hzscl(i)=one
hswgt(i)=one/three
end do
vs=one/1.5_r_kind
return
end subroutine init_berror
subroutine create_berror_vars 1,4
!$$$ subprogram documentation block
! . . . .
! subprogram: create_berror_vars create arrays for global background error
! prgmmr: kleist org: np20 date: 2004-01-01
!
! abstract: creates arrays for global background error
!
! program history log:
! 2004-01-01 kleist
! 2004-07-28 treadon - remove subroutine argument list to --> use modules
! 2004-11-16 treadon - add longitude dimension to array dssv
!
! input argument list:
!
! output argument list:
!
! attributes:
! language: f90
! machine: ibm RS/6000 SP
!
!$$$
use balmod
, only: llmin,llmax
use gridmod
, only: nlat,nlon,lat2,lon2,nsig,nsig1o
use radinfo
, only: jpch,npred
use pcpinfo
, only: jtype,npredp
implicit none
llmin=1
llmax=nlat
! Grid constant to transform to 3 pieces
nx=nlon*3/2
nx=nx/2*2
ny=nlat*8/9
ny=ny/2*2
if(mod(nlat,2)/=0)ny=ny+1
mr=0
nr=nlat/4
nf=nr
nlath=nlat/2
if(mod(nlat,2)/=0) nlath=nlath+1
allocate(wtaxs(0:norh*2-1,nf,0:(nlon/8)-1), &
wtxrs(0:norh*2-1,0:(nlon/8)-1,mr:nr), &
be(ndeg), &
bl(nx-nlon), &
bl2(nr+1+(ny-nlat)/2), &
alv(lat2,ndeg,nsig,6), &
dssv(6,lat2,lon2,nsig),&
dssvl(lat2,3),&
dssv2(lat2,lon2))
allocate(varprd(jpch*npred+jtype*npredp))
allocate(inaxs(nf,nlon/8), &
inxrs(nlon/8,mr:nr) )
allocate(slw(ny*nx,nsig1o),&
slw1((2*nf+1)*(2*nf+1),nsig1o),&
slw2((2*nf+1)*(2*nf+1),nsig1o))
allocate(ii(ny,nx,3,nsig1o),jj(ny,nx,3,nsig1o),&
ii1(2*nf+1,2*nf+1,3,nsig1o),jj1(2*nf+1,2*nf+1,3,nsig1o),&
ii2(2*nf+1,2*nf+1,3,nsig1o),jj2(2*nf+1,2*nf+1,3,nsig1o))
return
end subroutine create_berror_vars
subroutine destroy_berror_vars 1
!$$$ subprogram documentation block
! . . . .
! subprogram: destroy_berror_vars deallocates global background error arrays
! prgmmr: kleist org: np20 date: 2004-01-01
!
! abstract: deallocates global background error arrays
!
! program history log:
! 2004-01-01 kleist
! 2005-03-03 treadon - add implicit none
!
! input argument list:
!
! output argument list:
!
! attributes:
! language: f90
! machine: ibm RS/6000 SP
!
!$$$
implicit none
deallocate(wtaxs,wtxrs,be,table,bl,bl2,alv,&
dssv,dssvl,dssv2,inaxs,inxrs,&
varprd)
deallocate(slw,slw1,slw2)
deallocate(ii,jj,ii1,jj1,ii2,jj2)
return
end subroutine destroy_berror_vars
subroutine set_predictors_var 1,5
!$$$ subprogram documentation block
! . . . .
! subprogram: set_predictors_var sets variances for bias correction predictors
! prgmmr: kleist org: np20 date: 2004-01-01
!
! abstract: sets variances for bias correction predictors
!
! program history log:
! 2004-01-01 kleist
! 2004-07-28 treadon - remove subroutine calling list, pass through module
! 2005-05-24 pondeca - take into consideration that nrclen=0 for 2dvar only
! surface analysis option
!
! input argument list:
!
! output argument list:
!
! attributes:
! language: f90
! machine: ibm RS/6000 SP
!
!$$$
use kinds
, only: i_kind,r_kind
use constants
, only: one,one_tenth
use radinfo
, only: npred,jpch
use pcpinfo
, only: npredp,jtype
use jfunc
, only: nrclen
implicit none
integer(i_kind) i
real(r_kind) stndev
stndev = one/one_tenth ! 0.316 K background error
do i=1,max(1,nrclen)
varprd(i)=stndev
end do
return
end subroutine set_predictors_var
subroutine init_rftable(mype,rate,sli,sli1,sli2) 2,10
!$$$ subprogram documentation block
! . . . .
! subprogram: init_rftable initializes constants for the background error
! prgmmr: kleist org: np20 date: 2004-01-01
!
! abstract: intializes constants for the global background error
!
! program history log:
! 2004-01-01 kleist
! 2004-11-22 derber - modify to do both global and regional, make table
! reproducible with different number of processors and
! save only those elements of table which are used
! 2005-06-10 devenyi/treadon - remove mype from call rfdparv
!
! input argument list:
! sli - horizontal scale info for 1st patch
! sli1 - horizontal scale info for 2nd patch (optional)
! sli2 - horizontal scale info for 3rd patch (optional)
!
! output argument list:
!
! attributes:
! language: f90
! machine: ibm RS/6000 SP
!
!$$$
use kinds
, only: i_kind,r_kind
use gridmod
, only: nsig,nsig1o,regional
use mpimod
, only: levs_id,npe
use constants
, only: zero,one,two,four
implicit none
real(r_kind),parameter:: tin = 0.2e-3_r_kind
integer(i_kind) i,j,k,n,nynx,nfnf
integer(i_kind) nnn,mype,ihwlb
integer(i_kind) nfg,ntax,iloc
real(r_kind),optional,dimension((2*nf+1)*(2*nf+1),3,nsig1o):: sli1,sli2
real(r_kind),dimension(ny*nx,3,nsig1o):: sli
real(r_kind),dimension(ndeg):: rate
real(r_kind):: hwlmax,hwlmin,hwlb,hwle,wni2
real(r_kind),parameter:: r999 = 999.0_r_kind
real(r_kind),allocatable,dimension(:):: dsh
logical,allocatable,dimension(:):: iuse
integer(i_kind),allocatable,dimension(:):: ipoint
nynx=ny*nx
if(.not. regional)then
if(.not. present(sli1) .or. .not. present(sli2))then
write(6,*)'INIT_RFTABLE: ***ERROR*** sli1 or sli2 not present'
call stop2
(34)
end if
nfg=nf*2+1
nfnf=nfg*nfg
end if
nnn=0
do k=1,nsig1o
if (levs_id(k)/=0) nnn=nnn+1
end do
! Determine lower/upper bounds on scales
hwlmax=-r999
hwlmin=r999
do k=1,nnn
! Load slw arrays
do j=1,nynx
slw(j,k)=sli(j,1,k)
end do
do j=1,nynx
hwlmax=max(hwlmax,sli(j,2,k))
hwlmin=min(hwlmin,sli(j,2,k))
end do
do j=1,nynx
hwlmax=max(hwlmax,sli(j,3,k))
hwlmin=min(hwlmin,sli(j,3,k))
end do
if(.not. regional)then
do j=1,nfnf
slw1(j,k) = sli1(j,1,k)
slw2(j,k) = sli2(j,1,k)
end do
do j=1,nfnf
hwlmax=max(hwlmax,sli1(j,2,k))
hwlmin=min(hwlmin,sli1(j,2,k))
hwlmax=max(hwlmax,sli2(j,2,k))
hwlmin=min(hwlmin,sli2(j,2,k))
end do
do j=1,nfnf
hwlmax=max(hwlmax,sli1(j,3,k))
hwlmin=min(hwlmin,sli1(j,3,k))
hwlmax=max(hwlmax,sli2(j,3,k))
hwlmin=min(hwlmin,sli2(j,3,k))
end do
end if
enddo
! factor from multi-Gaussian RF
! write(6,*)'INIT_RFTABLE: hwlmax...=',hwlmax,hwlmin,&
! hzscl(1),hzscl(2),hzscl(3),mype,nynx,nnn
hwlmax=hwlmax*max(hzscl(1),hzscl(2),hzscl(3))
hwlmin=hwlmin*min(hzscl(1),hzscl(2),hzscl(3))
! setup smoother coef and scale
if (hwlmax==zero .or. hwlmin==zero) then
write(6,*)'INIT_RFTABLE: ***ERROR*** illegal value for min,max scale.',&
' hwlmin,hwlmax=',hwlmin,hwlmax,mype
call stop2
(41)
endif
hwlb=one/hwlmax
hwle=one/hwlmin
ihwlb=hwlb/tin
hwlb=ihwlb*tin
! tin=(hwle-hwlb)/float(nta-1)
ntax=(hwle-hwlb)/tin+2
! write(6,*)'INIT_RFTABLE: tin ',ntax,ihwlb,tin,hwlb,hwle
allocate(iuse(ntax))
iuse=.false.
wni2=one/tin
do k=1,nnn
do n=2,3
do i=1,nynx
do j=1,3
iloc=min(ntax,nint(one+wni2*(one/(hzscl(j)*sli(i,n,k))-hwlb)))
iuse(iloc)=.true.
enddo
enddo
if(.not. regional)then
do i=1,nfg*nfg
do j=1,3
iloc=min(ntax,nint(one+wni2*(one/(hzscl(j)*sli1(i,n,k))-hwlb)))
iuse(iloc)=.true.
iloc=min(ntax,nint(one+wni2*(one/(hzscl(j)*sli2(i,n,k))-hwlb)))
iuse(iloc)=.true.
enddo
enddo
end if
enddo
enddo
nta=0
allocate(dsh(ntax),ipoint(ntax))
ipoint=0
do i=1,ntax
if(iuse(i))then
nta=nta+1
ipoint(i)=nta
dsh(nta)=one/(float(i-1)*tin+hwlb)
end if
end do
! write(6,*)'INIT_RFTABLE: ntax,nta = ',ntax,nta
! Loop over number of sigma levels per task
do k=1,nnn
! Load pointers into table array
do j=1,3
call initable
(ny,nx,sli(1,1,k),nta,ntax,hwlb,&
ii(1,1,j,k),jj(1,1,j,k),hzscl(j),tin,ipoint)
if(.not. regional)then
call initable
(nfg,nfg,sli1(1,1,k),nta,ntax,hwlb,&
ii1(1,1,j,k),jj1(1,1,j,k),hzscl(j),tin,ipoint)
call initable
(nfg,nfg,sli2(1,1,k),nta,ntax,hwlb,&
ii2(1,1,j,k),jj2(1,1,j,k),hzscl(j),tin,ipoint)
end if
end do
! End of loop over number of sigma levels per mpi task
end do
deallocate(iuse,ipoint)
allocate(table(nta,ndeg))
call rfdparv
(dsh,rate,table,nta,ndeg)
deallocate(dsh)
return
end subroutine init_rftable
subroutine initable(nxdim,nydim,sli,nta,ntax,hwlb,iix,jjx,factor,tin,ipoint) 3,2
!$$$ subprogram documentation block
! . . . .
! subprogram: initable initializes pointers to table for background error
! prgmmr: kleist org: np20 date: 2004-01-01
!
! abstract: initializes pointers to table for global and regional background error
!
! program history log:
! 2004-01-01 kleist
! 2004-11-22 derber - modify to be consistent with init_rftable
!
! input argument list:
! nxdim - 1st dimension of arrays
! nydim - 2nd dimension of arrays
! sli - horizontal scale info
! nta - number of entries in table array
! ntax - number of possible entries in table array
! hwlb - minimum of possible coefficient values
! factor - horizontal scale factor
! tin - table interval
! ipoint - pointer at table locations
!
! output argument list:
! iix - first index pointer array to table
! jjx - second index pointer array to table
!
! attributes:
! language: f90
! machine: ibm RS/6000 SP
!
!$$$
use kinds
, only: r_kind,i_kind
use constants
, only: one
implicit none
integer(i_kind) iy,nydim,ix,nxdim,im,nta,iloc,ntax
integer(i_kind),dimension(nxdim,nydim):: iix,jjx
integer(i_kind),dimension(ntax):: ipoint
real(r_kind) wni2,hwlb,factor,tin
real(r_kind),dimension(nxdim,nydim,3):: sli
! Load pointers for table array
wni2=one/tin
do iy=1,nydim
do ix=1,nxdim
iloc=min(ntax, max(1, nint(one+wni2*(one/(sli(ix,iy,2)*factor)-hwlb))))
iix(ix,iy)=ipoint(iloc)
iloc=min(ntax, max(1, nint(one+wni2*(one/(sli(ix,iy,3)*factor)-hwlb))))
jjx(ix,iy)=ipoint(iloc)
enddo
enddo
return
end subroutine initable
subroutine create_berror_vars_reg(mype) 1,5
!$$$ subprogram documentation block
! . . . .
! subprogram: create_berror_vars_reg create arrays for reg background error
! prgmmr: kleist org: np20 date: 2004-01-01
!
! abstract: creates arrays for regional background error
!
! program history log:
! 2004-01-01 kleist
! 2004-07-28 treadon - simplify subroutine calling list
! 2004-11-16 treadon - add longitude dimension to array dssv
! 2005-05-24 pondeca - take into consideration that npred=npredp=0
! for 2dvar only surface analysis option
! 2005-06-23 middlecoff/treadon - iniitalize mr,nr,nf
!
! input argument list:
!
! output argument list:
! mype - mpi task id
!
! attributes:
! language: f90
! machine: ibm RS/6000 SP
!
!$$$
use kinds
, only: i_kind
use balmod
, only: llmin,llmax
use gridmod
, only: nlat,nlon,nsig,nsig1o,lat2,lon2
use radinfo
, only: jpch,npred
use pcpinfo
, only: jtype,npredp
implicit none
integer(i_kind),intent(in):: mype
nx=nlon
ny=nlat
mr=1
nr=1
nf=nr
! Grid constant for background error
allocate(be(ndeg), &
alv(llmin:llmax,ndeg,nsig,6), &
dssv(6,llmin:llmax,lon2,nsig), &
dssvl(llmin:llmax,3), &
dssv2(lat2,lon2))
allocate(varprd(max(1,jpch*npred+jtype*npredp) ) )
allocate(slw(ny*nx,nsig1o) )
allocate(ii(ny,nx,3,nsig1o),jj(ny,nx,3,nsig1o) )
return
end subroutine create_berror_vars_reg
subroutine destroy_berror_vars_reg 1
!$$$ subprogram documentation block
! . . . .
! subprogram: destroy_berror_vars_reg deallocate reg background error arrays
! prgmmr: kleist org: np20 date: 2004-01-01
!
! abstract: deallocates regional background error arrays
!
! program history log:
! 2004-01-01 kleist
! 2005-03-03 treadon - add implicit none
!
! input argument list:
!
! output argument list:
!
! attributes:
! language: f90
! machine: ibm RS/6000 SP
!
!$$$
implicit none
deallocate(be,table,alv,&
dssv,dssvl,dssv2,&
varprd)
deallocate(slw)
deallocate(ii,jj)
return
end subroutine destroy_berror_vars_reg
end module berror