!-------------------------------------- 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 gd2mvoad_1obs (cdvarname, klev) 9 * #if defined (DOC) * ***s/r gd2mvoad_1obs - Adjoint of the horizontal interpolation of the model variables * . in grid-point space to observation locations. * . Simple multiplication by the weights of * . the horizontal bilinear interpolation. * . (adapted from BILINAD) * * *Author : L. Fillion *ARMA/EC 16 Jun 2010 (from gd2mvoad.ftn prior to MPI) * *Revision: * ** Purpose: Update the estimate of GD from the gradient components * at the observation points which have been stored in * GOMOBS * * Arguments * CDVARNAME: identificator of the variable to be treated * KLEV : number of levels (typically 1 for 2D-fields and NFLEV for 3D-fields) * * * #endif IMPLICIT NONE *implicits #include "pardim.cdk"
#include "comdim.cdk"
#include "comdimo.cdk"
#include "comleg.cdk"
#include "comgem.cdk"
#include "comgd0.cdk"
#include "comcst.cdk"
#include "comoahdr.cdk"
#include "comoabdy.cdk"
#include "comoba.cdk"
#include "commvo.cdk"
* * Arguments * character*2 cdvarname integer klev * * Local Variables * INTEGER JLEV, JGL, JLON, JOBS, IOBTYP INTEGER ILON, ILOS, ILA, IMIDDLE, ISYM, IMAX REAL*8 DLMEAN, DLMEAS, DLLAO, DLLOO, DLDLON, DLDLOS REAL*8 DLDXN, DLDXS, DLDY, DLW1, DLW2, DLW3, DLW4 * real*8 zfield(nibeg:niend,1:klev,njbeg:njend) S , zprofil(1:klev,nobtot) * * Transfer Grid point field into local array (for generecity) * zfield(:,:,:) = 0. zprofil(:,:) = 0. * * SELECT CASE (CDVARNAME) * * 2D fields * CASE('TG') ZPROFIL(1:KLEV,1:NOBTOT)= GOMTGR(1:KLEV,1:NOBTOT) CASE('PS') ZPROFIL(1:KLEV,1:NOBTOT)= GOMPS(1:KLEV,1:NOBTOT) * * 3D fields * CASE('TT') ZPROFIL(1:KLEV,1:NOBTOT) = GOMT (1:KLEV,1:NOBTOT) CASE('Q0') ZPROFIL(1:KLEV,1:NOBTOT) = GOMQ (1:KLEV,1:NOBTOT) CASE('O3') ZPROFIL(1:KLEV,1:NOBTOT) = GOMOZ(1:KLEV,1:NOBTOT) CASE('TR') ZPROFIL(1:KLEV,1:NOBTOT) = GOMTR(1:KLEV,1:NOBTOT) CASE('UU') ZPROFIL(1:KLEV,1:NOBTOT) = GOMU(1:KLEV,1:NOBTOT) CASE('VV') ZPROFIL(1:KLEV,1:NOBTOT) = GOMV(1:KLEV,1:NOBTOT) CASE('GZ') ZPROFIL(1:KLEV,1:NOBTOT) = GOMGZ(1:KLEV,1:NOBTOT) END SELECT C C* 2. LOOP OVER ALL THE OBSERVATIONS C --------------------------------- C 200 CONTINUE C Observations: DO JOBS = 1, NOBTOT DLLAO = ROBHDR(NCMLAT,JOBS) DLLOO = ROBHDR(NCMLON,JOBS) IOBTYP = MOBHDR(NCMOTP,JOBS) C C * 2.1. LOCATE FIRST LATITUDE ROW NUMBER (ILA) TO THE NORTH C * OF ZLAO, AND THE TWO LONGITUDE POINT NUMBERS IMMEDIATELY C TO THE WEST (ILON AND ILOS) C ILA=MOBHDR(NCMTLA,JOBS) C IF(DLLOO.LT.0.) DLLOO = DLLOO + 2.*RPI IF(DLLOO.GE.2.*RPI) DLLOO = DLLOO - 2.*RPI DLDLON = 2.*RPI/NILON(ILA) DLDLOS = 2.*RPI/NILON(ILA+1) ILON = INT(DLLOO/DLDLON) + 1 ILOS = INT(DLLOO/DLDLOS) + 1 C C * 2.2 COMPUTE THE 4 WEIGHTS OF THE BILINEAR INTERPOLATION C DLDXN = DLLOO/DLDLON + 1. - ILON DLDXS = DLLOO/DLDLOS + 1. - ILOS DLDY = (RLATI(ILA)-DLLAO)/(RLATI(ILA)-RLATI(ILA+1)) DLW1 = (1.-DLDXN)*(1.-DLDY) DLW2 = DLDXN*(1.-DLDY) DLW3 = (1.-DLDXS)*DLDY DLW4 = DLDXS*DLDY C do jlev = 1, klev ZFIELD(ILON,jlev,ILA) = ZFIELD(ILON,jlev,ILA) + + DLW1 * ZPROFIL(jlev,JOBS) ZFIELD(ILON+1,jlev,ILA) = ZFIELD(ILON+1,jlev,ILA) + + DLW2 * ZPROFIL(jlev,JOBS) ZFIELD(ILOS,jlev,ILA+1) = ZFIELD(ILOS,jlev,ILA+1) + + DLW3 * ZPROFIL(jlev,JOBS) ZFIELD(ILOS+1,jlev,ILA+1) = ZFIELD(ILOS+1,jlev,ILA+1) + + DLW4 * ZPROFIL(jlev,JOBS) C end do * end do OBSERVATIONS C C C 1. REARRANGE GRID-POINTS ARRAYS GD0, BY CARRYING GRADIENTS C . CONTRIBUTIONS OF MERIDIAN 0, NILON(JGL)+1 AND NILON(JGL+2) C . INTO MERIDIANS NILON(JGL), 1, AND 2. SIMILAR TREATMENT NEAR POLES C C C 1.2 EXTRA PARALLELS C C TREATMENT OF GRADIENTS FOR PARALLELS -1 AND NJ + 2 (WITH SYMETRIZATION) C LEVELS: DO JLEV = 1, KLEV IMIDDLE = NILON(1) / 2 DO JLON = 0, IMIDDLE ISYM = JLON + IMIDDLE ZFIELD(ISYM,jlev,1) = ZFIELD(JLON,jlev,-1) + + ZFIELD(ISYM,jlev,1) ZFIELD(ISYM,jlev,NJ) = ZFIELD(JLON,jlev,NJ+2) + + ZFIELD(ISYM,jlev,NJ) END DO * IMAX = NILON(1) DO JLON = IMIDDLE + 1, IMAX + 2 ISYM = JLON - IMIDDLE ZFIELD(ISYM,JLEV,1) = ZFIELD(JLON,JLEV,-1) + + ZFIELD(ISYM,JLEV,1) ZFIELD(ISYM,JLEV,NJ) = ZFIELD(JLON,JLEV,NJ+2) + + ZFIELD(ISYM,JLEV,NJ) END DO C C TREATMENT OF THE GRADIENTS AT NORTH AND SOUTH POLES. C DLMEAN = 0. DLMEAS = 0. IMAX = NILON(0) DO JLON = 0, IMAX + 2 DLMEAN = DLMEAN + ZFIELD(JLON,jlev,0) DLMEAS = DLMEAS + ZFIELD(JLON,jlev,NJ+1) end do * DLMEAN = DLMEAN/NILON(1) DLMEAS = DLMEAS/NILON(NJ) IMAX = NILON(1) DO JLON = 1, IMAX ZFIELD(JLON,jlev,1) = DLMEAN + ZFIELD(JLON,jlev,1) ZFIELD(JLON,jlev,NJ) = DLMEAS + ZFIELD(JLON,jlev,NJ) end do * END DO LEVELS C C C 1.1 EXTRA MERIDIANS C DO JGL = 1, NJ IMAX = NILON(JGL) DO JLEV = 1, KLEV ZFIELD(IMAX,JLEV,JGL) = ZFIELD(0,JLEV,JGL) + + ZFIELD(IMAX,JLEV,JGL) ZFIELD(1,JLEV,JGL) = ZFIELD(IMAX+1,JLEV,JGL) + + ZFIELD(1,JLEV,JGL) ZFIELD(2,JLEV,JGL) = ZFIELD(IMAX+2,JLEV,JGL) + + ZFIELD(2,JLEV,JGL) END DO END DO * * Adjoint of the identity (change of norm) * DO JGL = 1, NJ IMAX = NILON(JGL) DO JLEV = 1, KLEV DO JLON = 1, IMAX ZFIELD(JLON,JLEV,JGL) = ZFIELD(JLON,JLEV,JGL) * + NILON(JGL) / RWT(JGL) END DO END DO END DO C C Transfer local results to global array C select case (cdvarname) * * 2D fields * case('TG') gtg0(:,1:klev,:) = zfield(:,1:klev,:) case('PS') gps0(:,1:klev,:) = zfield(:,1:klev,:) * * 3D fields * case('TT') tt0(:,1:klev,:) = zfield(:,1:klev,:) case('Q0') q0 (:,1:klev,:) = zfield(:,1:klev,:) case('O3') GOZ0(:,1:klev,:) = zfield(:,1:klev,:) case('TR') GTR0(:,1:klev,:) = zfield(:,1:klev,:) case('UU') UT0(:,1:klev,:) = zfield(:,1:klev,:) case('VV') VT0(:,1:klev,:) = zfield(:,1:klev,:) case ('GZ') GZ0(:,1:klev,:) = zfield(:,1:klev,:) end select RETURN END