!-------------------------------------- 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 GPSZTDOPTL(PLAT,PLON,PZOBS,PETA,PTT_D,PHU_D,PXP0_D, 1 + PXPT,PMT,PGZ,PHX_D,PTT,PHU,PXP0,PHX) #if defined (DOC) * ***s/r GPSZTDOPTL - tangent linear operator for GPS Zenith Delay ZTD * * *Author : S. Macpherson *ARMA November 2004 * ------------------- * *Arguments * PLAT Latitude of observation (deg) * PLON Longitude of observation (deg) * PZOBS GPS antenna height ASL (m) * PETA Trial eta level values * PTT_D Trial temperature profile (K) * PHU_D Trial specific humidity profile (kg/kg) * PXP0_D Trial surface pressure (Pa) * PXPT Trial model top pressure (Pa) * PMT Trial surface elevation ASL (m) * PGZ Trial geopotential profile (m**2/s**2) * PHX_D Value of H(x) = ZTD (m) * PTT TL of temperature profile (K) * PHU TL of humidity profile (kg/kg) * PXP0 TL of surface pressure * PHX TL of H(x) = ZTD (m) * * Revisions: * : S. Macpherson *ARMA/MSC 2004 * : S. Macpherson *ARMA/MRD Oct 2007 * - refractivity constants RCK1, RCK2, RCK3 now read from * NAMGPSGB section of namelist (comgpsgb.cdk) * #endif C IMPLICIT NONE C *implicits #include "comdim.cdk"
#include "comdimo.cdk"
#include "commvohr.cdk"
#include "comphy.cdk"
#include "pardim.cdk"
#include "comcst.cdk"
#include "comgpsgb.cdk"
* REAL*8 PLAT REAL*8 PLON REAL*8 PZOBS REAL*8 PETA (NFLEV) REAL*8 PTT_D (NFLEV), PTT (NFLEV) REAL*8 PHU_D (NFLEV), PHU (NFLEV) REAL*8 PGZ (NFLEV) REAL*8 PXP0_D, PXP0 REAL*8 PXPT REAL*8 PMT REAL*8 PHX_D, PHX C REAL*8 ZDETA (NFLEV-1) REAL*8 ZF3 (NFLEV-1), ZF3_D (NFLEV-1) REAL*8 ZG (NFLEV) REAL*8 ZZK (NFLEV) REAL*8 ZTTB REAL*8 ZQQB REAL*8 ZCLT, ZGRAV, ZLEVB REAL*8 ZGRAVM, ZCON, ZCON1, ZCON2 REAL*8 ZFPH, ZCONH, ZCONW, ZINTW, ZZHDV, ZZWDV, ZZTDV, ZDZ REAL*8 ZTVSFC, ZTVOBS, ZPMOBS, ZCON3, ZPBAR, ZTMOBS, ZQMOBS REAL*8 ZTBAR, ZQBAR, ZRMEAN, ZWDCOR, ZZTDVC C REAL*8 ZPTA, ZPTB, ZDZ2, ZDZ1, ZDZT REAL*8 ZPA, ZPB C * Refractivity constants k1, k2', k3 (units = m,Pa,K) REAL*8 PPK1, PPK2P, PPK3 C REAL*8 ZTTB_D, ZQQB_D, ZINTW_D, ZZHDV_D, ZZWDV_D, ZZTDV_D REAL*8 ZZTDVC_D, ZDPMDP, ZDP1, ZDP2, ZDPMDT, ZDPMDQ REAL*8 ZDDWDP, ZDDWDT, ZDDWDQ, ZDP3, ZDDW C INTEGER JLEV, IK, IML, JK, IJLEV C C * Mean column gravity at latitude 45 = PPGM0 (m/s**2) C * Temperature lapse rate (-dT/dz) = PPGAM (K/m) C REAL*8 PPGM0, PPGAM DATA PPGM0, PPGAM / 9.784, 0.0065 / C C * NAMELIST OPTIONS USED HERE (comgpsgb.cdk, read in PREPROC) C ----------------------------------------------------------------- C DZMIN Min Abs DZ to do DZ adjustment (m) C NJLEVP Nth level above the surface level (eta = 1) C (used for calculating model Psfc at Zobs) C ----------------------------------------------------------------- C C * Refractivity Constants (from namelist and in comgpsgb.cdk) C PPK1 = RCK1 PPK3 = RCK3 PPK2P = RCK2 - (EPS1*RCK1) C C * Height difference DZ between observation and model surface ZDZ = PZOBS - PMT C ZCLT = COS(2.0*(PI/180.)*PLAT) C C * Gravity at sea level as a function of latitude (GRAV = G0 = 9.80) ZGRAV = GRAV * (1.0 - 2.66E-03*ZCLT) C C * Mean column gravity as a function of latitude and model sfc height ZFPH = (1.0 - 2.66E-03*ZCLT - 2.8E-07*PMT) ZGRAVM = PPGM0 * ZFPH C C * Gravity and (TRIAL) height (ASL) profiles C DO JLEV = 1, NFLEV IF ( JLEV .EQ. NFLEV ) THEN ZZK(JLEV) = PMT ELSE ZZK(JLEV) = PGZ(JLEV)/ZGRAV ENDIF ZG(JLEV) = ZGRAV * (RA**2/(RA + ZZK(JLEV))**2) END DO C C * If PZOBS is below ZLEVB, use CMC extrapolation from surface C to get ZPMOBS = Psfc at PZOBS for DZ adjustment (later). C IJLEV = NJLEVP IF ( NJLEVP .GE. NFLEV ) IJLEV = NFLEV-1 ZLEVB = ZZK(NFLEV-IJLEV) C C C ---------------------------------------------------------------- C * Constants C ---------------------------------------------------------------- ZCON = 1.0E-06 * RGASD ZCON1 = ZCON * PPK1 ZCON2 = ZCON / EPS1 C ZCON3 = ZGRAV / (RGASD*PPGAM) ZCON3 = GRAV / (RGASD*PPGAM) C Constant used to compute the ZHD from Ps (Saastamoinen) ZCONH = ZCON1/PPGM0 C Value given by Vedel and others (for comparison) C ZCONH = 2.2768E-05 C Constant for ZWD computation (Vedel) ZCONW = ZCON2/ZGRAV C ---------------------------------------------------------------- C C * Set up terms required for vertical integration of HU, TT terms C * using trapezoidal rule C DO JLEV = 1, NFLEV-1 ZDETA(JLEV) = PETA(JLEV+1) - PETA(JLEV) ZTTB_D = (PTT_D(JLEV+1) + PTT_D(JLEV)) * 0.5 ZQQB_D = (PHU_D(JLEV+1) + PHU_D(JLEV)) * 0.5 ZTTB = (PTT (JLEV+1) + PTT (JLEV)) * 0.5 ZQQB = (PHU (JLEV+1) + PHU (JLEV)) * 0.5 C ZF3(JLEV) = ((PPK2P+(PPK3/ZTTB_D))*(1.0+2.0*DELTA*ZQQB_D))*ZQQB - + (PPK3*(ZQQB_D+DELTA*ZQQB_D**2)/ZTTB_D**2) *ZTTB C ZF3_D(JLEV) = (ZQQB_D + DELTA*ZQQB_D**2) * (PPK2P+(PPK3/ZTTB_D)) C END DO C C * Vertical integration (trapezoidal rule) C ZINTW = 0.0 ZINTW_D = 0.0 DO JLEV = 1, NFLEV-1 ZINTW = ZINTW + ZF3 (JLEV) * ZDETA(JLEV) ZINTW_D = ZINTW_D + ZF3_D(JLEV) * ZDETA(JLEV) END DO C C ----- ZHD (dry) Part ------ C ZZHDV_D = (ZCONH / ZFPH) * PXP0_D ZZHDV = (ZCONH / ZFPH) * PXP0 C C ----- ZWD (wet) Part ------ C ZZWDV_D = ZCONW * (PXP0_D - PXPT) * ZINTW_D ZZWDV = (ZCONW*ZINTW_D)*PXP0 + ZCONW*(PXP0_D-PXPT)*ZINTW C C * Compute ZTD = ZHD + ZWD C ZZTDV = ZZHDV + ZZWDV ZZTDVC = ZZTDV ZZTDV_D = ZZHDV_D + ZZWDV_D ZZTDVC_D = ZZTDV_D C C -------------------------------------------------------------------- C * Correction for DZ C -------------------------------------------------------------------- C IF ( ABS(ZDZ) .GT. DZMIN ) THEN C C * ------------ STEP 1: GET PRESSURE AT HEIGHT PZOBS --------------- C IF ( PZOBS .LE. ZLEVB ) THEN C C * CMC EXTRAPOLATION FROM SURFACE TO PZOBS: C ZTVSFC = PTT_D(NFLEV) * (1.0 + DELTA*PHU_D(NFLEV)) ZTVOBS = ZTVSFC - PPGAM * ZDZ ZPMOBS = PXP0_D * (ZTVOBS/ZTVSFC)**ZCON3 C C * TERMS FOR TL C ZDP1 = 1.0 - ((PPGAM*ZDZ)/ZTVSFC) ZDP2 = PXP0_D * ZCON3 * ZDP1**(ZCON3-1.0) ZDPMDP = ZDP1**ZCON3 ZDPMDT = ZDP2 * ((PPGAM*ZDZ*(1.0+DELTA*PHU_D(NFLEV))) / + ZTVSFC**2) ZDPMDQ = ZDP2 * (DELTA*PTT_D(NFLEV)*PPGAM*ZDZ) / ZTVSFC**2 C C ELSE C C * INTERPOLATION BETWEEN 2 ETA LEVELS: C C * Find eta level above observation height (adpated from routine C * VOBSLYRS, where result IK is stored in ROBDATA(NCMLYR,JDATA)). C * If obs height matches height of a model eta level, then C * set IML=1 (levels match) C IK = 1 IML = 0 C DO JK = 2,NFLEV-1 IF( ABS(ZZK(JK)-PZOBS) .LT. 1.0E-06 ) THEN IK = JK IML = 1 ELSE IF( PZOBS .LT. ZZK(JK) ) IK = JK ENDIF END DO C C * Linear in z interpolation of LOG P C * C IF ( IML .EQ. 1 ) THEN ZPMOBS = PXP0_D * PETA(IK) + PXPT * (1.0 - PETA(IK)) ELSE ZPTA = ZZK(IK) ZPTB = ZZK(IK+1) ZDZ2 = ZPTA - PZOBS ZDZ1 = PZOBS - ZPTB ZDZT = ZPTA - ZPTB ZPA = PXP0_D * PETA(IK) + PXPT * (1.0 - PETA(IK)) ZPB = PXP0_D * PETA(IK+1) + PXPT * (1.0 - PETA(IK+1)) ZPMOBS = EXP ( (ZDZ2/ZDZT)*LOG(ZPB) + (ZDZ1/ZDZT)*LOG(ZPA) ) ENDIF C C * TERMS FOR TL C IF (IML .EQ. 1) THEN ZDPMDP = PETA(IK) ZDPMDT = 0.0 ZDPMDQ = 0.0 ELSE ZDP1 = ( (ZDZ2/ZDZT) * PETA(IK+1) ) / ZPB ZDP2 = ( (ZDZ1/ZDZT) * PETA(IK) ) / ZPA ZDPMDP = ZPMOBS * ( ZDP1 + ZDP2 ) ZDPMDT = 0.0 ZDPMDQ = 0.0 ENDIF C ENDIF C * --------------- END STEP 1 ------------------------------------- C C * --------- STEP 2: ADJUST ZTD FOR DZ ---------------------------- C C - Calculate new ZHD with new Psfc = ZPMOBS ZFPH = (1.0 - 2.66E-03*ZCLT - 2.8E-07*PZOBS) ZZHDV_D = (ZCONH / ZFPH) * ZPMOBS C - Adjust wet delay using Higgins method (Q constant over DZ layer) ZTMOBS = PTT_D(NFLEV) - (PPGAM * ZDZ) ZQMOBS = PHU_D(NFLEV) ZPBAR = (ZPMOBS + PXP0_D) * 0.5 ZTBAR = (ZTMOBS + PTT_D(NFLEV)) * 0.5 ZQBAR = (ZQMOBS + PHU_D(NFLEV)) * 0.5 C Mean (wet) refractivity of DZ layer ZRMEAN = 1.0E-06 * (PPK2P*((ZPBAR*ZQBAR)/(EPS1*ZTBAR)) + + PPK3*((ZPBAR*ZQBAR)/(EPS1*ZTBAR**2))) ZWDCOR = ZRMEAN * ZDZ ZZWDV_D = ZZWDV_D - ZWDCOR C C ------------- TL CODE FOR ZTD ADJUSTMENT ------------------------ C ZZHDV = (ZCONH / ZFPH) * + (ZDPMDP*PXP0 + ZDPMDT*PTT(NFLEV) + ZDPMDQ*PHU(NFLEV)) C C ZDPMDP = 0.5 * (ZDPMDP + 1.0) ZDPMDT = 0.5 * ZDPMDT ZDPMDQ = 0.5 * ZDPMDQ ZDP1 = 1.0E-06 * ZDZ ZDDWDP = ZDP1 * ( ( (PPK2P*ZQBAR)/(EPS1*ZTBAR) + + (PPK3 *ZQBAR)/(EPS1*ZTBAR**2) ) * ZDPMDP ) C ZDP2 = -(ZQBAR*ZPBAR) / (EPS1*ZTBAR**2) + + (ZQBAR*ZDPMDT) / (EPS1*ZTBAR) ZDP3 = -(2.0*ZQBAR*ZPBAR) / (EPS1*ZTBAR**3) + + (ZQBAR*ZDPMDT) / (EPS1*ZTBAR**2) ZDDWDT = ZDP1 * (PPK2P*ZDP2 + PPK3*ZDP3) C ZDP2 = ZPBAR / (EPS1*ZTBAR) + (ZQBAR*ZDPMDQ) / (EPS1*ZTBAR) ZDP3 = ZPBAR / (EPS1*ZTBAR**2) + + (ZQBAR*ZDPMDQ) / (EPS1*ZTBAR**2) ZDDWDQ = ZDP1 * (PPK2P*ZDP2 + PPK3*ZDP3) C ZDDW = ZDDWDP*PXP0 + ZDDWDT*PTT(NFLEV) + ZDDWDQ*PHU(NFLEV) ZZWDV = ZZWDV - ZDDW C C C -------------------------------------------------------------------- C C - Corrected ZTD = new ZHD + adjusted ZWD ZZTDVC_D = ZZHDV_D + ZZWDV_D ZZTDVC = ZZHDV + ZZWDV C C * --------------- END STEP 2 ------------------------------------- C ENDIF C --------------------------------------------------------------------- C * End DZ correction C --------------------------------------------------------------------- C C Return H(x) and TL H(x) C PHX_D = ZZTDVC_D PHX = ZZTDVC C RETURN END