!######################################################################## !######################################################################## !######### ######### !######### WRF:MODEL_LAYER:PHYSICS:MODULE module_cu_bmj ######### !######### ######### !######### Adapted by ######### !######### Center for Analysis and Prediction of Storms ######### !######### University of Oklahoma ######### !######### ######### !######################################################################## !######################################################################## MODULE module_cu_bmj 2 !------------------------------------------------------------------------ ! ! PURPOSE: ! ! Contains the routines and parameters for the Betts-Miller-Janjic ! deep and shallow convective adjustment scheme. ! ! REFERENCES: ! ! Janjic, Z. I., 1994: The step-mountain Eta coordinate model: Further ! developments of the convection, viscous sublayer, and turbulence ! closure schemes. _Mon. Wea. Rev._, 122, 927-945. ! Betts, A. K., and M. J. Miller, 1993: The Betts-Miller Scheme. _The ! Representation of Cumulus Convection in Numerical Models_. _Meteor. ! Mono._, 24, 107-121. ! Janjic, Z. I., 1990: The step-mountain coordinate: Physical package. ! _Mon. Wea. Rev._, 118, 1429-1443. ! Betts, A. K., 1986: A new convective adjustment scheme. Part I: ! Observational and theroetical basis. _Quart. J. Roy. Meteor. Soc._, ! 112, 677-691. ! Betts, A. K., and M. J. Miller, 1986: A new convective adjustment ! scheme. Part II: Single column tests using GATE wave, BOMEX, ATEX ! and arctic air-mass data sets. _Quart. J. Roy. Meteor. Soc._, 112, ! 693-709. ! Betts, A. K., 1985: Mixing line analysis of clouds and cloudy ! boundary layers. _J. Atmos. Sci._, 42, 2751-2763. ! Betts, A. K., 1984: Boundary layer thermodynamics of a High Plains ! severe storm. _Mon. Wea. Rev._, 112, 2199-2211. ! Betts, A. K., 1983a: Thermodynamics of mixed stratocumulus layers: ! Saturation point budgets. _J. Atmos. Sci._, 40, 2655-2670. ! Betts, A. K., 1983b: Atmospheric convective structure and a convection ! scheme based on saturation point adjustment. Workshop on convection ! in large-scale models, 20 Nov. to 1 Dec., ECMWF. ! Betts, A. K., 1982a: Saturation point analysis of moist convective ! overturning. _J. Atmos. Sci._, 39, 1484-1505. ! Betts, A. K., 1982b: Cloud thermodynamic models in saturation point ! coordinates. _J. Atmos. Sci._, 39, 2182-2191. ! !------------------------------------------------------------------------ ! ! AUTHOR: ??? ! ! MODIFICATIONS: ! ! Eric Kemp, 21 September 2001 ! Reformatted code. ! !------------------------------------------------------------------------ ! ! Declare module parameters and variables. ! !------------------------------------------------------------------------ LOGICAL :: UNIS=.TRUE.,UNIL=.FALSE. REAL,PARAMETER :: A2=17.2693882,A3=273.16,A4=35.86 & ,DSPC=-3000. & ,DTTOP=0.,EFIFC=5.0,EFIMN=.20,EFMNT=.70 & ,ELIVW=2.72E6 & ,EPSDN=1.05,EPSDT=0.,EPSNTP=1.E2 & ,EPSP=1.E-7,EPSQ=2.E-12,EPSUP=1.0 & ,FCC=.50,FSL=.850,FSS=.85 & ,PBM=13000.,PFRZ=15000.,PNO=1000. & ,PONE=2500.,PQM=20000.,PQ0=379.90516 & ,PSH=20000.,PSHU=45000.,RHF=0.10,ROW=1.E3 & ,STABD=.90,STABFC=1.0 & ,STABS=1.0,STRESH=1.10 & ,T1=274.16,TREL=2400. REAL,PARAMETER :: DSPBFL=-4843.75,DSP0FL=-7050.0,DSPTFL=-2250.0 & ,DSPBFS=-3875.,DSP0FS=-5875.,DSPTFS=-1875. REAL,PARAMETER :: PL=2500.,PLQ=70000.,PH=105000. & ,THL=210.,THH=365.,THHQ=325. INTEGER,PARAMETER :: ITB=76,JTB=134,ITBQ=152,JTBQ=440 !------------------------------------------------------------------------ ! ! Arrays for lookup tables. ! !------------------------------------------------------------------------ REAL,DIMENSION(ITB),PRIVATE,SAVE :: STHE,THE0 REAL,DIMENSION(JTB),PRIVATE,SAVE :: QS0,SQS REAL,DIMENSION(ITBQ),PRIVATE,SAVE :: STHEQ,THE0Q REAL,DIMENSION(ITB,JTB),PRIVATE,SAVE :: PTBL REAL,DIMENSION(JTB,ITB),PRIVATE,SAVE :: TTBL REAL,DIMENSION(JTBQ,ITBQ),PRIVATE,SAVE :: TTBLQ REAL,PARAMETER :: RDP=(ITB-1.)/(PH-PL),RDPQ=(ITBQ-1.)/(PH-PLQ) & ,RDQ=ITB-1,RDTH=(JTB-1.)/(THH-THL) & ,RDTHE=JTB-1.,RDTHEQ=JTBQ-1. CONTAINS ! Subroutine declarations !######################################################################## !######################################################################## !######### ######### !######### SUBROUTINE bmjdrv ######### !######### ######### !######### Adapted by ######### !######### Center for Analysis and Prediction of Storms ######### !######### University of Oklahoma ######### !######### ######### !######################################################################## !######################################################################## SUBROUTINE BMJDRV(DT,ITIMESTEP,STEPCU & 1,1 ,RR,RTHCUTEN,RQVCUTEN & ,RAINCV & ,TH,T,QV,PINT,PMID,PI,RHO,DZ8W & ,CP,R,RVOVRD,ELWV,G,TFRZ,D608 & ,CLDEFI,LOWLYR,XLAND & ,IDS,IDE,JDS,JDE,KDS,KDE & ,IMS,IME,JMS,JME,KMS,KME & ,ITS,ITE,JTS,JTE,KTS,KTE) !------------------------------------------------------------------------ ! ! PURPOSE: ! ! Driver subroutine for Betts-Miller-Janjic deep and shallow convective ! adjustment scheme. ! !------------------------------------------------------------------------ ! ! AUTHOR: ??? ! ! MODIFICATIONS: ! ! Eric Kemp, 21 September 2001 ! Reformatted code. ! !------------------------------------------------------------------------ ! ! Force explicit declarations. ! !------------------------------------------------------------------------ IMPLICIT NONE !------------------------------------------------------------------------ ! ! Declare arguments ! !------------------------------------------------------------------------ ! INTEGER,INTENT(IN) :: IDS,IDE,JDS,JDE,KDS,KDE & ! ,IMS,IME,JMS,JME,KMS,KME & ! ,ITS,ITE,JTS,JTE,KTS,KTE INTEGER,INTENT(IN) :: IDS, & ! start index for i in domain IDE, & ! end index for i in domain JDS, & ! start index for j in domain JDE, & ! end index for j in domain KDS, & ! start index for k in domain KDE, & ! end index for k in domain IMS, & ! start index for i in memory IME, & ! end index for i in memory JMS, & ! start index for j in memory JME, & ! end index for j in memory KMS, & ! start index for k in memory KME, & ! end index for k in memory ITS, & ! start index for i in tile ITE, & ! end index for i in tile JTS, & ! start index for j in tile JTE, & ! end index for j in tile KTS, & ! start index for k in tile KTE ! end index for k in tile INTEGER,INTENT(IN) :: ITIMESTEP, & ! Number of time step (integer) STEPCU ! Number of fundamental timesteps ! between convection calls. INTEGER,DIMENSION(IMS:IME,JMS:JME),INTENT(IN) :: & LOWLYR ! Index of lowest model layer above the ground ! REAL,INTENT(IN) :: CP,DT,ELWV,G,R,RVOVRD,TFRZ,D608 REAL,INTENT(IN) :: CP, & ! specific heat at constant pressure ! (1004 J/k/kg) DT, & ! Time step (sec) ELWV, & ! Latent heat of vaporization at 0 deg C ! (2.5e6 J kg**-1) G, & ! Acceleration due to gravity ! (9.81 m s**-2) R, & ! Dry gas constant (287 J K**-1 kg**-1) RVOVRD, & ! Ratio of gas constant for water vapor ! over dry gas constant ! (461.6/287 J K**-1 kg**-1 TFRZ, & ! Freezing point (273.15 K) D608 ! rvovrd - 1. REAL,DIMENSION(IMS:IME,JMS:JME),INTENT(IN) :: & XLAND ! Land-sea mask (1.0 for land; 2.0 for ! water) REAL,DIMENSION(IMS:IME,KMS:KME,JMS:JME),INTENT(IN) :: & TH, & ! Potential temperature (K) T, & ! Temperature (K) QV, & ! Water vapor mixing ratio (kg/kg) RR, & ! Dry air density (kg/m^3) PINT, & ! Pressure at full levels (Pa) PMID, & ! Pressure (Pa) PI, & ! Exner function (dimensionless) RHO, & ! Density (kg/m^3) DZ8W ! dz between full levels (m) REAL,DIMENSION(IMS:IME,KMS:KME,JMS:JME),INTENT(INOUT) :: & RQVCUTEN,& ! Rho_dTheta_m tendency due to ! cumulus scheme precipitation ! (kg/m^3 . K) RTHCUTEN ! Rho_dQv tendency due to ! cumulus scheme precipitation ! (kg/m^3 . kg/kg) REAL,DIMENSION(IMS:IME,JMS:JME),INTENT(INOUT) :: & RAINCV, & ! Cumulus scheme precipitation (mm) CLDEFI ! Precipitation efficiency (for BMJ ! scheme) (dimensionless) !------------------------------------------------------------------------ ! ! Local variables. ! !------------------------------------------------------------------------ REAL :: CUBOT,CUTOP,DTCNVC,LANDMASK,PCPCOL,PSFC,PTOP REAL,DIMENSION(KTS:KTE) :: DPCOL,DQDT,DTDT,PCOL,QCOL,TCOL INTEGER :: I,J,K,KFLIP,ICLDCK,LBOT,LMH,LTOP !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !------------------------------------------------------------------------ ! ! Check to see if this is a convection timestep. ! !------------------------------------------------------------------------ ICLDCK=MOD(ITIMESTEP,STEPCU) !------------------------------------------------------------------------ ! ! Compute convection every stepcu*dt/60.0 minutes. ! !------------------------------------------------------------------------ IF (ICLDCK.EQ.0) THEN DTCNVC=DT*STEPCU DO J=JTS,JTE DO I=ITS,ITE DO K=KTS,KTE DQDT(K)=0. DTDT(K)=0. END DO ! DO k = kts,kte RAINCV(I,J)=0. PCPCOL=0. PSFC=PINT(I,LOWLYR(I,J),J) ! Surface pressure (Pa) PTOP=PINT(I,KTE+1,J) ! Top level pressure (Pa) KTE+1=KME !------------------------------------------------------------------------ ! ! Convert to BMJ land mask. (1.0 for sea, 0.0 for land) ! !------------------------------------------------------------------------ LANDMASK=XLAND(I,J)-1. !------------------------------------------------------------------------ ! ! Fill 1-D vertical arrays and flip direction since BMJ scheme ! counts downward from the domain's top. ! !------------------------------------------------------------------------ DO K=KTS,KTE KFLIP=KTE+1-K TCOL(K)=T(I,KFLIP,J) ! Local temperature (K) ! change 10/18/00 ! from mixing ratio to specific humidity (prevent -ve 4/23/01) QCOL(K)=MAX(0.,QV(I,KFLIP,J)/(1.+QV(I,KFLIP,J))) ! Spec. Humidity PCOL(K)=PMID(I,KFLIP,J) ! Pressure DPCOL(K)=PINT(I,KFLIP,J)-PINT(I,KFLIP+1,J) DPCOL(K)=RHO(I,KFLIP,J)*G*DZ8W(I,KFLIP,J) ! Pressure thickness ! of layer. END DO ! DO k=kts,kte !------------------------------------------------------------------------ ! ! Lowest layer above ground must also be flipped. ! !------------------------------------------------------------------------ LMH=KTE+1-LOWLYR(I,J) !------------------------------------------------------------------------ ! ! Run BMJ scheme. ! !------------------------------------------------------------------------ CALL BMJ(I,J,DTCNVC,LMH,LANDMASK,CLDEFI(I,J) & ,DPCOL,PCOL,QCOL,TCOL,PSFC,PTOP & ,DQDT,DTDT,PCPCOL,LBOT,LTOP & ,CP,R,ELWV,G,TFRZ,D608 & ,IDS,IDE,JDS,JDE,KDS,KDE & ,IMS,IME,JMS,JME,KMS,KME & ,ITS,ITE,JTS,JTE,KTS,KTE) !------------------------------------------------------------------------ ! ! Compute heating and moistening tendencies. ! !------------------------------------------------------------------------ DO K=KTS,KTE KFLIP=KTE+1-K RTHCUTEN(I,K,J)=RR(I,K,J)* & ((1.+RVOVRD*QV(I,K,J))*DTDT(KFLIP) & /PI(I,K,J) & +RVOVRD*TH(I,K,J)*DQDT(KFLIP)) ! change 10/18/00 ! from specific humidity back to mixing ration RQVCUTEN(I,K,J)=RR(I,K,J)*DQDT(KFLIP)/(1.-QCOL(KFLIP)**2) END DO ! DO k = kts,kte !------------------------------------------------------------------------ ! ! All units in BMJ scheme are MKS, so convert precip from meters ! to millimeters per step. ! !------------------------------------------------------------------------ RAINCV(I,J)=PCPCOL*1.E3/STEPCU !------------------------------------------------------------------------ ! ! Variables cubot and cutop are the bottom and top layers, ! respectively, of the convective cloud. If need be, they can be ! used in the radiation computations. (Note: They are not ! used at this time! EMK) ! !------------------------------------------------------------------------ IF (CUBOT.NE.0) CUBOT=REAL(KTE+1-LBOT) IF (CUTOP.NE.0) CUTOP=REAL(KTE+1-LTOP) END DO ! DO i = its,ite END DO ! DO j = jts,jte END IF ! IF (ICLDCK.EQ.0) THEN END SUBROUTINE BMJDRV !######################################################################## !######################################################################## !######### ######### !######### SUBROUTINE bmj ######### !######### ######### !######### Adapted by ######### !######### Center for Analysis and Prediction of Storms ######### !######### University of Oklahoma ######### !######### ######### !######################################################################## !######################################################################## SUBROUTINE BMJ(I,J,DTCNVC,LMH,SM,CLDEFI & 1,2 ,DPRS,PRSMID,Q,T,PSFC,PT & ,DQDT,DTDT,PCPCOL,LBOT,LTOP & ,CP,R,ELWV,G,TFRZ,D608 & ,IDS,IDE,JDS,JDE,KDS,KDE & ,IMS,IME,JMS,JME,KMS,KME & ,ITS,ITE,JTS,JTE,KTS,KTE) !------------------------------------------------------------------------ ! ! PURPOSE: ! ! Runs the Betts-Miller-Janjic deep and shallow convective adjustment ! scheme. ! !------------------------------------------------------------------------ ! ! AUTHOR: ??? ! ! MODIFICATION: ! ! Eric Kemp, 21 September 2001 ! Reformatted code. ! !------------------------------------------------------------------------ ! ! Force explicit declarations ! !------------------------------------------------------------------------ IMPLICIT NONE !------------------------------------------------------------------------ ! ! Declare arguments ! !------------------------------------------------------------------------ INTEGER,INTENT(IN) :: IDS, & ! start index for i in domain IDE, & ! end index for i in domain JDS, & ! start index for j in domain JDE, & ! end index for j in domain KDS, & ! start index for k in domain KDE, & ! end index for k in domain IMS, & ! start index for i in memory IME, & ! end index for i in memory JMS, & ! start index for j in memory JME, & ! end index for j in memory KMS, & ! start index for k in memory KME, & ! end index for k in memory ITS, & ! start index for i in tile ITE, & ! end index for i in tile JTS, & ! start index for j in tile JTE, & ! end index for j in tile KTS, & ! start index for k in tile KTE, & ! end index for k in tile I, & ! I index of column J ! J index of column INTEGER,INTENT(IN) :: LMH ! Lowest k index above ground INTEGER,INTENT(OUT) :: LBOT,&! K level of bottom of convection LTOP ! K level of top of convection REAL,INTENT(IN) :: CP, & ! Specific heatat constant pressure ! (1004 J/K/kg) D608, & ! (Rv/Rd) - 1. DTCNVC, & ! Convection time step (stepcu*dt) ELWV, & ! Latent heat of vaporization at 0 deg C ! (2.5e6 J/kg) G, & ! Gravitational acceleration (9.81 m/s/s) PSFC, & ! Surface (lowest layer) pressure (Pa) PT, & ! Model top pressure (Pa) R, & ! Dry gas constant (287 J/K/kg) SM, & ! Land mask (1.0 for sea, 0.0 for land) TFRZ ! Freezing point (273.15 K) REAL,DIMENSION(KTS:KTE),INTENT(IN) :: & DPRS, & ! Delta pressure across layer (Pa) PRSMID, & ! Pressure at layer (Pa) Q, & ! Specific humidity (kg/kg) T ! Temperature (K) REAL,INTENT(INOUT) :: & CLDEFI, & ! Precip. efficiency (dimensionless) PCPCOL ! Convective precip. (m) REAL,DIMENSION(KTS:KTE),INTENT(INOUT) :: & DQDT, & ! Specific humidity time tendency (kg/kg/s) DTDT ! Temperature time tendency (K/s) !------------------------------------------------------------------------ ! ! Declare local variable arrays. ! !------------------------------------------------------------------------ REAL,DIMENSION(KTS:KTE) :: APEK,APESK,FPK & ,PK,PSK,QK,QREFK,QSATK & ,THERK,THEVRF,THSK & ,THVMOD,THVREF,TK,TREFK REAL,DIMENSION(KTS:KTE) :: APE,DIFQ,DIFT,TREF !------------------------------------------------------------------------ ! ! Declare local scalar variables. ! !------------------------------------------------------------------------ LOGICAL :: DEEP,SHALLOW REAL :: APEKL,APEKXX,APEKXY,APESP,APESTS & ,AVRGT,AVRGTL,BQ,BQK,BQS00K,BQS10K & ,CAPA,CTHRS,DEN,DENTPY,DEPMIN,DEPTH & ,DEPWL,DHDT,DIFQL,DIFTL,DPKL,DPMIX & ,DQREF,DRHDP,DRHEAT,DSP & ,DSP0,DSP0K,DSPB,DSPBK,DSPT,DSPTK & ,DST,DSTQ,DTHEM,DTDP,EFI & ,FEFI,FPTK,HCORR,OTSUM,P,P00K,P01K,P10K,P11K & ,PART1,PART2,PART3,PBOT,PBTK & ,PK0,PKB,PKL,PKT,PKXXXX,PKXXXY & ,PLMH,POTSUM,PP1,PPK,PRECK & ,PRESK,PSP,PSUM,PTHRS,PTOP,PTPK & ,QBT,QKL,QNEW,QOTSUM,QQ1,QQK,QRFKL,QRFTP,QSUM,RDP0T & ,RDPSUM,RDTCNVC,RHH,RHL,RHMAX,ROTSUM,RTBAR & ,SMIX,SQ,SQK,SQS00K,SQS10K,STABDL,SUMDE,SUMDP & ,SUMDT,TAUK,TCORR,THBT,THERKX,THERKY & ,THESP,THSKL,THTPK,THVMKL,TKL & ,TPSP,TQ,TQK,TREFKX,TRFKL,TSKL,TTH,TTHBT,TTHES,TTHK INTEGER :: IQ,IQTB,IT,ITER,ITTB,ITTBK,KB,KNUMH,KNUML & ,L,L0,L0M1,LB,LBM1,LCOR,LPT1 & ,LQM,LSHU,LTP1,LTP2,LTSH !------------------------------------------------------------------------ ! ! Declare local parameters. ! !------------------------------------------------------------------------ REAL,PARAMETER :: DSPBSL=DSPBFL*FSL,DSP0SL=DSP0FL*FSL & ,DSPTSL=DSPTFL*FSL & ,DSPBSS=DSPBFS*FSS,DSP0SS=DSP0FS*FSS & ,DSPTSS=DSPTFS*FSS REAL,PARAMETER :: AVGEFI=(EFIMN+1.)*.5,STEFI=1. REAL,PARAMETER :: SLOPBL=(DSPBFL-DSPBSL)/(1.-EFIMN) & ,SLOP0L=(DSP0FL-DSP0SL)/(1.-EFIMN) & ,SLOPTL=(DSPTFL-DSPTSL)/(1.-EFIMN) & ,SLOPBS=(DSPBFS-DSPBSS)/(1.-EFIMN) & ,SLOP0S=(DSP0FS-DSP0SS)/(1.-EFIMN) & ,SLOPTS=(DSPTFS-DSPTSS)/(1.-EFIMN) & ,SLOPE=(1.-EFMNT)/(1.-EFIMN) REAL :: A23M4L,CPRLG,ELOCP,FCB,RCP !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ CAPA=R/CP CPRLG=CP/(ROW*G*ELWV) ELOCP=ELIVW/CP RCP=1./CP A23M4L=A2*(A3-A4)*ELWV FCB=1.-FCC RDTCNVC=1./DTCNVC DEEP=.FALSE. SHALLOW=.FALSE. DSP0=0. DSPB=0. DSPT=0. PSP=0. TAUK=DTCNVC/TREL CTHRS=(0.006350/86400.)*DTCNVC/CPRLG !------------------------------------------------------------------------ ! ! Preparations. (???) ! !------------------------------------------------------------------------ LBOT=LMH THESP=0. PCPCOL=0. TREF(1)=T(1) DO L=1,LMH APESTS=PRSMID(L) APE(L)=(1.E5/APESTS)**CAPA END DO ! DO l = 1,lmh !------------------------------------------------------------------------ ! ! Search for maximum buoyancy level. ! !------------------------------------------------------------------------ DO 170 KB=1,LMH !------------------------------------------------------------------------ ! ! Trial maximum buoyancy level variables. ! !------------------------------------------------------------------------ PKL=PRSMID(KB) PLMH=PRSMID(LMH) !------------------------------------------------------------------------ ! ! Search over a scaled depth (between bottom pressure level and 80% ! of the bottom pressure level) to find the parcel with the maximum ! equivalent potential temperature. ! !------------------------------------------------------------------------ IF (PKL.GE.0.80*PLMH) THEN QBT=Q(KB) TTHBT=T(KB)*APE(KB) ! T to Theta TTH=(TTHBT-THL)*RDTH QQ1=TTH-AINT(TTH) ! Remainder used with (bi)linear ! interpolation. ITTB=INT(TTH)+1 ! Look-up table index. !------------------------------------------------------------------------ ! ! Keep indices within the table. (A look-up table is used for this ! code --EMK) ! !------------------------------------------------------------------------ IF (ITTB.LT.1) THEN ITTB=1 QQ1=0. END IF ! IF (ITTB.LT.1) THEN IF (ITTB.GE.JTB) THEN ITTB=JTB-1 QQ1=0. END IF ! IF (ITTB.GE.JTB) THEN !------------------------------------------------------------------------ ! ! Base and scaling factor for saturation specific humidity. ! !------------------------------------------------------------------------ ITTBK=ITTB BQS00K=QS0(ITTBK) SQS00K=SQS(ITTBK) BQS10K=QS0(ITTBK+1) SQS10K=SQS(ITTBK+1) !------------------------------------------------------------------------ ! ! Scaling specific humidity and table index using linear ! interpolation. ! !------------------------------------------------------------------------ BQ=(BQS10K-BQS00K)*QQ1+BQS00K SQ=(SQS10K-SQS00K)*QQ1+SQS00K TQ=(QBT-BQ)/SQ*RDQ PP1=TQ-AINT(TQ) ! Remainder used with bilinear interpolation. IQTB=INT(TQ)+1 ! Index in look-up table !------------------------------------------------------------------------ ! ! Keep indices within the table. (Refers to look-up table -- EMK) ! !------------------------------------------------------------------------ IF (IQTB.LT.1) THEN IQTB=1 PP1=0. END IF ! IF (IQTB.LT.1) THEN IF (IQTB.GE.ITB) THEN IQTB=ITB-1 PP1=0. END IF ! IF (IQTB.GE.ITB) THEN !------------------------------------------------------------------------ ! ! Saturation pressure at four surrounding table points. (Refers to ! look-up table --EMK) ! !------------------------------------------------------------------------ IQ=IQTB IT=ITTB P00K=PTBL(IQ ,IT ) P10K=PTBL(IQ+1,IT ) P01K=PTBL(IQ ,IT+1) P11K=PTBL(IQ+1,IT+1) !------------------------------------------------------------------------ ! ! Saturation point variables at the bottom. ! !------------------------------------------------------------------------ TPSP=P00K+(P10K-P00K)*PP1+(P01K-P00K)*QQ1 & +(P00K-P10K-P01K+P11K)*PP1*QQ1 ! Saturation pressure APESP=(1.E5/TPSP)**CAPA TTHES=TTHBT*EXP(ELOCP*QBT*APESP/TTHBT) ! Theta-e. !------------------------------------------------------------------------ ! ! Check for maximum buoyancy. ! !------------------------------------------------------------------------ IF (TTHES.GT.THESP) THEN PSP =TPSP THBT =TTHBT THESP=TTHES END IF ! IF (TTHES.GT.THESP) THEN END IF ! IF (ITTB.LT.1) THEN 170 CONTINUE ! DO 170 KB=1,LMH !------------------------------------------------------------------------ ! ! Choose cloud base as model level just below psp. ! !------------------------------------------------------------------------ DO L=1,LMH-1 P=PRSMID(L) IF (P.LT.PSP.AND.P.GE.PQM) LBOT=L+1 ! K level of bottom of convection END DO ! DO L=1,LMH-1 !------------------------------------------------------------------------ ! ! WARNING: LBOT must not be greater than LMH-1 in shallow convection ! scheme. Make sure the cloud base is at least PONE above the surface. ! PONE is currently set to 2500 Pa. ! !------------------------------------------------------------------------ PBOT=PRSMID(LBOT) ! Pressure at bottom of convection. PLMH=PRSMID(LMH) ! Bottom level pressure. IF (PBOT.GE.PLMH-PONE.OR.LBOT.GE.LMH) THEN DO L=1,LMH-1 P=PRSMID(L) IF(P.LT.PLMH-PONE) LBOT=L END DO ! DO L=1,LMH-1 PBOT=PRSMID(LBOT) END IF ! IF (PBOT.GE.PLMH-PONE.OR.LBOT.GE.LMH) THEN !------------------------------------------------------------------------ ! ! Cloud top computation. ! !------------------------------------------------------------------------ LTOP=LBOT ! Initialize k-index of top of convection PTOP=PBOT ! Initialize pressure of top of convection !------------------------------------------------------------------------ ! ! Compute parcel temperature along moist adiabat, scaling pressure ! and TT table index. (???) ! !------------------------------------------------------------------------ DO L=LMH,1,-1 PRESK=PRSMID(L) IF (PRESK.LT.PLQ) THEN ! PLQ = 70000 Pa CALL TTBLEX(ITB,JTB,PL,PRESK,RDP,RDTHE & ,STHE,THE0,THESP,TTBL,TREF(L)) ELSE CALL TTBLEX(ITBQ,JTBQ,PLQ,PRESK,RDPQ,RDTHEQ & ,STHEQ,THE0Q,THESP,TTBLQ,TREF(L)) END IF ! IF (PRESK.LT.PLQ) THEN END DO ! DO L=LMH,1,-1 !------------------------------------------------------------------------ ! ! Buoyancy check. ! !------------------------------------------------------------------------ DO L=LMH,1,-1 IF (TREF(L).GT.T(L)-DTTOP) LTOP=L ! K-index of top of cloud END DO ! DO L=LMH,1,-1 !------------------------------------------------------------------------ ! ! Cloud top pressure. ! !------------------------------------------------------------------------ PTOP=PRSMID(LTOP) !------------------------------------------------------------------------ ! ! Define and smooth dsps and cldefi. Unified or separate land/sea ! conv ! ! DSPB is the saturation pressure difference at cloud base. ! DSP0 is the saturation pressure difference at freezing level. ! DSPT is the saturation pressure difference at cloud top. ! !------------------------------------------------------------------------ EFI=CLDEFI IF (UNIS) THEN ! Currently, UNIS is set to true. !------------------------------------------------------------------------ ! ! All profiles are sea profiles (unified sea) (???) ! !------------------------------------------------------------------------ DSPB=(EFI-EFIMN)*SLOPBS+DSPBSS DSP0=(EFI-EFIMN)*SLOP0S+DSP0SS DSPT=(EFI-EFIMN)*SLOPTS+DSPTSS ELSE IF (.NOT.UNIL) THEN ! Currently, UNIL is set to false !------------------------------------------------------------------------ ! ! All profiles are not land profiles (not unified land) (???) ! !------------------------------------------------------------------------ DSPB=((EFI-EFIMN)*SLOPBS+DSPBSS)*SM & +((EFI-EFIMN)*SLOPBL+DSPBSL)*(1.-SM) DSP0=((EFI-EFIMN)*SLOP0S+DSP0SS)*SM & +((EFI-EFIMN)*SLOP0L+DSP0SL)*(1.-SM) DSPT=((EFI-EFIMN)*SLOPTS+DSPTSS)*SM & +((EFI-EFIMN)*SLOPTL+DSPTSL)*(1.-SM) ELSE !------------------------------------------------------------------------ ! ! All profiles are land profiles (unified land) (???) ! !------------------------------------------------------------------------ DSPB=((EFI-EFIMN)*SLOPBL+DSPBSL) DSP0=((EFI-EFIMN)*SLOP0L+DSP0SL) DSPT=((EFI-EFIMN)*SLOPTL+DSPTSL) END IF ! IF (UNIS) ... ELSE IF (.NOT. UNIL) ... !------------------------------------------------------------------------ ! ! Clean up and gather deep convection points. ! !------------------------------------------------------------------------ IF (LTOP.GE.LBOT) THEN LBOT=0 LTOP=LBOT PTOP=PBOT END IF IF (PTOP.GT.PBOT-PNO.OR.LTOP.GT.LBOT-2) & CLDEFI=AVGEFI*SM+STEFI*(1.-SM) ! Recalculate precip. efficiency !------------------------------------------------------------------------ ! ! Depth of cloud required to make the point a deep convection point is ! a scaled value of psfc. ! !------------------------------------------------------------------------ DEPMIN=PSH*PSFC*1.E-5 DEPTH=PBOT-PTOP IF (DEPTH.GE.DEPMIN) THEN DEEP=.TRUE. END IF ! IF (DEPTH.GE.DEPMIN) THEN !------------------------------------------------------------------------ ! ! Deep convection. ! !------------------------------------------------------------------------ IF (.NOT.DEEP) GO TO 600 ! Skip to shallow convection LB =LBOT EFI =CLDEFI DSPBK=DSPB DSP0K=DSP0 DSPTK=DSPT !------------------------------------------------------------------------ ! ! Initialize variables in the convective column. One should note that ! the values assigned to the array trefk in the following loop are ! really only relevant in anchoring the reference temperature profile ! at level lb. When building the reference profile from cloud base, ! then assigning the ambient temperature to trefk is acceptable. ! However, when building the reference profile from some other level ! (such as one level above the ground), then trefk should be filled with ! the temperatures in tref(l) which are the temperatures of the moist ! adiabat through cloud base. By the time the line numbered 450 has ! been reached, trefk actually does hold the reference temperature ! profile. ! !------------------------------------------------------------------------ DO L=1,LMH DIFT (L)=0. DIFQ (L)=0. TKL =T(L) TK (L)=TKL ! Temperature TREFK (L)=TKL ! Temperature QKL =Q(L) QK (L)=QKL ! Specific humidity QREFK (L)=QKL ! Specific humidity PKL =PRSMID(L) PK (L)=PKL ! Pressure PSK (L)=PKL ! Pressure APEKL =APE(L) APEK (L)=APEKL THERK (L)=TREF(L)*APEKL ! Temperature to Theta END DO ! DO L=1,LMH !------------------------------------------------------------------------ ! ! Deep convection reference temperature profile. ! !------------------------------------------------------------------------ LTP1=LTOP+1 ! K-index of one level below cloud top LBM1=LB-1 ! K-index of one level above cloud bottom PKB=PK(LB) ! Pressure at cloud bottom PKT=PK(LTOP) ! Pressure at cloud top !------------------------------------------------------------------------ ! ! Temperature reference profile below freezing level. ! !------------------------------------------------------------------------ L0=LB PK0=PK(LB) TREFKX=TREFK(LB) ! Temperature at cloud bottom THERKX=THERK(LB) ! Theta at cloud bottom APEKXX=APEK(LB) THERKY=THERK(LBM1) ! Theta at one level above cloud bottom APEKXY=APEK(LBM1) DO L=LBM1,LTOP,-1 IF (T(L+1).LT.TFRZ) GO TO 430 ! Skip to code for temperature profile ! above freezing level. STABDL=STABD TREFKX=((THERKY-THERKX)*STABDL & +TREFKX*APEKXX)/APEKXY ! Reference profile temperature TREFK(L)=TREFKX ! Reference profile temperature APEKXX=APEKXY THERKX=THERKY ! Change lower level theta to ! upper level theta. APEKXY=APEK(L-1) THERKY=THERK(L-1) ! Change upper level theta to ! theta from next highest level. L0=L PK0=PK(L0) ! Pressure END DO ! DO L=LBM1,LTOP,-1 !------------------------------------------------------------------------ ! ! Freezing level at or above the cloud top. ! !------------------------------------------------------------------------ L0M1=L0-1 GO TO 450 ! Skip to deep convection reference humidity profile. !------------------------------------------------------------------------ ! ! Temperature reference profile above freezing level. ! !------------------------------------------------------------------------ 430 L0M1=L0-1 RDP0T=1./(PK0-PKT) ! Reciprocal of difference in pressure between ! current level and cloud top. DTHEM=THERK(L0)-TREFK(L0)*APEK(L0) ! Difference between theta and ! reference theta. DO L=LTOP,L0M1 TREFK(L)=(THERK(L)-(PK(L)-PKT)*DTHEM*RDP0T)/APEK(L) ! Reference ! profile ! temperature. END DO ! DO L=LTOP,L0M1 !------------------------------------------------------------------------ ! ! Deep convection reference humidity profile. ! ! DEPWL is the pressure difference between cloud base and the freezing ! level. ! !------------------------------------------------------------------------ 450 DEPWL=PKB-PK0 DEPTH=PFRZ*PSFC*1.E-5 ! 15000 Pa * lowest layer pressure * 1.E-5 !------------------------------------------------------------------------ ! ! Saturation pressure difference. ! !------------------------------------------------------------------------ DO 460 L=LTOP,LB ! Cloud top to cloud base. IF (DEPWL.GE.DEPTH) THEN IF (L.LT.L0) THEN ! L0 is k-index of freezing level DSP=((PK0-PK(L))*DSPTK+(PK(L)-PKT)*DSP0K)/(PK0-PKT) ELSE DSP=((PKB-PK(L))*DSP0K+(PK(L)-PK0)*DSPBK)/(PKB-PK0) END IF ! IF (L.LT.L0) THEN ELSE DSP=DSP0K IF (L.LT.L0) & DSP=((PK0-PK(L))*DSPTK+(PK(L)-PKT)*DSP0K)/(PK0-PKT) END IF ! IF (DEPWL.GE.DEPTH) THEN !------------------------------------------------------------------------ ! ! Humidity profile. ! !------------------------------------------------------------------------ IF (PK(L).GT.PQM) THEN ! PQM = 20000 Pa PSK(L)=PK(L)+DSP APESK(L)=(1.E5/PSK(L))**CAPA THSK(L)=TREFK(L)*APEK(L) ! Reference profile theta QREFK(L)=PQ0/PSK(L)*EXP(A2*(THSK(L)-A3*APESK(L)) & /(THSK(L)-A4*APESK(L))) ! Reference ! profile ! sp. humidity. ELSE QREFK(L)=Q(L) ! Reference profile specific humidity. END IF ! IF (PK(L).GT.PQM) THEN 460 CONTINUE ! DO 460 L=LTOP,LB !------------------------------------------------------------------------ ! ! Enthalpy conservation integral. ! !------------------------------------------------------------------------ LQM=0 DO 520 ITER=1,2 SUMDE=0. ! Integral of enthalpy multiplied by delta pressure ! across each layer. SUMDP=0. ! Integral of pressure from cloud base to cloud top. DO L=LTOP,LB ! Cloud top to cloud base SUMDE=((TK(L)-TREFK(L))*CP+(QK(L)-QREFK(L))*ELWV)*DPRS(L) & +SUMDE SUMDP=SUMDP+DPRS(L) END DO ! DO L=LTOP,LB HCORR=SUMDE/(SUMDP-DPRS(LTOP)) ! Integrated enthalpy. LCOR=LTOP+1 ! One level below cloud top height. !------------------------------------------------------------------------ ! ! Find LQM. ! !------------------------------------------------------------------------ DO L=1,LB IF (PK(L).LE.PQM) LQM=L ! PQM = 20000 Pa END DO ! DO L=1,LB !------------------------------------------------------------------------ ! ! Below lqm (above 200 mb level) correct temperature only. ! !------------------------------------------------------------------------ IF (LCOR.LE.LQM) THEN DO L=LCOR,LQM TREFK(L)=TREFK(L)+HCORR*RCP END DO ! DO L=LCOR,LQM LCOR=LQM+1 END IF ! IF (LCOR.LE.LQM) THEN !------------------------------------------------------------------------ ! ! Above lqm (below 200 mb level) correct both temperature and moisture. ! !------------------------------------------------------------------------ DO L=LCOR,LB ! LQM + 1 to cloud bottom TSKL=TREFK(L)*APEK(L)/APESK(L) DHDT=QREFK(L)*A23M4L/(TSKL-A4)**2+CP TREFK(L)=HCORR/DHDT+TREFK(L) THSKL=TREFK(L)*APEK(L) QREFK(L)=PQ0/PSK(L)*EXP(A2*(THSKL-A3*APESK(L)) & /(THSKL-A4*APESK(L))) END DO ! DO L=LCOR,LB 520 CONTINUE ! DO 520 ITER=1,2 !------------------------------------------------------------------------ ! ! Heating, moistening, precipitation. (???) ! !------------------------------------------------------------------------ DENTPY=0. ! Integral of difference in entropy between actual and ! reference thermodynamic profile. AVRGT =0. PRECK =0. ! Condensate/precipitation DO L=LTOP,LB ! Cloud top to cloud base TKL =TK(L) DIFTL =(TREFK(L)-TKL )*TAUK ! TAUK=DTCNVC/TREL DIFQL =(QREFK(L)-QK(L))*TAUK ! TAUK=DTCNVC/TREL AVRGTL =(TKL+TKL+DIFTL) DENTPY =(DIFTL*CP+DIFQL*ELWV)*DPRS(L)/AVRGTL+DENTPY AVRGT =AVRGTL*DPRS(L)+AVRGT PRECK =DPRS(L)*DIFTL+PRECK DIFT(L)=DIFTL DIFQ(L)=DIFQL END DO ! DO L=LTOP,LB DENTPY=DENTPY+DENTPY AVRGT =AVRGT/(SUMDP+SUMDP) !------------------------------------------------------------------------ ! ! Swap if entropy and/or precip is less than zero. ! !------------------------------------------------------------------------ IF (DENTPY.LT.EPSNTP.OR.PRECK.LT.0.) THEN ! EPSNTP = 1.E2 CLDEFI=EFIMN*SM+STEFI*(1.-SM) ! New precip. efficiency !------------------------------------------------------------------------ ! ! Search for shallow cloud top. ! !------------------------------------------------------------------------ LTSH=LBOT ! K-index of cloud bottom LBM1=LBOT-1 ! K-index of level above cloud bottom PBTK=PK(LBOT) ! Pressure at cloud bottom DEPMIN=PSH*PSFC*1.E-5 PTPK=PBTK-DEPMIN ! Est. pressure at shallow cloud top !------------------------------------------------------------------------ ! ! Cloud top is the level just below pbtk-psh. ! !------------------------------------------------------------------------ DO L=1,LMH IF(PK(L).LE.PTPK)LTOP=L+1 ! K-index of shallow cloud top END DO ! DO L=1,LMH PTPK=PK(LTOP) ! Pressure of shallow cloud top !------------------------------------------------------------------------ ! ! Highest level allowed is level just below pshu. ! !------------------------------------------------------------------------ IF (PTPK.LE.PSHU) THEN ! PSHU = 45000 Pa DO L=1,LMH IF (PK(L).LE.PSHU) LSHU=L+1 END DO ! DO L=1,LMH LTOP=LSHU ! K-index of shallow cloud top PTPK=PK(LTOP) ! Pressure of shallow cloud top END IF ! IF (PTPK.LE.PSHU) THEN LTP1=LTOP+1 ! K-index of first level below shallow cloud top LTP2=LTOP+2 ! K-index of second level below shallow cloud top DO L=LTOP,LBOT QSATK(L)=PQ0/PK(L)*EXP(A2*(TK(L)-A3)/(TK(L)-A4)) ! Saturation ! sp. humidity. END DO ! DO L=LTOP,LBOT RHH=QK(LTOP)/QSATK(LTOP) ! Relative humidity at shallow cloud top RHMAX=0. DO L=LTP1,LBM1 ! Cloud top to cloud bottom RHL=QK(L)/QSATK(L) ! Relative humidity DRHDP=(RHH-RHL)/(PK(L-1)-PK(L)) ! Lapse rate of relative humidity IF (DRHDP.GT.RHMAX) THEN LTSH=L-1 ! K-index of maximum relative humidity RHMAX=DRHDP END IF ! IF (DRHDP.GT.RHMAX) THEN RHH=RHL END DO ! DO L=LTP1,LBM1 LTOP=LTSH ! K-index of shallow cloud top !------------------------------------------------------------------------ ! ! Cloud must be at least two layers thick. ! !------------------------------------------------------------------------ IF (LBOT-LTOP.LT.2) LTOP=LBOT-2 PTOP=PK(LTOP) ! Pressure of shallow cloud top GO TO 600 ! Go to shallow convection END IF ! IF (DENTPY.LT.EPSNTP.OR.PRECK.LT.0.) THEN !------------------------------------------------------------------------ ! ! Deep convection otherwise. ! ! Keep the land value of efi equal to 1 until precip surpasses ! a threshold value, currently set to 0.25 in per 24 hrs. ! !------------------------------------------------------------------------ PTHRS=CTHRS DRHEAT=(PRECK*SM+AMAX1(EPSP,PRECK-PTHRS)*(1.-SM)) & *CP/AVRGT ! Latent heat release EFI=EFIFC*DENTPY/DRHEAT ! Precip. efficiency !------------------------------------------------------------------------ ! ! Unified or separate land/sea conv. (???) ! !------------------------------------------------------------------------ EFI=CLDEFI*FCB+EFI*FCC ! Precip. efficiency, between 0.20 and 1. IF(EFI.GT.1. )EFI=1. IF(EFI.LT.EFIMN)EFI=EFIMN IF(PRECK.EQ.0.) EFI=1. CLDEFI=EFI FEFI=EFMNT+SLOPE*(EFI-EFIMN) ! FEFI=AMAX1(EFI,EFMNT) ! PRECK=PRECK*FEFI !------------------------------------------------------------------------ ! ! Precipitation, temperature and moisture changes. ! !------------------------------------------------------------------------ PCPCOL=PRECK*CPRLG ! Precipitation accumuluation. DO L=LTOP,LB DTDT(L)=DIFT(L)*FEFI*RDTCNVC ! Temperature tendency DQDT(L)=DIFQ(L)*FEFI*RDTCNVC ! Moisture tendency END DO ! DO L=LTOP,LB 600 CONTINUE ! End of deep convection !------------------------------------------------------------------------ ! ! Gather shallow convection points. ! !------------------------------------------------------------------------ IF (PTOP.LE.PBOT-PNO.AND.LTOP.LE.LBOT-2) THEN DEPMIN=PSH*PSFC*1.E-5 ! Minimum depth requirement IF (PTOP+1..GE.PBOT-DEPMIN) THEN SHALLOW=.TRUE. END IF ! IF (PTOP+1..GE.PBOT-DEPMIN) THEN END IF ! IF (PTOP.LE.PBOT-PNO.AND.LTOP.LE.LBOT-2) THEN IF (.NOT.SHALLOW) GO TO 800 ! Skip shallow convection !------------------------------------------------------------------------ ! ! Shallow convection. ! !------------------------------------------------------------------------ DO L=1,LMH TKL =T(L) TK (L) =TKL ! Temperature TREFK(L) =TKL ! Temperature QKL =Q(L) QK (L) =QKL ! Specific humidity QREFK(L) =QKL ! Specific humidity PKL =PRSMID(L) PK (L) =PKL ! Pressure QSATK(L) =PQ0/PK(L)*EXP(A2*(TK(L)-A3)/(TK(L)-A4)) ! Saturation specific humidity APEKL =APE(L) APEK (L) =APEKL THVMKL =TKL*APEKL*(QKL*D608+1.) ! Theta-v THVREF(L)=THVMKL ! Theta-v END DO ! DO L=1,LMH !------------------------------------------------------------------------ ! ! Shallow cloud top. ! !------------------------------------------------------------------------ LBM1=LBOT-1 ! One k-level above cloud bottom PTPK=PTOP ! Pressure at cloud top LTP1=LTOP-1 ! One k-level above cloud top ! NOTE: This appears to be redundant...EMK IF (PTOP.GT.PBOT-PNO.OR.LTOP.GT.LBOT-2) THEN LBOT=0 LTOP=LBOT PTOP=PBOT GO TO 800 ! Skip shallow convection END IF ! IF (PTOP.GT.PBOT-PNO.OR.LTOP.GT.LBOT-2) THEN !------------------------------------------------------------------------ ! ! Scaling potential temperature and table index at top. ! !------------------------------------------------------------------------ THTPK=T(LTP1)*APE(LTP1) ! Theta at one level above cloud top TTHK=(THTPK-THL)*RDTH QQK =TTHK-AINT(TTHK) ! Remainder for linear interpolation. IT =INT(TTHK)+1 ! Index for look-up table IF (IT.LT.1) THEN IT=1 QQK=0. END IF ! IF (IT.LT.1) THEN IF (IT.GE.JTB) THEN IT=JTB-1 QQK=0. END IF ! IF (IT.GE.JTB) THEN !------------------------------------------------------------------------ ! ! Base and scaling factor for saturation specific humidity at top. ! !------------------------------------------------------------------------ BQS00K=QS0(IT) SQS00K=SQS(IT) BQS10K=QS0(IT+1) SQS10K=SQS(IT+1) !------------------------------------------------------------------------ ! ! Scaling saturation specific humidity and table index at top. ! !------------------------------------------------------------------------ BQK=(BQS10K-BQS00K)*QQK+BQS00K SQK=(SQS10K-SQS00K)*QQK+SQS00K ! TQK=(Q(LTOP)-BQK)/SQK*RDQ TQK=(Q(LTP1)-BQK)/SQK*RDQ PPK=TQK-AINT(TQK) ! Remainder for linear interpolation. IQ =INT(TQK)+1 ! Index for look-up table. IF (IQ.LT.1) THEN IQ=1 PPK=0. END IF ! IF (IQ.LT.1) THEN IF (IQ.GE.ITB) THEN IQ=ITB-1 PPK=0. END IF ! IF (IQ.GE.ITB) THEN !------------------------------------------------------------------------ ! ! Cloud top saturation point pressure. ! !------------------------------------------------------------------------ PART1=(PTBL(IQ+1,IT)-PTBL(IQ,IT))*PPK PART2=(PTBL(IQ,IT+1)-PTBL(IQ,IT))*QQK PART3=(PTBL(IQ ,IT )-PTBL(IQ+1,IT ) & -PTBL(IQ ,IT+1)+PTBL(IQ+1,IT+1))*PPK*QQK PTPK=PTBL(IQ,IT)+PART1+PART2+PART3 ! Saturation point pressure DPMIX=PTPK-PSP ! Difference in saturation pressure along mixing line ! between cloud base and cloud top. IF (ABS(DPMIX).LT.3000.) DPMIX=-3000. !------------------------------------------------------------------------ ! ! Temperature profile slope. ! !------------------------------------------------------------------------ SMIX=(THTPK-THBT)/DPMIX*STABS TREFKX=TREFK(LBOT+1) ! Reference profile temperature one level below ! cloud bottom. PKXXXX=PK(LBOT+1) ! Pressure one level below cloud bottom. PKXXXY=PK(LBOT) ! Pressure at cloud bottom. APEKXX=APEK(LBOT+1) APEKXY=APEK(LBOT) DO L=LBOT,LTOP,-1 TREFKX=((PKXXXY-PKXXXX)*SMIX & +TREFKX*APEKXX)/APEKXY TREFK(L)=TREFKX ! Reference profile temperature. APEKXX=APEKXY PKXXXX=PKXXXY ! Switch lower-level pressure with upper-level ! pressure. APEKXY=APEK(L-1) PKXXXY=PK(L-1) ! Switch upper-level pressure with pressure at ! next highest level. END DO ! DO L=LBOT,LTOP,-1 !------------------------------------------------------------------------ ! ! Temperature reference profile correction. ! !------------------------------------------------------------------------ SUMDT=0. ! Integral of temperature difference times pressure thickness ! of layers. SUMDP=0. ! Integral of thickness of pressure of layers. DO L=LTOP,LBOT SUMDT=(TK(L)-TREFK(L))*DPRS(L)+SUMDT SUMDP=SUMDP+DPRS(L) END DO ! DO L=LTOP,LBOT RDPSUM=1./SUMDP FPK(LBOT)=TREFK(LBOT) TCORR=SUMDT*RDPSUM ! Integral of temperature difference. DO L=LTOP,LBOT TRFKL =TREFK(L)+TCORR TREFK(L)=TRFKL ! Reference profile temperature. FPK (L)=TRFKL END DO ! DO L=LTOP,LBOT !------------------------------------------------------------------------ ! ! Humidity profile equations. ! !------------------------------------------------------------------------ PSUM =0. ! Integral of pressure differences 1 (pressure of layer and ! pressure of cloud top) times pressure difference 2 ! (thickness of layers). QSUM =0. ! Integral of specific humidity times pressure thickness ! of layers. POTSUM=0. QOTSUM=0. OTSUM =0. DST =0. ! Change in entropy. FPTK =FPK(LTOP) ! Reference profile temperature at cloud top. DO L=LTOP,LBOT ! Cloud top to cloud base DPKL =FPK(L)-FPTK PSUM =DPKL *DPRS(L)+PSUM QSUM =QK(L)*DPRS(L)+QSUM RTBAR =2./(TREFK(L)+TK(L)) OTSUM =DPRS(L)*RTBAR+OTSUM POTSUM=DPKL *RTBAR*DPRS(L)+POTSUM QOTSUM=QK(L) *RTBAR*DPRS(L)+QOTSUM DST =(TREFK(L)-TK(L))*RTBAR*DPRS(L)+DST END DO ! DO L=LTOP,LBOT PSUM =PSUM*RDPSUM QSUM =QSUM*RDPSUM ROTSUM=1./OTSUM POTSUM=POTSUM*ROTSUM QOTSUM=QOTSUM*ROTSUM DST =DST*ROTSUM*CP/ELWV ! Change in entropy !------------------------------------------------------------------------ ! ! Ensure positive entropy change. ! !------------------------------------------------------------------------ IF (DST.GT.0.) THEN ! DSTQ=DST*EPSUP LBOT=0 LTOP=LBOT PTOP=PBOT GO TO 800 ! Skip shallow convection ELSE DSTQ=DST*EPSDN ! EPSDN = 1.05 END IF ! IF (DST.GT.0.) THEN !------------------------------------------------------------------------ ! ! Check for isothermal atmosphere. ! !------------------------------------------------------------------------ DEN=POTSUM-PSUM IF (-DEN/PSUM.LT.5.E-5) THEN LBOT=0 LTOP=LBOT PTOP=PBOT GO TO 800 ! Skip shallow convection ELSE !------------------------------------------------------------------------ ! ! Slope of the reference humidity profile. ! !------------------------------------------------------------------------ DQREF=(QOTSUM-DSTQ-QSUM)/DEN END IF ! IF (-DEN/PSUM.LT.5.E-5) THEN !------------------------------------------------------------------------ ! ! Humidity does not increase with height. ! !------------------------------------------------------------------------ IF (DQREF.LT.0.) THEN LBOT=0 LTOP=LBOT PTOP=PBOT GO TO 800 ! Skip shallow convection END IF ! IF (DQREF.LT.0.) THEN !------------------------------------------------------------------------ ! ! Humidity at the cloud top. ! !------------------------------------------------------------------------ QRFTP=QSUM-DQREF*PSUM !------------------------------------------------------------------------ ! ! Humidity profile. ! !------------------------------------------------------------------------ DO L=LTOP,LBOT ! Cloud top to cloud base QRFKL=(FPK(L)-FPTK)*DQREF+QRFTP !------------------------------------------------------------------------ ! ! Supersaturation or negative q not allowed. ! !------------------------------------------------------------------------ QNEW=(QRFKL-QK(L))*TAUK+QK(L) ! New specific humidity. IF (QNEW.GT.QSATK(L)*STRESH .OR. QNEW.LT.0.) THEN LBOT=0 LTOP=LBOT PTOP=PBOT GO TO 800 ! Skip shallow convection END IF ! IF (QNEW.GT.QSATK(L)*STRESH .OR. QNEW.LT.0.) THEN THVREF(L)=TREFK(L)*APEK(L)*(QRFKL*D608+1.) ! New theta-v. QREFK(L)=QRFKL ! New reference profile specific humidity. END DO ! DO L=LTOP,LBOT !------------------------------------------------------------------------ ! ! Eliminate impossible slopes. (Betts, dtheta/dq) ! !------------------------------------------------------------------------ DO L=LTOP,LBOT ! Cloud top to cloud base. DTDP=(THVREF(L-1)-THVREF(L))/(PRSMID(L)-PRSMID(L-1)) ! Dthetav/DP IF (DTDP.LT.EPSDT) THEN ! EPSDT = 0. LBOT=0 LTOP=LBOT PTOP=PBOT GO TO 800 ! Skip shallow convection END IF ! IF (DTDP.LT.EPSDT) THEN END DO ! DO L=LTOP,LBOT DENTPY=0. DO L=LTOP,LBOT ! Cloud top to cloud base. DENTPY=((TREFK(L)-TK(L))*CP+(QREFK(L)-QK(L))*ELWV) & /(TK(L)+TREFK(L))*DPRS(L)+DENTPY ! Change in entropy END DO ! DO L=LTOP,LBOT !------------------------------------------------------------------------ ! ! Relaxation toward reference profiles. ! !------------------------------------------------------------------------ DO L=LTOP,LBOT ! Cloud top to cloud base DTDT(L)=(TREFK(L)-TK(L))*TAUK*RDTCNVC ! Temperature tendency DQDT(L)=(QREFK(L)-QK(L))*TAUK*RDTCNVC ! Specific humidity tendency END DO ! DO L=LTOP,LBOT !------------------------------------------------------------------------ ! ! End of shallow convection. ! !------------------------------------------------------------------------ 800 CONTINUE END SUBROUTINE BMJ !######################################################################## !######################################################################## !######### ######### !######### SUBROUTINE ttblex ######### !######### ######### !######### Adapted by ######### !######### Center for Analysis and Prediction of Storms ######### !######### University of Oklahoma ######### !######### ######### !######################################################################## !######################################################################## SUBROUTINE TTBLEX(ITBX,JTBX,PLX,PRSMID,RDPX,RDTHEX,STHE,THE0,THESP,TTBL & 4 ,TREF) !------------------------------------------------------------------------ ! ! PURPOSE: ! ! Extract temperature of the moist adiabat from the appropriate ttbl. ! !------------------------------------------------------------------------ ! ! AUTHOR: ??? ! ! MODIFICATIONS: ! ! Eric Kemp, 24 September 2001 ! Reformatted code. ! !------------------------------------------------------------------------ ! ! Force explicit declarations. ! !------------------------------------------------------------------------ IMPLICIT NONE !------------------------------------------------------------------------ ! ! Declare arguments. ! !------------------------------------------------------------------------ INTEGER,INTENT(IN) :: ITBX,JTBX ! Dimensions of look-up tables REAL,INTENT(IN) :: PLX, & ! Pressure reference used with look-up ! table calculation. PRSMID, & ! Grid point pressure (Pa). RDPX, & ! Remainder used with look-up table ! calculation. RDTHEX, & ! Remainder used with look-up table ! calculation. THESP ! Saturation point potential temperature ! (K). REAL,DIMENSION(ITBX),INTENT(IN) :: STHE, & ! Look-up table. THE0 ! Look-up table. REAL,DIMENSION(JTBX,ITBX),INTENT(IN) :: TTBL ! Look-up table. REAL,INTENT(OUT) :: TREF ! Parcel temperature (K) !------------------------------------------------------------------------ ! ! Internal variables. ! !------------------------------------------------------------------------ REAL :: BTHE00K,BTHE10K,BTHK,PK,PP,QQ,STHE00K,STHE10K,STHK & ,T00K,T01K,T10K,T11K,TPK,TTHK INTEGER :: IPTB,ITHTB !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !------------------------------------------------------------------------ ! ! Scaling pressure and TT table index. ! ! Determine pressure index for look-up table and remainder for (bi)linear ! interpolation. ! !------------------------------------------------------------------------ PK=PRSMID TPK=(PK-PLX)*RDPX QQ=TPK-AINT(TPK) ! Remainder for linear interpolation. IPTB=INT(TPK)+1 ! Index for look-up table. !------------------------------------------------------------------------ ! ! Keeping indices within the table. ! !------------------------------------------------------------------------ IF (IPTB.LT.1) THEN IPTB=1 ! Index for look-up table. QQ=0. ! Remainder for linear interpolation. END IF ! IF (IPTB.LT.1) THEN IF (IPTB.GE.ITBX) THEN IPTB=ITBX-1 ! Index for look-up table. QQ=0. ! Remainder for linear interpolation. END IF ! IF (IPTB.GE.ITBX) THEN !------------------------------------------------------------------------ ! ! Base and scaling factor for thetae. ! !------------------------------------------------------------------------ BTHE00K=THE0(IPTB) STHE00K=STHE(IPTB) BTHE10K=THE0(IPTB+1) STHE10K=STHE(IPTB+1) !------------------------------------------------------------------------ ! ! Scaling the and TT table index. (???) ! ! Use linear interpolation to determine the scale and base factors for ! thetae, then use them to determine theta-e index for look-up table ! and remainder for bilinear interpolation. ! !------------------------------------------------------------------------ BTHK=(BTHE10K-BTHE00K)*QQ+BTHE00K STHK=(STHE10K-STHE00K)*QQ+STHE00K TTHK=(THESP-BTHK)/STHK*RDTHEX PP=TTHK-AINT(TTHK) ! Remainder for linear interpolation. ITHTB=INT(TTHK)+1 ! Index for look-up table. !------------------------------------------------------------------------ ! ! Keeping indices within the table. ! !------------------------------------------------------------------------ IF (ITHTB.LT.1) THEN ITHTB=1 ! Index for look-up table. PP=0. ! Remainder for linear interpolation. END IF ! IF (ITHTB.LT.1) THEN IF (ITHTB.GE.JTBX) THEN ITHTB=JTBX-1 ! Index for look-up table. PP=0. ! Remainder for linear interpolation. END IF ! IF (ITHTB.GE.JTBX) THEN !------------------------------------------------------------------------ ! ! Temperature at four surrounding TT table points. ! !------------------------------------------------------------------------ T00K=TTBL(ITHTB,IPTB) T10K=TTBL(ITHTB+1,IPTB) T01K=TTBL(ITHTB,IPTB+1) T11K=TTBL(ITHTB+1,IPTB+1) !------------------------------------------------------------------------ ! ! Parcel temperature, using bilinear interpolation. ! !------------------------------------------------------------------------ TREF=(T00K+(T10K-T00K)*PP+(T01K-T00K)*QQ & +(T00K-T10K-T01K+T11K)*PP*QQ) END SUBROUTINE TTBLEX !######################################################################## !######################################################################## !######### ######### !######### SUBROUTINE bmjinit ######### !######### ######### !######### Adapted by ######### !######### Center for Analysis and Prediction of Storms ######### !######### University of Oklahoma ######### !######### ######### !######################################################################## !######################################################################## SUBROUTINE BMJINIT(RTHCUTEN,RQVCUTEN,RQCCUTEN,RQRCUTEN & 1,3 ,CLDEFI,LOWLYR,CP,RD,restart & ,IDS,IDE,JDS,JDE,KDS,KDE & ,IMS,IME,JMS,JME,KMS,KME & ,ITS,ITE,JTS,JTE,KTS,KTE) !------------------------------------------------------------------------ ! ! PURPOSE: ! ! Initialize variables and look-up tables used by Betts-Miller-Janjic ! convective scheme. ! !------------------------------------------------------------------------ ! ! AUTHOR: ??? ! ! MODIFICATIONS: ! ! Eric Kemp, 24 September 2001 ! Reformatted code. ! !------------------------------------------------------------------------ ! ! Force explicit declarations. ! !------------------------------------------------------------------------ IMPLICIT NONE !------------------------------------------------------------------------ ! ! Declare arguments. ! !------------------------------------------------------------------------ LOGICAL , INTENT(IN) :: restart ! Restart flag. INTEGER,INTENT(IN) :: IDS, & ! start index for i in domain IDE, & ! end index for i in domain JDS, & ! start index for j in domain JDE, & ! end index for j in domain KDS, & ! start index for k in domain KDE, & ! end index for k in domain IMS, & ! start index for i in memory IME, & ! end index for i in memory JMS, & ! start index for j in memory JME, & ! end index for j in memory KMS, & ! start index for k in memory KME, & ! end index for k in memory ITS, & ! start index for i in tile ITE, & ! end index for i in tile JTS, & ! start index for j in tile JTE, & ! end index for j in tile KTS, & ! start index for k in tile KTE ! end index for k in tile REAL,INTENT(IN) :: CP, & ! specific heat at constant pressure ! (1004 J/k/kg) RD ! Dry air gas constant. REAL,DIMENSION(IMS:,KMS:,JMS:),INTENT(OUT) :: & RTHCUTEN, & ! Rho_dTheta_m tendency due to ! cumulus scheme precipitation ! (kg/m^3 . K) RQVCUTEN, & ! Rho_dQv tendency due to ! cumulus scheme precipitation ! (kg/m^3 . kg/kg) RQCCUTEN, & ! Rho_dQc tendency due to ! cumulus scheme precipitation ! (kg/m^3 . kg/kg) RQRCUTEN ! Rho_dQr tendency due to ! cumulus scheme precipitation ! (kg/m^3 . kg/kg) REAL,DIMENSION(IMS:,JMS:),INTENT(OUT) :: & CLDEFI ! Precipitation efficiency (for BMJ scheme) ! (dimensionless) INTEGER,DIMENSION(IMS:,JMS:),INTENT(OUT) :: & LOWLYR ! Index of lowest model layer above the ground !------------------------------------------------------------------------ ! ! Declare internal parameters. ! !------------------------------------------------------------------------ REAL,PARAMETER :: ELIWV=2.683E6,EPS=1.E-9 !------------------------------------------------------------------------ ! ! Declare internal variables. ! !------------------------------------------------------------------------ REAL, DIMENSION(JTB) :: APP,APT,AQP,AQT,PNEW,POLD,QSNEW,QSOLD & ,THENEW,THEOLD,TNEW,TOLD,Y2P,Y2T REAL,DIMENSION(JTBQ) :: APTQ,AQTQ,THENEWQ,THEOLDQ & ,TNEWQ,TOLDQ,Y2TQ INTEGER :: I,J,K,ITF,JTF,KTF INTEGER :: KTH,KTHM,KTHM1,KP,KPM,KPM1 REAL :: APE,DP,DQS,DTH,DTHE,P,QS,QS0K,SQSK,STHEK & ,TH,THE0K !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ JTF=MIN0(JTE,JDE-1) KTF=MIN0(KTE,KDE-1) ITF=MIN0(ITE,IDE-1) IF (.not.restart) THEN DO J=JTS,JTF DO K=KTS,KTF DO I=ITS,ITF RTHCUTEN(I,K,J)=0. RQVCUTEN(I,K,J)=0. RQCCUTEN(I,K,J)=0. RQRCUTEN(I,K,J)=0. END DO ! DO I=ITS,ITF END DO ! DO K=KTS,KTF END DO ! DO J=JTS,JTF DO J=JTS,JTF DO I=ITS,ITF CLDEFI(I,J)=1. END DO ! DO I=ITS,ITF END DO ! DO J=JTS,JTF END IF ! IF (.not.restart) THEN !------------------------------------------------------------------------ ! ! For now, assume sigma mode for lowest model layer. ! !------------------------------------------------------------------------ DO J=JTS,JTF DO I=ITS,ITF LOWLYR(I,J)=1 END DO ! DO I=ITS,ITF END DO ! DO J=JTS,JTF !------------------------------------------------------------------------ ! ! Coarse look-up table for saturation point. ! !------------------------------------------------------------------------ KTHM=JTB KPM=ITB KTHM1=KTHM-1 KPM1=KPM-1 DTH=(THH-THL)/REAL(KTHM-1) DP =(PH -PL )/REAL(KPM -1) TH=THL-DTH DO 100 KTH=1,KTHM TH=TH+DTH P=PL-DP DO KP=1,KPM P=P+DP APE=(100000./P)**(RD/CP) QSOLD(KP)=PQ0/P*EXP(A2*(TH-A3*APE)/(TH-A4*APE)) ! Saturation ! specific humidity. POLD(KP)=P END DO ! DO KP=1,KPM QS0K=QSOLD(1) SQSK=QSOLD(KPM)-QSOLD(1) ! Scaling factor. QSOLD(1 )=0. QSOLD(KPM)=1. DO KP=2,KPM1 QSOLD(KP)=(QSOLD(KP)-QS0K)/SQSK ! Base look-up table IF ((QSOLD(KP)-QSOLD(KP-1)).LT.EPS) QSOLD(KP)=QSOLD(KP-1)+EPS END DO ! DO KP=2,KPM1 QS0(KTH)=QS0K ! Base factor look-up table. SQS(KTH)=SQSK ! Scaling factor look-up table. QSNEW(1 )=0. QSNEW(KPM)=1. DQS=1./REAL(KPM-1) DO KP=2,KPM1 QSNEW(KP)=QSNEW(KP-1)+DQS END DO ! DO KP=2,KPM1 Y2P(1 )=0. Y2P(KPM )=0. CALL SPLINE(JTB,KPM,QSOLD,POLD,Y2P,KPM,QSNEW,PNEW,APP,AQP) DO KP=1,KPM PTBL(KP,KTH)=PNEW(KP) END DO ! DO KP=1,KPM 100 CONTINUE ! DO 100 KTH=1,KTHM !------------------------------------------------------------------------ ! ! Coarse look-up table for T(P) from constant THE. (???) ! !------------------------------------------------------------------------ P=PL-DP DO 200 KP=1,KPM P=P+DP TH=THL-DTH DO KTH=1,KTHM TH=TH+DTH APE=(1.E5/P)**(RD/CP) QS=PQ0/P*EXP(A2*(TH-A3*APE)/(TH-A4*APE)) TOLD(KTH)=TH/APE THEOLD(KTH)=TH*EXP(ELIWV*QS/(CP*TOLD(KTH))) END DO ! DO KTH=1,KTHM THE0K=THEOLD(1) STHEK=THEOLD(KTHM)-THEOLD(1) THEOLD(1 )=0. THEOLD(KTHM)=1. DO KTH=2,KTHM1 THEOLD(KTH)=(THEOLD(KTH)-THE0K)/STHEK IF((THEOLD(KTH)-THEOLD(KTH-1)).LT.EPS) & THEOLD(KTH)=THEOLD(KTH-1) + EPS END DO ! DO KTH=2,KTHM1 THE0(KP)=THE0K STHE(KP)=STHEK THENEW(1 )=0. THENEW(KTHM)=1. DTHE=1./REAL(KTHM-1) DO KTH=2,KTHM1 THENEW(KTH)=THENEW(KTH-1)+DTHE END DO ! DO KTH=2,KTHM1 Y2T(1 )=0. Y2T(KTHM)=0. CALL SPLINE(JTB,KTHM,THEOLD,TOLD,Y2T,KTHM,THENEW,TNEW,APT,AQT) DO KTH=1,KTHM TTBL(KTH,KP)=TNEW(KTH) END DO ! DO KTH=1,KTHM 200 CONTINUE ! DO 200 KP=1,KPM !------------------------------------------------------------------------ ! ! Fine look-up table for saturation point. ! !------------------------------------------------------------------------ KTHM=JTBQ KPM=ITBQ KTHM1=KTHM-1 KPM1=KPM-1 DTH=(THHQ-THL)/REAL(KTHM-1) DP=(PH-PLQ)/REAL(KPM-1) TH=THL-DTH P=PLQ-DP !------------------------------------------------------------------------ ! ! Fine look-up table for T(P) from constant THE. (???) ! !------------------------------------------------------------------------ DO 300 KP=1,KPM P=P+DP TH=THL-DTH DO KTH=1,KTHM TH=TH+DTH APE=(1.E5/P)**(RD/CP) QS=PQ0/P*EXP(A2*(TH-A3*APE)/(TH-A4*APE)) TOLDQ(KTH)=TH/APE THEOLDQ(KTH)=TH*EXP(ELIWV*QS/(CP*TOLDQ(KTH))) END DO ! DO KTH=1,KTHM THE0K=THEOLDQ(1) STHEK=THEOLDQ(KTHM)-THEOLDQ(1) THEOLDQ(1 )=0. THEOLDQ(KTHM)=1. DO KTH=2,KTHM1 THEOLDQ(KTH)=(THEOLDQ(KTH)-THE0K)/STHEK IF ((THEOLDQ(KTH)-THEOLDQ(KTH-1)).LT.EPS) & THEOLDQ(KTH)=THEOLDQ(KTH-1) + EPS END DO ! DO KTH=2,KTHM1 THE0Q(KP)=THE0K STHEQ(KP)=STHEK THENEWQ(1 )=0. THENEWQ(KTHM)=1. DTHE=1./REAL(KTHM-1) DO KTH=2,KTHM1 THENEWQ(KTH)=THENEWQ(KTH-1)+DTHE END DO ! DO KTH=2,KTHM1 Y2TQ(1 )=0. Y2TQ(KTHM)=0. CALL SPLINE(JTBQ,KTHM,THEOLDQ,TOLDQ,Y2TQ,KTHM & ,THENEWQ,TNEWQ,APTQ,AQTQ) DO KTH=1,KTHM TTBLQ(KTH,KP)=TNEWQ(KTH) END DO ! DO KTH=1,KTHM 300 CONTINUE END SUBROUTINE BMJINIT !######################################################################## !######################################################################## !######### ######### !######### SUBROUTINE spline ######### !######### ######### !######### Adapted by ######### !######### Center for Analysis and Prediction of Storms ######### !######### University of Oklahoma ######### !######### ######### !######################################################################## !######################################################################## SUBROUTINE SPLINE(JTBX,NOLD,XOLD,YOLD,Y2,NNEW,XNEW,YNEW,P,Q) 6 !------------------------------------------------------------------------ ! ! PURPOSE: ! ! 1-D cubic spline fitting subroutine. ! !------------------------------------------------------------------------ ! ! AUTHOR: Z. Janjic ! ! MODIFICATIONS: ! ! Eric Kemp, 24 September 2001 ! Reformatted code. However, the overall "spagetti" structure of ! the code has been left undisturbed. ! !------------------------------------------------------------------------ ! ! Original documentation: ! ! ****************************************************************** ! * * ! * THIS IS A ONE-DIMENSIONAL CUBIC SPLINE FITTING ROUTINE * ! * PROGRAMED FOR A SMALL SCALAR MACHINE. * ! * * ! * PROGRAMER Z. JANJIC * ! * * ! * NOLD - NUMBER OF GIVEN VALUES OF THE FUNCTION. MUST BE GE 3. * ! * XOLD - LOCATIONS OF THE POINTS AT WHICH THE VALUES OF THE * ! * FUNCTION ARE GIVEN. MUST BE IN ASCENDING ORDER. * ! * YOLD - THE GIVEN VALUES OF THE FUNCTION AT THE POINTS XOLD. * ! * Y2 - THE SECOND DERIVATIVES AT THE POINTS XOLD. IF NATURAL * ! * SPLINE IS FITTED Y2(1)=0. AND Y2(NOLD)=0. MUST BE * ! * SPECIFIED. * ! * NNEW - NUMBER OF VALUES OF THE FUNCTION TO BE CALCULATED. * ! * XNEW - LOCATIONS OF THE POINTS AT WHICH THE VALUES OF THE * ! * FUNCTION ARE CALCULATED. XNEW(K) MUST BE GE XOLD(1) * ! * AND LE XOLD(NOLD). * ! * YNEW - THE VALUES OF THE FUNCTION TO BE CALCULATED. * ! * P, Q - AUXILIARY VECTORS OF THE LENGTH NOLD-2. * ! * * ! ****************************************************************** ! !------------------------------------------------------------------------ ! ! Force explicit declarations. ! !------------------------------------------------------------------------ IMPLICIT NONE !------------------------------------------------------------------------ ! ! Declare arguments. ! !------------------------------------------------------------------------ INTEGER,INTENT(IN) :: JTBX,NNEW,NOLD REAL,DIMENSION(JTBX),INTENT(IN) :: XNEW,XOLD,YOLD REAL,DIMENSION(JTBX),INTENT(INOUT) :: P,Q,Y2 REAL,DIMENSION(JTBX),INTENT(OUT) :: YNEW !------------------------------------------------------------------------ ! ! Declare internal variables. ! !------------------------------------------------------------------------ INTEGER :: K,K1,K2,KOLD,NOLDM1 REAL :: AK,BK,CK,DEN,DX,DXC,DXL,DXR,DYDXL,DYDXR & ,RDX,RTDXC,X,XK,XSQ,Y2K,Y2KP1 !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NOLDM1=NOLD-1 DXL=XOLD(2)-XOLD(1) DXR=XOLD(3)-XOLD(2) DYDXL=(YOLD(2)-YOLD(1))/DXL DYDXR=(YOLD(3)-YOLD(2))/DXR RTDXC=0.5/(DXL+DXR) P(1)= RTDXC*(6.*(DYDXR-DYDXL)-DXL*Y2(1)) Q(1)=-RTDXC*DXR IF (NOLD.EQ.3) GO TO 150 ! Skip down K=3 100 DXL=DXR DYDXL=DYDXR DXR=XOLD(K+1)-XOLD(K) DYDXR=(YOLD(K+1)-YOLD(K))/DXR DXC=DXL+DXR DEN=1./(DXL*Q(K-2)+DXC+DXC) P(K-1)= DEN*(6.*(DYDXR-DYDXL)-DXL*P(K-2)) Q(K-1)=-DEN*DXR K=K+1 IF (K.LT.NOLD) GO TO 100 ! Jump back up 150 K=NOLDM1 200 Y2(K)=P(K-1)+Q(K-1)*Y2(K+1) K=K-1 IF (K.GT.1) GO TO 200 ! Jump back up K1=1 300 XK=XNEW(K1) DO 400 K2=2,NOLD IF (XOLD(K2).GT.XK) THEN KOLD=K2-1 GO TO 450 ! Exit loop, jump down END IF ! IF (XOLD(K2).GT.XK) THEN 400 CONTINUE ! DO 400 K2=2,NOLD YNEW(K1)=YOLD(NOLD) GO TO 600 ! Jump down 450 IF (K1.EQ.1) GO TO 500 ! Jump down IF (K.EQ.KOLD) GO TO 550 ! Jump down 500 K=KOLD Y2K=Y2(K) Y2KP1=Y2(K+1) DX=XOLD(K+1)-XOLD(K) RDX=1./DX AK=.1666667*RDX*(Y2KP1-Y2K) BK=0.5*Y2K CK=RDX*(YOLD(K+1)-YOLD(K))-.1666667*DX*(Y2KP1+Y2K+Y2K) 550 X=XK-XOLD(K) XSQ=X*X YNEW(K1)=AK*XSQ*X+BK*XSQ+CK*X+YOLD(K) 600 K1=K1+1 IF (K1.LE.NNEW) GO TO 300 ! Jump up END SUBROUTINE SPLINE !------------------------------------------------------------------------ ! ! End subroutine declarations. ! !------------------------------------------------------------------------ END MODULE MODULE_CU_BMJ