SUBROUTINE CH_VCOLM(KNUM,KFLAG,KFLAG2,PINOUT,PROF, 4,2
1 CDBGTYP,pvtr,pobslev,pobslev2,
1 pressa,knflev,plat,klat,pstate,
1 cdstnid,cdvar,kmod,KKERN)
C
IMPLICIT NONE
C
C* Declaration of arguments
C
CHARACTER*(*) CDBGTYP,CDSTNID
CHARACTER*(*) cdvar
INTEGER knflev,kmod,knum,klat
INTEGER KFLAG(knum),KFLAG2(knum),KKERN
REAL*8 pvtr(knflev),pstate(knflev),pinout(knum),prof(knflev)
REAL*8 plat,pobslev(knum),pobslev2(knum),pressa(knflev)
C
*---------------------------------------------------------------------
#if defined (DOC)
*
***s/r CH_VCOLM -- Control module for forward/TLM model or adjoint model calculations
* related to observations of partial or total column amounts.
*
*Author : Y.J. Rochon and Y. Yang AQRB/MSC July 2005
*
*Revision:
*
** Purpose: Control module for forward/TLM model or adjoint model calculations
* related to observations of partial or total column amounts.
*
*Arguments:
*
* Input pvtr(nvlev) -- background/increment values at eta levels when kmod=0
* pinout(knum) -- Column amount (divided by std. dev.)
* when kmod=1
* kmod -- Flag indicating purpose of call:
* 0: Use as forward model
* 1: Use as adjoint of forward model.
* knvlev -- # of analysis vertical levels
* plat -- Latitude of obs. (=ROBHDR(NMCLAT,obsindex)
* klat -- Latitude index (=MOBHDR(NCMTLA,obsindex)
* cdvar -- Model variable name
* pstate(knflev) -- State profile for possible use in CH_GENOPER
* (see CH_VERTINTG)
* CDBGTYP -- 'HR' for high resolution (trial field) grid
* 'BG' for low resolution (rebm) grid
* knum -- # of obs elements in the obs profile
* kflag(knum) -- MOBDATA(NCMASS,*) for obs elements
* kflag2(knum) -- MOBDATA(NCMXTR,*) for obs elements
* prof(knflev) -- Initial GOMOBS segment when kmod=1
* kkern -- Use of averaging kernel
* 0 for no, position index for yes
*
* Output pinout(knum) -- Total or partial column amounts when kmod=0
* prof(knflev) -- Updated GOMOBS segment when kmod=1
* kflag(knum) -- MOBDATA(NCMASS,*) for obs elements
* kflag2(knum) -- MOBDATA(NCMXTR,*) for obs elements
*
* Others ztot -- partial (or total column) value between
* pressure levels ptop and pbtm when kmod=0
* itot -- Flag indicating of pinout(j) (or pvtr) was
* correctly produced (1 for yes)
*
*Comments:
*
*---------------------------------------------------------------------
#endif
C
C* Global variables
C
#include "pardim.cdk"
#include "comdim.cdk"
#include "comlun.cdk"
#include "comgem.cdk"
#include "comchem.cdk"
#include "commatrix.cdk"
C
INTEGER J,J1,ITOT,KFIRST
REAL*8 ZTOT,ZPTOP,ZPBTM,zwin
REAL*8 zh(knum,knflev),zhp(knum,knflev),zhw(knflev),zhpw(knflev)
REAL*8 zg(knflev)
C
C Total or partial column amounts.
C
C Loop over observation elements in a profile
C (with common lat-long)
C
if (kmod.eq.0) pinout(:)=0.0
C
C First determine integration weights and flags
C
zh(:,:)=0.0
zhp(:,:)=0.0
C
kfirst=1
DO J=1,knum
C
C Check for partial columns which extend above the top analysis level
C or are entirely below surface.
C
if (kflag(j).EQ.1.AND.kflag2(j).EQ.0) then
if (POBSLEV2(J).lt.PRESSA(1)*10.0.and.POBSLEV(J).lt.PRESSA(1)) then
kflag2(j)=1
else if (POBSLEV2(J).gt.PRESSA(KNFLEV).and.POBSLEV(J).gt.PRESSA(KNFLEV)) then
kflag(j)=0
kflag2(j)=2
end if
end if
C
if ((kflag(j).EQ.1.AND.kflag2(j).EQ.0).or.kkern.gt.0) then
C
C Set range of vertical levels
C
ZPTOP = POBSLEV(J)
ZPBTM = POBSLEV2(J)
if (ZPBTM.gt.PRESSA(KNFLEV)) ZPBTM=PRESSA(KNFLEV)
IF (ZPTOP.GE.ZPBTM) THEN
write(nulout,*) 'CH_VCOLM: Boundary problem: skip data'
write(nulout,*) 'ZPTOP.GE.ZPBTM ',ZPTOP,ZPBTM
kflag(j)=0
c call abort3d(nulout,'CH_VCOLM: Boundary problem')
END IF
C
C Calculate innovation operator terms
C
CALL CH_VERTINTG
(pvtr, zptop,zpbtm,
1 pressa,knflev,kfirst,pstate,
1 nulout,cdvar,itot,
1 zhw(1:knflev),zhpw(1:knflev))
if (itot.eq.0) kflag(j)=0
kfirst=2
if (kkern.gt.0) then
C
C Incorporate averaging kernels
C
do j1=1,knum
zh(j1,1:knflev)=zh(j1,1:knflev)+zhw(1:knflev)*ravgkern(j1,j,kkern)
zhp(j1,1:knflev)=zhp(j1,1:knflev)+zhpw(1:knflev)*ravgkern(j1,j,kkern)
end do
else
zh(j,1:knflev)=zhw(1:knflev)
zhp(j,1:knflev)=zhpw(1:knflev)
end if
end if
end do
C
C Apply observation, TLM or adjoint operator
C
DO J=1,knum
if (kflag(j).EQ.1.AND.kflag2(j).EQ.0) then
if (CDBGTYP.EQ.'BG'.and.ngenoper.eq.1) then
c write(nulout,*) j
c write(nulout,*) 'zhp ',zhp(j,1:40)
C
C* Determine generalized innovation operator.
C Applicable only to increments.
C
zwin=0.01
CALL CH_GENOPER
(plat,klat,nulout,pressa,1,pstate,
1 cdvar,zwin,zh(j,1:knflev),zhp(j,1:knflev),zg,knflev)
else
zg(1:knflev)=zh(j,1:knflev)
end if
C
if (kmod.eq.0) then
C
C* Forward model (innovation) calc.
C
c if (CDBGTYP.EQ.'BG'.and.ngenoper.eq.1) then
c write(nulout,*) 'pstate ',pstate(1:40)
c write(nulout,*) 'zhp ',zhp(j,1:40)
c write(nulout,*) 'zg ',zg(1:40)
c end if
pinout(j)=dot_product(pvtr,zg)
C
else
C
C* Adjoint of forward model calc.
C
prof(1:knflev)=prof(1:knflev)+pinout(j)*zg(1:knflev)
C
end if
end if
END DO
c if (CDBGTYP.EQ.'BG'.and.ngenoper.eq.1) call abort3d(nulout,'DONE')
C
RETURN
END