!-------------------------------------- LICENCE BEGIN ------------------------------------
!Environment Canada - Atmospheric Science and Technology License/Disclaimer,
! version 3; Last Modified: May 7, 2008.
!This is free but copyrighted software; you can use/redistribute/modify it under the terms
!of the Environment Canada - Atmospheric Science and Technology License/Disclaimer
!version 3 or (at your option) any later version that should be found at:
!http://collaboration.cmc.ec.gc.ca/science/rpn.comm/license.html
!
!This software 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 above mentioned License/Disclaimer for more details.
!You should have received a copy of the License/Disclaimer along with this software;
!if not, you can write to: EC-RPN COMM Group, 2121 TransCanada, suite 500, Dorval (Quebec),
!CANADA, H9P 1J3; or send e-mail to service.rpn@ec.gc.ca
!-------------------------------------- LICENCE END --------------------------------------
!
SUBROUTINE LAYERAVG(KFLAG,PX1,PX2,PY2,PY2INCR,KN1,KN2,KI, 1,2
& PPS,PMEAN,PZ,PZS,PZPS)
C
IMPLICIT NONE
C
C* Declaration of arguments
C
INTEGER KN1,KN2,KI,KFLAG
REAL*8 PX1(KN1),PX2(KN2),PY2(KN2),PY2INCR(KN2)
REAL*8 PPS,PMEAN,PZ(KN2),PZPS,PZS(KN2)
C
*---------------------------------------------------------
#if defined (DOC)
*
***s/r LAYERAVG - Perform integration between points PX1(KI-1) and
* PX1(KI+1) with piecewise linear weighting having
* weights of zero at ki-1 and ki+1 and max weight at ki.
*
* Output: Weighted mean value, its contribution to
* the TLM*increment or to the adjoint.
*
*Author : Y.J. Rochon *ARQX/EC Nov. 2005
*
**Revisions:
*
* -------------------
*
*Purpose: Perform integration between points PX1(KI-1) and
* PX1(KI+1) with piecewise linear weighting having
* weights of zero at ki-1 and ki+1 and max weight at ki.
*
* Output: Weighted mean value, its contribution to
* the TLM*increment or to the adjoint.
*
*Arguments:
*
* INPUT
*
* KFLAG: Indicates purpose of calc
* 0 - Application as forward interpolator
* 1 - Application for TLM* increments
* 2 - Setting of adjoint elements
*
* PX1: Reference levels (e.g. lnP; in increasing values)
* PX2: Available levels (e.g. lnP; in increasing values)
* PY2: Values at levels (e.g. temperature)
* PY2INCR: Not relevant when kflag=0 or 2
* Increments when kflag=1
* PZ: Extra array related to gradients w.r.t. Ps for KFLAG.gt.0
* PMEAN: Mean weigthed value for PX1(KI-1) to PX1(KI+1) when KFLAG=2.
* Output otherwise.
* KN1: Dimension of PX1.
* KN2: Dimension of other arrays.
* PZS: dlnP/dPs
* KI: Identifies region of interest: PX1(KI-1) to PX1(KI+1)
* PPS: Surface pressure increment when KFLAG=1, not needed otherwise.
*
* OUTPUT:
*
* PMEAN: Mean weigthed value for PX1(KI-1) to PX1(KI+1) using
* background values when kflag=0 and increments when kflag=1.
* PZ: Resultant accumulated contribution factors
* Adjoint when KFLAG=2
* TLM when KFLAG=1 or 0.
* PZPS: Surface pressure related adjoint term when KFLAG=2
* Surface pressure related TLM*increment term when KFLAG=1
*
*-----------------------------------------------------------
#endif
C
C* Declaration of local variables
C
REAL*8 Z1,Z2,Z3,ZW1,ZW2
REAL*8 zsum
INTEGER J,IC,ISKIP
C
C --- Identify boundary points
C
z2=px1(ki)
C
if (ki.eq.1) then
z1=2.0*z2-px1(ki+1)
else
z1=px1(ki-1)
endif
C
if (ki.eq.kn1) then
z3=2.0*z2-z1
else
z3=px1(ki+1)
endif
if (z3.gt.px2(kn2)) z3=px2(kn2)
C
iskip=0
if (z2.ge.px2(kn2)) then
z3=px2(kn2)
z2=px2(kn2)
iskip=1
endif
C
C --- Determine forward interpolator (kflag=0) or TLM (kflag>0)
C
pzps=0.0
pz(1:kn2)=0.0
ic=0
do j=1,kn2-1
if (px2(j).ge.z3) go to 1000
C
if (px2(j).le.z2.and.px2(j+1).gt.z1) then
C
call sublayer
(z1,z2,z3,px2(j),px2(j+1),kflag,
& py2(j),py2(j+1),zw1,zw2,
& pzs(j),pzs(j+1),pzps)
pz(j)=pz(j)+zw1
pz(j+1)=pz(j+1)+zw2
ic=1
endif
C
if (px2(j).lt.z3.and.px2(j+1).ge.z2.and.iskip.eq.0) then
C
call sublayer
(z3,z2,z1,px2(j),px2(j+1),kflag,
& py2(j),py2(j+1),zw1,zw2,
& pzs(j),pzs(j+1),pzps)
pz(j)=pz(j)+zw1
pz(j+1)=pz(j+1)+zw2
ic=1
endif
enddo
1000 continue
if (ic.eq.0) pz(j)=1.0
C
C --- Apply forward interpolator (kflag=0), determine TLM*increment (kflag=1)
C or use TLM for adjoint calc (kflag=2)
C
zsum=0.0
if (kflag.eq.0) then
pmean=0.0
do j=1,kn2
pmean=pmean+pz(j)*py2(j)
zsum=zsum+pz(j)
end do
pmean=pmean/zsum
else if (kflag.eq.1) then
pmean=0.0
do j=1,kn2
pmean=pmean+pz(j)*py2incr(j)
zsum=zsum+pz(j)
end do
pmean=pmean/zsum
if (ic.ne.0) pzps=pzps*pps/zsum
else if (kflag.eq.2) then
do j=1,kn2
zsum=zsum+pz(j)
end do
pz(1:kn2)=pz(1:kn2)*pmean/zsum
if (ic.ne.0) pzps=pzps*pmean/zsum
endif
C
RETURN
END