SUBROUTINE RDSPPTOT(poper,knstatlev,kulbgsto) 1,13
#if defined (DOC)
*
**s/r rdspptot -Read in balance operator spectral coefficients
* .
* Purpose
* . Read in coefficients for P_to_T operator and also turning angle
* for balanced divergence operator
* . Vertical interpolation of operators
*
*Author : S. Pellerin *ARMA/AES February, 2000
*Revision:
* JM Belanger CMDA/SMC Jul 2000
* . 32 bits conversion
* Y.J Rochon *ARQX, Nov 2008
* . Reading and setting of new balance operators
* (*BAL_*C).
*
#endif
IMPLICIT NONE
*implicits
*
* Global variables
*
#include "comdim.cdk"
#include "comlun.cdk"
#include "comleg.cdk"
#include "comstate.cdk"
#include "comcorr.cdk"
#include "rpnstd.cdk"
#include "comspg.cdk"
#include "cominterp.cdk"
#include "comcva.cdk"
*
* Local variables
*
integer knstatlev,kulbgsto
real*8 poper(nflev,knstatlev)
*
integer jn, jk1, jk2, ikey, ilen,jlat,jcol
real*8 zsptheta, zgrtheta, zleg,zwork
real*8 zptotsrc,zspptot,zgrptot,ztheta,zptotecr
& ,zptotmix
real*8 zrgsigtt,zfact
c
pointer (pxzrgsigtt,zrgsigtt(nj,nflev))
pointer (pxzsptheta,zsptheta(0:ntrunc,nflev)),(pxzgrtheta
& ,zgrtheta(nj,nflev))
pointer (pxzspptot,zspptot(0:ntrunc,nflev+1,nflev))
pointer (pxzgrptot,zgrptot(nj,nflev+1,nflev))
pointer (pxzleg,zleg(0:ntrunc,nj))
pointer (pxzptotecr,zptotecr(nflev+1,nflev,nj))
*
pointer (pxzptotmix,zptotmix(nflev+1,knstatlev))
*
pointer (pxzptotsrc,zptotsrc(knstatlev+1,knstatlev))
pointer (pxztheta,ztheta(knstatlev))
*
**
integer vfstlir,vfstecr
external vfstlir,vfstecr
C ------------------------------------------------------
write(nulout,*) 'RDSPPTOT - Begin'
call vflush(nulout)
*
* Allocating a local array
*
ilen = (ntrunc + 1)*nflev
call hpalloc(pxzsptheta,max(1,ilen),ierr,8)
ilen = nj * nflev
call hpalloc(pxzgrtheta,max(1,ilen),ierr,8)
call hpalloc(pxzrgsigtt,max(1,ilen),ierr,8)
ilen = (ntrunc+1) * (nflev+1) * nflev
call hpalloc(pxzspptot,max(1,ilen),ierr,8)
ilen = nj * (nflev + 1) * nflev
call hpalloc(pxzgrptot,max(1,ilen),ierr,8)
ilen = (ntrunc + 1) * nj
call hpalloc(pxzleg,max(1,ilen),ierr,8)
ilen = nj * (nflev + 1) * nflev
call hpalloc(pxzptotecr,max(1,ilen),ierr,8)
*
ilen = (nflev+1) * knstatlev
call hpalloc(pxzptotmix,max(1,ilen),ierr,8)
*
ilen = (knstatlev + 1) * knstatlev
call hpalloc(pxzptotsrc,max(1,ilen),ierr,8)
ilen = knstatlev
call hpalloc(pxztheta,max(1,ilen),ierr,8)
*
* set up simple spectral transforms
*
write(nulout,*) 'RDSPPTOT: Set up simple spectral transforms'
call vflush(nulout)
call zlegpol(zleg,rmu,nj,ntrunc,ntrunc,nj)
C
C Read and set new balance operators BAL_TBPP_CC and BAL_UTPP_UC
C
C Read TT std dev
C
ip1 = -1
ip2 = -1
ip3 = -1
idateo = -1
cletiket = 'STDDEV'
cltypvar = 'E'
clnomvar = 'TT'
ikey = vfstlir
(zrgsigtt,nulbgst,ini,inj,ink
& ,idateo,cletiket,ip1,ip2,ip3,cltypvar,clnomvar)
IF(IKEY .LT.0 ) THEN
ibal_tbpp_cc=0
write(NULOUT,*)
& 'RDSPPTOT: TT STDDEV not available.'
go to 150
ENDIF
C****
c ibal_tbpp_cc=0
c go to 150
C****
ip1 = -1
ip3 = -1
idateo = -1
cletiket = 'SP_TBCC'
cltypvar = 'X'
clnomvar = 'ZZ'
C
write(nulout,*) 'RDSPPTOT: Start reading in TBPP_CC from unit:'
& ,nulbgst
call vflush(nulout)
ibal_tbpp_cc=1
do jn = 0,ntrunc
ip2 = jn
ikey = vfstlir
(ztheta,nulbgst,ini,inj,ink
& ,idateo,cletiket,ip1,ip2,ip3,cltypvar,clnomvar)
c
IF(IKEY .LT.0 ) THEN
ibal_tbpp_cc=0
write(NULOUT,*)
& 'RDSPPTOT: BAL_TBPP_CC not available.'
exit
ENDIF
c
if (ini .ne. knstatlev) then
CALL ABORT3D(NULOUT
& ,'RDSPPTOT: BG stat levels inconsitencies')
endif
c
if(lvintbgstat) then
c
c Vertical interpolation O'm = Vmn On
c
call mxmaop1(poper,1,nflev,ztheta,1,knstatlev,zsptheta(jn,1)
& ,ntrunc+1,1,nflev,knstatlev,1)
else
do jk1 = 1,nflev
zsptheta(jn,jk1) = ztheta(jk1)
enddo
endif
c
enddo
c
c Converting BAL_TBPP_CC in physical space
c
if (ibal_tbpp_cc.eq.1) then
c
write(nulout,*) 'RDSPPTOT: Converting tbpp_cc in physical space'
call vflush(nulout)
call zleginv2
(zgrtheta,zsptheta,zleg,ntrunc,nj,nflev,nj,nflev
& ,ntrunc)
c
c write(nulout,*) 'TB_CC ',(zgrtheta(jlat,6),jlat=1,nj)
do jlat = 1, nj
do jk1 = 1, nflev
C
C Set TB std dev
C
zfact=sqrt(max(0.01D0,
& zrgsigtt(jlat,jk1)**2-rgsig(jlat,nsposit(nstt)+jk1-1)**2))
C
C Complete balance operator
C
if (abs(zgrtheta(jlat,jk1)).lt.0.05) zgrtheta(jlat,jk1)=0.0D0
bal_tbpp_cc(jk1,jlat) = zgrtheta(jlat,jk1)*
& rgsig(jlat,nsposit(nsdiv)+jk1-1)/zfact
C
C Correspondingly adjust std. dev. of related analysis increment var.
C
rgsig(jlat,nsposit(nsdiv)+jk1-1)=
& sqrt(max(0.0001*rgsig(jlat,nsposit(nsdiv)+jk1-1)**2,
& rgsig(jlat,nsposit(nsdiv)+jk1-1)**2*
& (1.0-zgrtheta(jlat,jk1)**2)))
end do
end do
c write(nulout,*) 'TB_CC ',(bal_tbpp_cc(6,jlat),jlat=1,nj)
open(unit=668,file='./uc_stddev.asc',status='UNKNOWN')
do jk1=0, nflev-1
write(668,400)(rgsig(jlat,nsposit(nsdiv)+jk1),jlat=nj,1,-1)
enddo
write(668,*)
close (unit=668,status='KEEP')
400 format(2x, 7(g11.5, 3x))
end if
C
150 continue
C
write(nulout,*) 'RDSPPTOT: Start reading in UTPP_CC from unit:'
& ,nulbgst
C
C NOTE: Correl(UT,CC) = correl(UT,UC) given that correl(UT,CCB)=0
C where CCB=part of CC from balance with PSI and thus TB (from region
C away from the surface), i.e.
C
C Balance operator = correl(UT,UC)*sigma(UT)/sigma(UC)
C = correl(UT,CC)*sigma(UT)/sigma(UC)
C
C where sigma^2(UC) = sigma^2(CC)- sigma^2(CCB)
C and sigma(UC)= rgsig part for nsposit(nsdiv) set above
C
ip1 = -1
ip3 = -1
idateo = -1
cletiket = 'SP_UTCC'
cltypvar = 'X'
clnomvar = 'ZZ'
C
call vflush(nulout)
ibal_utpp_uc=1
do jn = 0,ntrunc
ip2 = jn
ikey = vfstlir
(ztheta,nulbgst,ini,inj,ink
& ,idateo,cletiket,ip1,ip2,ip3,cltypvar,clnomvar)
c
IF(IKEY .LT.0 ) THEN
ibal_utpp_uc=0
write(NULOUT,*)
& 'RDSPPTOT: BAL_UTPP_CC not available.'
exit
ENDIF
c
if (ini .ne. knstatlev) then
CALL ABORT3D(NULOUT
& ,'RDSPPTOT: BG stat levels inconsitencies')
endif
c
if(lvintbgstat) then
c
c Vertical interpolation O'm = Vmn On
c
call mxmaop1(poper,1,nflev,ztheta,1,knstatlev,zsptheta(jn,1)
& ,ntrunc+1,1,nflev,knstatlev,1)
else
do jk1 = 1,nflev
zsptheta(jn,jk1) = ztheta(jk1)
enddo
endif
c
enddo
c
c Converting BAL_UTPP_UC in physical space
c
if (ibal_utpp_uc.eq.1) then
C
write(nulout,*) 'RDSPPTOT: Converting UTPP_UC in physical space'
call vflush(nulout)
call zleginv2
(zgrtheta,zsptheta,zleg,ntrunc,nj,nflev,nj,nflev
& ,ntrunc)
c
c write(nulout,*) 'UT_CC ',(zgrtheta(jlat,6),jlat=1,nj)
do jlat = 1, nj
do jk1 = 1, nflev
C
C Complete balance operator
C
if (abs(zgrtheta(jlat,jk1)).lt.0.05) zgrtheta(jlat,jk1)=0.0D0
bal_utpp_uc(jk1,jlat) = zgrtheta(jlat,jk1)*
& rgsig(jlat,nsposit(nstt)+jk1-1)/
& rgsig(jlat,nsposit(nsdiv)+jk1-1)
C
C Correspondingly adjust std. dev. of related analysis increment var.
C
rgsig(jlat,nsposit(nstt)+jk1-1)=
& sqrt(max(0.0001D0,rgsig(jlat,nsposit(nstt)+jk1-1)**2*
& (1.0-zgrtheta(jlat,jk1)**2)))
end do
end do
c write(nulout,*) 'UT_CC ',(bal_utpp_uc(6,jlat),jlat=1,nj)
open(unit=668,file='./ut_stddev.asc',status='UNKNOWN')
do jk1=0, nflev-1
write(668,400)(rgsig(jlat,nsposit(nstt)+jk1),jlat=nj,1,-1)
enddo
write(668,*)
close (unit=668,status='KEEP')
end if
c
if (kulbgsto.gt. 0 ) then
ierr = fstprm(ikey,idateo,ideet,inpas,ini,inj,ink, inbits,
& idatyp,ip1,ip2,ip3,cltypvar,clnomvar,cletiket,clgrtyp,ig1
& ,ig2,ig3,ig4,iswa,ilength,idltf,iubc,iextr1,iextr2,iextr3)
c
ini = nflev
inj = nj
ink = 0
ip1 = 0
ip2 = 0
c
if (ibal_tbpp_cc.eq.1) then
cletiket = 'TBPP_CC'
c
ierr = vfstecr
(bal_tbpp_cc,zwork,-inbits,kulbgsto,idateo,ideet,
& inpas, ini, inj, ink, ip1, ip2, ip3, cltypvar, clnomvar,
& cletiket,clgrtyp,ig1, ig2, ig3, ig4, idatyp, .true.)
c
end if
c
if (ibal_tbpp_cc.eq.1) then
cletiket = 'UTPP_UC'
c
ierr = vfstecr
(bal_utpp_uc,zwork,-inbits,kulbgsto,idateo,ideet,
& inpas, ini, inj, ink, ip1, ip2, ip3, cltypvar, clnomvar,
& cletiket,clgrtyp,ig1, ig2, ig3, ig4, idatyp, .true.)
c
end if
endif
C Read of spectral coefficients for theta
*
ip1 = -1
ip3 = -1
idateo = -1
cletiket = 'SP_THETA'
cltypvar = 'X'
clnomvar = 'ZZ'
C
c read of spectral coefficients for theta
c
write(nulout,*) 'RDSPPTOT: Start reading in THETA from unit:'
& ,nulbgst
call vflush(nulout)
do jn = 0,ntrunc
ip2 = jn
ikey = vfstlir
(ztheta,nulbgst,ini,inj,ink
& ,idateo,cletiket,ip1,ip2,ip3,cltypvar,clnomvar)
c
IF(IKEY .LT.0 ) THEN
CALL ABORT3D(NULOUT
& ,'RDSPPTOT: Problem with background stat file')
ENDIF
c
if (ini .ne. knstatlev) then
CALL ABORT3D(NULOUT
& ,'RDSPPTOT: BG stat levels inconsitencies')
endif
c
if(lvintbgstat) then
c
c Vertical interpolation O'm = Vmn On
c
call mxmaop1(poper,1,nflev,ztheta,1,knstatlev,zsptheta(jn,1)
& ,ntrunc+1,1,nflev,knstatlev,1)
else
do jk1 = 1,nflev
zsptheta(jn,jk1) = ztheta(jk1)
enddo
endif
*
enddo
*
c converting theta in physical space
c
write(nulout,*) 'RDSPPTOT: converting theta in physical space'
call vflush(nulout)
call zleginv2
(zgrtheta,zsptheta,zleg,ntrunc,nj,nflev,nj,nflev
& ,ntrunc)
*
do jlat = 1, nj
do jk1 = 1, nflev
theta(jk1,jlat) = zgrtheta(jlat,jk1)
end do
end do
c
if ( kulbgsto .gt. 0 ) then
ierr = fstprm(ikey,idateo,ideet,inpas,ini,inj,ink, inbits,
& idatyp,ip1,ip2,ip3,cltypvar,clnomvar,cletiket,clgrtyp,ig1
& ,ig2,ig3,ig4,iswa,ilength,idltf,iubc,iextr1,iextr2,iextr3)
c
ini = nflev
inj = nj
ink = 0
ip1 = 0
ip2 = 0
cletiket = 'THETA'
c
ierr = vfstecr
(theta, zwork, -inbits, kulbgsto, idateo, ideet,
& inpas, ini, inj, ink, ip1, ip2, ip3, cltypvar, clnomvar,
& cletiket,clgrtyp,ig1, ig2, ig3, ig4, idatyp, .true.)
c
endif
write(nulout,*) 'RDSPPTOT: Start Reading in SP_PtoT from unit:'
& ,nulbgst
ip1 = -1
ip2 = -1
ip3 = -1
idateo = -1
cletiket = 'SP_PtoT'
cltypvar = 'X'
clnomvar = 'ZZ'
C
c read of spectral coefficients for P to T operator
c
do jn = 0,ntrunc
ip2 = jn
ikey = vfstlir
(zptotsrc,nulbgst,ini,inj,ink
s ,idateo,cletiket,ip1,ip2,ip3,cltypvar,clnomvar)
c
IF(IKEY .LT.0 ) THEN
CALL ABORT3D(NULOUT
& ,'RDSPPTOT: Problem with background stat file')
ENDIF
c
if (ini .ne. knstatlev+1 .or. inj .ne. knstatlev) then
call abort3d(nulout
& ,'RDSPPTOT: BG stat levels inconsitencies')
endif
c
if(lvintbgstat) then
c
c Vertical interpolation of P to T
c First Vertical interpolation: P'mn = Vmn Pnn
c
call mxmaop1(poper,1,nflev,zptotsrc,1,knstatlev+1,zptotmix,1
& ,nflev+1,nflev,knstatlev,knstatlev)
c
c Copy of the bottom row (P to Ps) from zptotsrc to zptotmix
c
do jcol = 1, knstatlev
zptotmix(nflev+1,jcol) = zptotsrc(knstatlev+1,jcol)
enddo
c
c Second Vertical interpolation: P''mm = P'mn (Vnm)
c
call mxmaop1(zptotmix,1,nflev+1,poper,knstatlev,1,zspptot(jn,1
& ,1),ntrunc+1,(ntrunc+1)*(nflev+1),nflev+1,knstatlev,nflev
& )
c
else
do jk2 = 1,nflev
do jk1 = 1,nflev+1
zspptot(jn,jk1,jk2) = zptotsrc(jk1,jk2)
enddo
enddo
endif
enddo
c
write(nulout,*) 'RDSPPTOT: converting PtoT in physical space'
call vflush(nulout)
ilen = nflev*(nflev+1)
call zleginv2
(zgrptot,zspptot,zleg,ntrunc,nj,ilen,nj,ilen
& ,ntrunc)
c
do jlat = 1, nj
do jk2 = 1,nflev
do jk1 = 1, nflev+1
ptot(jk1,jk2,jlat) = zgrptot(jlat,jk1,jk2)
end do
end do
enddo
c COPY NH PTOT TO SH
if(LCOPYPTOT) then
do jk1=1,nflev+1
do jk2=1,nflev
do jlat=1,nj/2
ptot(jk1,jk2,nj-jlat+1)=ptot(jk1,jk2,jlat)
enddo
enddo
enddo
endif
c SCALE PTOT
do jk1=1,nflev+1
do jk2=1,nflev
do jlat=1,nj
ptot(jk1,jk2,jlat)=ptot(jk1,jk2,jlat)*RSCALEPTOT
enddo
enddo
enddo
c ---------------------------------------------------
if ( kulbgsto .gt. 0 ) then
ierr = fstprm(ikey,idateo,ideet,inpas,ini,inj,ink, inbits,
& idatyp,ip1,ip2,ip3,cltypvar,clnomvar,cletiket,clgrtyp,ig1
& ,ig2,ig3,ig4,iswa,ilength,idltf,iubc,iextr1,iextr2,iextr3)
c
do jlat = 1, nj
do jk2 = 1,nflev
do jk1 = 1, nflev + 1
zptotecr(jk1,jk2,jlat) = ptot(jk1,jk2,nj-jlat+1)
end do
end do
enddo
c
ini = nflev + 1
inj = nflev
ink = nj
ip1 = 0
ip2 = 0
cletiket = 'P_to_T'
c
ierr = vfstecr
(zptotecr, zwork, -inbits, kulbgsto, idateo,
& ideet, inpas, ini, inj, ink, ip1, ip2, ip3, cltypvar,
& clnomvar, cletiket,clgrtyp,ig1, ig2, ig3, ig4, idatyp,
& .true.)
c
endif
c
* 9. Deallocate local arrays
*
call hpdeallc(pxzleg,ierr,1)
c
call hpdeallc(pxztheta,ierr,1)
call hpdeallc(pxzsptheta,ierr,1)
call hpdeallc(pxzgrtheta,ierr,1)
call hpdeallc(pxzrgsigtt,ierr,1)
c
call hpdeallc(pxzptotsrc,ierr,1)
call hpdeallc(pxzptotmix,ierr,1)
call hpdeallc(pxzspptot,ierr,1)
call hpdeallc(pxzgrptot,ierr,1)
call hpdeallc(pxzptotecr,ierr,1)
*
write(nulout,*)'DONE in RDSPTOT'
c
return
end