!-------------------------------------- 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 --------------------------------------
***S/P TABULATE_XCW - PART OF THE ISCCP CLOUD SIMULATOR PACKAGE
*
SUBROUTINE TABULATE_XCW() 1,1
*Author
* Jason Cole, MSC/Cloud Physics (Summer 2005)
*Revisions
* 001 ...
*Object
* This subroutine tabulates
* XCW = ratio of cloud condensate mixing ratio (QC)
* to its mean value as a function of cumulative
* *** cumulative probability (N1 points)
* *** relative standrad deviation of CWC
* (N2 points, presently 0.100, 0.125, ....)
* Either a beta (DIST=1.0) or
* a gamma distribution (DIST=2.0) can be used
#include "impnone.cdk"
#include "mcica.cdk"
C Local variables
INTEGER I,J
REAL AVG, STD, A, B, BG, C, D, R, Q, BETA, ALPHA, PROB_MIN,
1 PROB, DIST, A_BETA, A_GAMMA
C Loop over standard deviations
DO 10 J=1,N2
c mean and std dev
AVG = 1.0
STD = 0.025*(J+3)
c
c upper and lower limits for beta dist (A and B).
c upper limit for gamma dist (BG).
c BG superficially optimized by P. Raisanen (July 2002?)
C
A = 0.0
B = (5. + 5.*STD**2)*AVG
BG = (5. + 5.*STD**2)*AVG
c
c using mean and std dev, determine parameters of
c beta dist and gamma dist
c
C = (AVG - A) / (B - AVG)
D = ((B - A) / STD)**2
R = C * (D - 2.0 - C) / (C * (C**2 + 3.0 * C + 3.0) + 1.0)
Q = C * R
BETA = AVG / STD**2
ALPHA = AVG * BETA
PROB_MIN = 0.0
c - PROB = cumulative frequency
c - A_BETA and A_GAMMA = returned value given PROB
c
DO 20 I=1,N1
PROB = REAL(I-1.)/REAL(N1-1.)
C DIST = 1.0 ! <<<<< BETA distribution >>>>>
C
C CALL ROOT_LIMIT (DIST, Q, R, A, B, ALPHA, BETA, PROB_MIN,
C + PROB, A_BETA)
C XCW(I,J) = A_BETA
DIST = 2.0 ! <<<<< GAMMA distribution >>>>>
CALL ROOT_LIMIT
(DIST, Q, R, A, BG, ALPHA, BETA, PROB_MIN,
+ PROB, A_GAMMA)
XCW(I,J) = A_GAMMA
20 CONTINUE
10 CONTINUE
RETURN
END
C~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SUBROUTINE ROOT_LIMIT (DIST, Q, R, A, B, ALPHA, BETA, 1,6
+ A_PROB, C_PROB, VALUE)
PARAMETER (XACC = 0.00001, JMAX = 10000, EPS = 1.0E-5)
C PARAMETER (XACC = 0.005, JMAX = 1000, EPS = 1.0E-5)
IF (DIST .EQ. 1.0) THEN
X2 = (B - A) / (B - A)
FMID = BETAI
(Q,R,X2) - A_PROB
X1 = (A+EPS - A) / (B - A)
FF = BETAI
(Q,R,X1) - A_PROB
ELSE IF (DIST .EQ. 2.0) THEN
X2 = B * BETA
FMID = GAMMP
(ALPHA,X2) - A_PROB
X1 = (EPS) * BETA
FF = GAMMP
(ALPHA,X1) - A_PROB
END IF
c IF (FF * FMID .GE. 0.0) PAUSE
c IF (FF .LT. 0.0)THEN
RTBIS = X1
DX = X2 - X1
c ELSE
c RTBIS = X2
c DX = X1 - X2
c ENDIF
DO 11 J=1,JMAX
DX = DX * .50
XMID = RTBIS + DX
X = XMID
IF (DIST .EQ. 1.0) THEN
FMID = BETAI
(Q,R,X) - C_PROB
ELSE IF (DIST .EQ. 2.0) THEN
FMID = GAMMP
(ALPHA,X) - C_PROB
END IF
IF (FMID .LT. 0.0) RTBIS = XMID
IF (ABS(DX) .LT. XACC .OR. FMID .EQ. 0.0) go to 15
11 CONTINUE
WRITE(*,*) 'too many bisections'
15 CONTINUE
IF (DIST .EQ. 1.0) THEN
VALUE = RTBIS * (B - A) + A
ELSE IF (DIST .EQ. 2.0) THEN
VALUE = RTBIS / BETA
END IF
RETURN
END
C~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FUNCTION BETA_FTN(z,w),3
REAL beta_ftn,w,z
CU USES gammln
REAL gammln
beta_ftn=exp(gammln
(z)+gammln
(w)-gammln
(z+w))
return
END
C~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FUNCTION gammp(a,x) 4,4
REAL a,gammp,x
CU USES gcf,gser
REAL gammcf,gamser,gln
if(x.lt.0..or.a.le.0.) WRITE(*,*) 'bad arguments in gammp'
if(x.lt.a+1.)then
call gser
(gamser,a,x,gln)
gammp=gamser
else
call gcf
(gammcf,a,x,gln)
gammp=1.-gammcf
endif
return
END
C~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SUBROUTINE gcf(gammcf,a,x,gln) 1,1
INTEGER ITMAX
REAL a,gammcf,gln,x,EPS,FPMIN
PARAMETER (ITMAX=100,EPS=3.e-7,FPMIN=1.e-30)
CU USES gammln
INTEGER i
REAL an,b,c,d,del,h,gammln
gln=gammln
(a)
b=x+1.-a
c=1./FPMIN
d=1./b
h=d
do 11 i=1,ITMAX
an=-i*(i-a)
b=b+2.
d=an*d+b
if(abs(d).lt.FPMIN)d=FPMIN
c=b+an/c
if(abs(c).lt.FPMIN)c=FPMIN
d=1./d
del=d*c
h=h*del
if(abs(del-1.).lt.EPS)goto 1
11 continue
WRITE(*,*) 'a too large, ITMAX too small in gcf'
1 gammcf=exp(-x+a*log(x)-gln)*h
return
END
C~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SUBROUTINE gser(gamser,a,x,gln) 2,2
INTEGER ITMAX
REAL a,gamser,gln,x,EPS
PARAMETER (ITMAX=100,EPS=3.e-7)
CU USES gammln
INTEGER n
REAL ap,del,sum,gammln
gln=gammln
(a)
if(x.le.0.)then
if(x.lt.0.) WRITE(*,*) 'x < 0 in gser'
gamser=0.
return
endif
ap=a
sum=1./a
del=sum
do 11 n=1,ITMAX
ap=ap+1.
del=del*x/ap
sum=sum+del
if(abs(del).lt.abs(sum)*EPS)goto 1
11 continue
WRITE(*,*) 'a too large, ITMAX too small in gser'
1 gamser=sum*exp(-x+a*log(x)-gln)
return
END
C~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FUNCTION gammln(xx) 11
REAL gammln,xx
INTEGER j
DOUBLE PRECISION ser,stp,tmp,x,y,cof(6)
SAVE cof,stp
DATA cof,stp/76.18009172947146d0,-86.50532032941677d0,
*24.01409824083091d0,-1.231739572450155d0,.1208650973866179d-2,
*-.5395239384953d-5,2.5066282746310005d0/
x=xx
y=x
tmp=x+5.5d0
tmp=(x+0.5d0)*log(tmp)-tmp
ser=1.000000000190015d0
do 11 j=1,6
y=y+1.d0
ser=ser+cof(j)/y
11 continue
gammln=tmp+log(stp*ser/x)
return
END
C~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FUNCTION betai(a,b,x) 3,5
REAL betai,a,b,x
CU USES betacf,gammln
REAL bt,betacf,gammln
if(x.lt.0..or.x.gt.1.)WRITE(*,*) 'bad argument x in betai'
if(x.eq.0..or.x.eq.1.)then
bt=0.
else
bt=exp(gammln
(a+b)-gammln
(a)-gammln
(b)+a*log(x)+b*log(1.-x))
endif
if(x.lt.(a+1.)/(a+b+2.))then
betai=bt*betacf
(a,b,x)/a
return
else
betai=1.-bt*betacf
(b,a,1.-x)/b
return
endif
END
C~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FUNCTION betacf(a,b,x) 2
INTEGER MAXIT
REAL betacf,a,b,x,EPS,FPMIN
PARAMETER (MAXIT=100,EPS=3.e-7,FPMIN=1.e-30)
INTEGER m,m2
REAL aa,c,d,del,h,qab,qam,qap
qab=a+b
qap=a+1.
qam=a-1.
c=1.
d=1.-qab*x/qap
if(abs(d).lt.FPMIN)d=FPMIN
d=1./d
h=d
do 11 m=1,MAXIT
m2=2*m
aa=m*(b-m)*x/((qam+m2)*(a+m2))
d=1.+aa*d
if(abs(d).lt.FPMIN)d=FPMIN
c=1.+aa/c
if(abs(c).lt.FPMIN)c=FPMIN
d=1./d
h=h*d*c
aa=-(a+m)*(qab+m)*x/((a+m2)*(qap+m2))
d=1.+aa*d
if(abs(d).lt.FPMIN)d=FPMIN
c=1.+aa/c
if(abs(c).lt.FPMIN)c=FPMIN
d=1./d
del=d*c
h=h*del
if(abs(del-1.).lt.EPS)goto 1
11 continue
WRITE(*,*) 'a or b too big, or MAXIT too small in betacf'
1 betacf=h
return
END
*******************************************************************