SUBROUTINE CH_VPROF(KFLAG1,KFLAG2,PINDEX,KNUM,KNLEV, 4 & PRESS,PRESSA,PIN,POUT,KMOD,KDIM,KKERN) C IMPLICIT NONE INTEGER KNUM,KNLEV,KFLAG1(KNUM),KFLAG2(KNUM),KMOD,KKERN,KDIM REAL*8 PRESS(KNUM),PIN(KDIM),POUT(KDIM) REAL PINDEX(KNUM) REAL*8 PRESSA(KNLEV) C #if defined (DOC) * * **s/r CH_LVPROF - Apply forward/TLM model or its adjoint for profile of point * values. * * Forward model: piecewise linear vertical interpolation. * * * AUTHOR: Y. Rochon *ARQX/MSC July 2005 * * REVISIONS: * * PURPOSE: - Apply forward/TLM model or its adjoint for profile of point values. * Forward model: piecewise linear vertical interpolation. * * ARGUMENTS * * INPUT: * * KFLAG1.......Flags (1 for valid obs data) * KFLAG2.......Flags (0 for data in vertical range) * PINDEX.......Array of indices of analysis upper levels closest * obs levels. * KNLEV........Number of analyis levels * KNUM.........Number of obs levels * PRESS........Obs levels * PRESSA.......Analysis levels (in increasing size) * PIN..........Input background/increment values at analysis levels * POUT.........Initial GOMOBS segment when KMOD=1 * kmod........ Flag indicating purpose of call: * 0: Use as forward or TLM model * 1: Use as adjoint of TLM model. * kkern.......Use of averaging kernel. * 0 for no, position index for yes * kdim........dimension >= max(knum,knlev) * * OUTPUT: * * POUT.........Output background/increment values at obs levels * when KMOD=0. * Updated GOMOBS segment when KMOD=1. * KFLAG2.......Flags modified to 1 or 2 if point above or below * analysis region. * * *COMMENT * * * 1) ZDAPPS contribution when obs is T or wind for both 'BG' and 'HR' * is not included in this version. * ************************************************************************ #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,IK1,J1 REAL*8 ZWB,ZWT REAL*8 zh(knum,knlev) integer IKINDEX(knum) C zh(:,:)=0.0 ikindex(:)=0 C C Determine interpolation weights C DO J=1,KNUM C C Check for levels which extend above the top analysis level C or are entirely below surface. C if (KFLAG1(J).EQ.1.AND.KFLAG2(J).EQ.0) then if (PRESS(J).lt.PRESSA(1)) then kflag2(j)=1 else if (PRESS(J).gt.PRESSA(KNLEV)) then kflag2(j)=2 end if end if C IF ((KFLAG1(J).EQ.1.AND.KFLAG2(J).EQ.0).or.KKERN.gt.0) THEN C C Apply vertical linear interpolation to obs location C IK1 = PINDEX(J) C C Make sure obs level is in between analysis C levels IK1 and IK1+1. C C This is to account for any inconsistency in C vertical coordinate transformation which C might occur in processing when input C obs vertical coordinate is not pressure. C if (PRESS(J).LT.PRESSA(ik1)) then IK1 = IK1 - 1 IF (IK1.LT.1) IK1=1 endif if (PRESS(J).GT.PRESSA(ik1+1)) then IK1 = IK1 + 1 IF (IK1.GT.KNLEV-1) IK1=KNLEV-1 endif IKINDEX(J)=IK1 ZWB = LOG(press(j)/pressa(ik1)) & /LOG(pressa(ik1+1)/pressa(ik1)) ZWT = 1.0D0 - ZWB c c zpresbpt = ((vhybinc(ik1) - rptopinc/rprefinc) c & /(1.0-rptopinc/rprefinc))**rcoefinc c zpresbpb = ((vhybinc(ik1+1) - rptopinc/rprefinc) c & /(1.0-rptopinc/rprefinc))**rcoefinc c ZDADPS = ( (ZPRESBPT/pressa(ik1))*LOG(ZLEV/pressa(ik1+1)) c + -(ZPRESBPB/pressa(ik1+1))*LOG(ZLEV/pressa(ik1)) ) c + /LOG(ZPB/ZPT)**2 C if (kkern.gt.0) then C C Incorporate averaging kernels C do j1=1,knum zh(j1,ik1+1)=zh(j1,ik1+1)+ZWB*ravgkern(j1,j,kkern) zh(j1,ik1)=zh(j1,ik1)+ZWT*ravgkern(j1,j,kkern) end do else zh(j,ik1+1)=ZWB zh(j,ik1)=ZWT end if END IF END DO C C Apply interpolation weights C IF (kkern.gt.0) then C C Case with averaging kernel C IF (KMOD.EQ.0) THEN C C Forward model calc. C POUT(:)=0.0 DO J=1,KNUM IF (KFLAG1(J).EQ.1.AND.KFLAG2(J).EQ.0) & POUT(J)=dot_product(PIN(1:knlev),ZH(J,:)) END DO C ELSE IF (KMOD.EQ.1) THEN C C Adjoint of forward/TLM model calc. C DO J=1,KNUM IF (KFLAG1(J).EQ.1.AND.KFLAG2(J).EQ.0) & POUT(1:KNLEV)=POUT(1:KNLEV)+zh(J,:)*PIN(J) END DO END IF ELSE IF (KMOD.EQ.0) THEN C C Forward model calc. C POUT(:)=0.0 DO J=1,KNUM IF (KFLAG1(J).EQ.1.AND.KFLAG2(J).EQ.0) THEN IK1=IKINDEX(J) POUT(J) = zh(J,IK1+1)*PIN(IK1+1) + zh(J,IK1)*PIN(IK1) END IF END DO C ELSE IF (KMOD.EQ.1) THEN C C Adjoint of forward/TLM model calc. C DO J=1,KNUM IF (KFLAG1(J).EQ.1.AND.KFLAG2(J).EQ.0) THEN IK1=IKINDEX(J) POUT(IK1)=POUT(IK1)+zh(J,IK1)*PIN(J) POUT(IK1+1)=POUT(IK1+1)+zh(J,IK1+1)*PIN(J) END IF END DO END IF END IF C RETURN END