!-------------------------------------- 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 SUBLAYER (z1,z2,z3,x1,x2,imode, 4 & t1,t2,w1,w2,pzs1,pzs2,pzps) C IMPLICIT NONE REAL*8 z1,z2,z3,x1,x2,t1,t2,w1,w2,pzs1,pzs2,pzps INTEGER imode #include "comlun.cdk"
C #if defined (DOC) *----------------------------------------------------------------- * * Written by Yves J. Rochon *ARQX/EC, Nov. 2005 * * Revisions: * Saroja Polavarapu *ARMA/EC, Nov 2005 * - Setting of y1 and y2 moved from calling routine. * * Revisions: * * Purpose: Determine weight coefficients to assign to NWP variables * at x1 and x2. Weights are determined from integration over * the range (y1,y2), which is within the ranges of the * NWP layer (x1,x2) and of the RTM layer (z1,z2). Intergrals * are approximated via the trapezoidal rule: * * integral of f(x) from y1 to y2 = (f(y1)+f(y2))/2*abs(y1-y2) * * This is synonomous to having an integrand linear in x. * * Normalization done in calling routine. * * Input: * * z1.........Outer boundary of RTM level (could be above are below z2) * z2.........Inner boundary of RTM level * (position of RTM reference level) * z3.........Second outer boundary * x1.........Upper boundary of NWP layer (x1<x2) * x2.........Lower boundary of NWP layer * imode......0: Forward interpolator and linear model contribution * to TLM only * >0: Also provide NLM contribution to TLM (gradients * w.r.t. Ps) * t1.........Variable value at upper NWP level. * t2.........Variable value at lower NWP level. * dzs1.......dlnP/dPs = dx1/dPs * dzs2.......dlnP/dPs = dx2/dPs * pzps.......Current gradient contribution for weights*variable w.r.t Ps * * Output: * * w1.........Weight assigned to variable at upper NWP level * w2.........Weight assigned to variable at lower NWP level * pzps.......Updated gradient contribution for weights*variable w.r.t Ps * * Other: * * tot........Evaluated integral * g1.........Gradient of weights*variables w.r.t. x1 * g2.........Gradient of weights*variables w.r.t. x2 * *----------------------------------------------------------------- #endif C REAL*8 y1,y2,tot,d,w10,w20,dz,dx,dy,dzd,dxd,g1,g2 REAL*8 a1,a2,aa1,aa2 integer ibot,itop C C --- Identify and set upper and lower boundaries of C integration/averaging layers. C C y1.........Upper boundary of integral range (y1<y2) C y2.........Lower boundary of integral range C itop=0 ibot=0 if (z1.lt.z3) then y1=z1 if (x1.gt.z1) then y1=x1 itop=1 endif y2=z2 if (x2.lt.z2) then y2=x2 ibot=1 endif else y1=z2 if (x1.gt.z2) then y1=x1 itop=1 endif y2=z1 if (x2.lt.z1) then y2=x2 ibot=1 endif endif C C --- Set weights for forward interpolator and linear model contribution to TLM C dy=y2-y1 dz=z1-z2 C dzd=1.0/dz if (abs(dz).lt.1E-10) then write(nulout,*) 'SUBLAYER: ERROR: dz is zero. dz = ',dz write(nulout,*) 'z1,z2,z3 = ',z1,z2,z3 write(nulout,*) 'x1,x2 = ',x1,x2 write(nulout,*) 't1,t2 = ',t1,t2 cbue stop w1=0.0 w2=0.0 return else dzd=1.0/dz endif w1=(z1-y1)*dzd*dy w2=(z1-y2)*dzd*dy w10=w1 w20=w2 dx=(x2-x1) C dxd=1.0/dx if (abs(dx).lt.1E-10) then write(nulout,*) 'SUBLAYER: ERROR: dx is zero. dx = ',dx write(nulout,*) 'z1,z2,z3 = ',z1,z2,z3 write(nulout,*) 'x1,x2 = ',x1,x2 write(nulout,*) 't1,t2 = ',t1,t2 cbue stop w1=0.0 w2=0.0 return else dxd=1.0/dx endif C if (z1.lt.z3.and.ibot.eq.0) then d=(x2-z2)*dxd w1=w1+w2*d w2=w2*(1.0-d) else if (z1.gt.z3.and.itop.eq.0) then d=(x2-z2)*dxd w2=w2+w1*(1.0-d) w1=w1*d end if tot=t1*w1+t2*w2 C C --- Provide NLM contribution to TLM (gradients w.r.t. Ps) C IF (imode.gt.0) THEN C C Determine gradient of 'tot' w.r.t. x1 C aa1=0.0 aa2=0.0 a1=0.0 a2=0.0 if (itop.eq.1) then a1=-(dy+(z1-y1))*dzd a2=-(z1-y2)*dzd else if (z1.gt.z3) then a1=(x2-z2)*dxd*dxd*w10 a2=-a1 end if if (z1.lt.z3.and.ibot.eq.0) then aa2=(x2-z2)*dxd*dxd*w20 aa1=-aa2 if (itop.eq.1) then a1=a1+a2*d+aa1 a2=a2*(1.0-d)+aa2 end if end if g1=a1*t1+a2*t2 C C Determine gradient of 'tot' w.r.t. x2 C aa1=0.0 aa2=0.0 a1=0.0 a2=0.0 if (ibot.eq.1) then a1=dzd*(z1-y1) a2=((z1-y2)-dy)*dzd else if (z1.lt.z3) then a1=((x2-z2)*dxd+1.0)*dxd*w20 a2=-a1 end if if (z1.gt.z3.and.itop.eq.0) then aa1=(1.0-(x2-z2)*dxd)*dxd*w10 aa2=-aa1 if (ibot.eq.1) then a2=a2+a1*(1.0-d)+aa2 a1=a1*d+aa1 end if end if g2=a1*t1+a2*t2 C C Accumulate for gradient w.r.t. Ps C pzps=pzps+g1*pzs1+g2*pzs2 C ENDIF C RETURN END