/wrfv2_fire/phys/module_bl_acm.F
FORTRAN Legacy | 1210 lines | 722 code | 153 blank | 335 comment | 1 complexity | 596dc859b7d9c664a4454fbd0a5733c4 MD5 | raw file
Possible License(s): AGPL-1.0
- !WRF:MODEL_LAYER:PHYSICS
- !
- MODULE module_bl_acm
- ! USE module_model_constants
- REAL, PARAMETER :: RIC = 0.25 ! critical Richardson number
- REAL, PARAMETER :: CRANKP = 0.5 ! CRANK-NIC PARAMETER
- CONTAINS
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- SUBROUTINE ACMPBL(XTIME, DTPBL, ZNW, SIGMAH, &
- U3D, V3D, PP3D, DZ8W, TH3D, T3D, &
- QV3D, QC3D, QI3D, RR3D, &
- UST, HFX, QFX, TSK, &
- PSFC, EP1, G, &
- ROVCP, RD, CPD, &
- PBLH, KPBL2D, REGIME, &
- GZ1OZ0, WSPD, PSIM, MUT, &
- RUBLTEN, RVBLTEN, RTHBLTEN, &
- RQVBLTEN, RQCBLTEN, RQIBLTEN, &
- ids,ide, jds,jde, kds,kde, &
- ims,ime, jms,jme, kms,kme, &
- its,ite, jts,jte, kts,kte)
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- ! THIS MODULE COMPUTES VERTICAL MIXING IN AND ABOVE THE PBL ACCORDING TO
- ! THE ASYMMETRICAL CONVECTIVE MODEL, VERSION 2 (ACM2), WHICH IS A COMBINED
- ! LOCAL NON-LOCAL CLOSURE SCHEME BASED ON THE ORIGINAL ACM (PLEIM AND CHANG 1992)
- !
- ! REFERENCES:
- ! Pleim (2007) A combined local and non-local closure model for the atmospheric
- ! boundary layer. Part1: Model description and testing.
- ! JAMC, 46, 1383-1395
- ! Pleim (2007) A combined local and non-local closure model for the atmospheric
- ! boundary layer. Part2: Application and evaluation in a mesoscale
- ! meteorology model. JAMC, 46, 1396-1409
- !
- ! REVISION HISTORY:
- ! AX 3/2005 - developed WRF version based on the MM5 PX LSM
- ! RG and JP 7/2006 - Finished WRF adaptation
- ! JP 12/2011 12/2011 - ACM2 modified so it's not dependent on first layer thickness.
- !
- !**********************************************************************
- ! ARGUMENT LIST:
- !
- !... Inputs:
- !-- XTIME Time since simulation start (min)
- !-- DTPBL PBL time step
- !-- ZNW Sigma at full layer
- !-- SIGMAH Sigma at half layer
- !-- U3D 3D u-velocity interpolated to theta points (m/s)
- !-- V3D 3D v-velocity interpolated to theta points (m/s)
- !-- PP3D Pressure at half levels (Pa)
- !-- DZ8W dz between full levels (m)
- !-- TH3D Potential Temperature (K)
- !-- T3D Temperature (K)
- !-- QV3D 3D water vapor mixing ratio (Kg/Kg)
- !-- QC3D 3D cloud mixing ratio (Kg/Kg)
- !-- QI3D 3D ice mixing ratio (Kg/Kg)
- !-- RR3D 3D dry air density (kg/m^3)
- !-- UST Friction Velocity (m/s)
- !-- HFX Upward heat flux at the surface (w/m^2)
- !-- QFX Upward moisture flux at the surface (Kg/m^2/s)
- !-- TSK Surface temperature (K)
- !-- PSFC Pressure at the surface (Pa)
- !-- EP1 Constant for virtual temperature (r_v/r_d-1) (dimensionless)
- !-- G Gravity (m/s^2)
- !-- ROVCP r/cp
- !-- RD gas constant for dry air (j/kg/k)
- !-- CPD heat capacity at constant pressure for dry air (j/kg/k)
- !-- GZ1OZ0 log(z/z0) where z0 is roughness length
- !-- WSPD wind speed at lowest model level (m/s)
- !-- PSIM similarity stability function for momentum
- !-- MUT Total Mu : Psfc - Ptop
-
- !-- 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
- !-- 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
- !
- !... Outputs:
- !-- PBLH PBL height (m)
- !-- KPBL2D K index for PBL layer
- !-- REGIME Flag indicating PBL regime (stable, unstable, etc.)
- !-- RUBLTEN U tendency due to PBL parameterization (m/s^2)
- !-- RVBLTEN V tendency due to PBL parameterization (m/s^2)
- !-- RTHBLTEN Theta tendency due to PBL parameterization (K/s)
- !-- RQVBLTEN Qv tendency due to PBL parameterization (kg/kg/s)
- !-- RQCBLTEN Qc tendency due to PBL parameterization (kg/kg/s)
- !-- RQIBLTEN Qi tendency due to PBL parameterization (kg/kg/s)
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- IMPLICIT NONE
- !.......Arguments
- ! DECLARATIONS - INTEGER
- INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde, &
- ims,ime, jms,jme, kms,kme, &
- its,ite, jts,jte, kts,kte, XTIME
- ! DECLARATIONS - REAL
- REAL, INTENT(IN) :: DTPBL, EP1, &
- G, ROVCP, RD, CPD
- REAL, DIMENSION( kms:kme ), INTENT(IN) :: ZNW, SIGMAH
- REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), &
- INTENT(IN) :: U3D, V3D, &
- PP3D, DZ8W, T3D, &
- QV3D, QC3D, QI3D, &
- RR3D, TH3D
- REAL, DIMENSION( ims:ime, jms:jme ), INTENT(IN) :: PSIM, GZ1OZ0, &
- HFX, QFX, TSK, &
- PSFC, WSPD, MUT
- REAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: PBLH, REGIME, UST
- REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), &
- INTENT(INOUT) :: RUBLTEN, RVBLTEN, &
- RTHBLTEN, RQVBLTEN, &
- RQCBLTEN, RQIBLTEN
- INTEGER, DIMENSION( ims:ime, jms:jme ), INTENT(OUT ) :: KPBL2D
- !... Local Variables
- !... Integer
- INTEGER :: J, K
- !... Real
- REAL, DIMENSION( kts:kte ) :: DSIGH, DSIGHI, DSIGFI
- REAL, DIMENSION( 0:kte ) :: SIGMAF
- REAL RDT
- REAL, PARAMETER :: KARMAN = 0.4
- !...
- RDT = 1.0 / DTPBL
- DO K = 1, kte
- SIGMAF(K-1) = ZNW(K)
- ENDDO
- SIGMAF(kte) = 0.0
- DO K = 1, kte
- DSIGH(K) = SIGMAF(K) - SIGMAF(K-1)
- DSIGHI(K) = 1.0 / DSIGH(K)
- ENDDO
- DO K = kts,kte-1
- DSIGFI(K) = 1.0 / (SIGMAH(K+1) - SIGMAH(K))
- ENDDO
- DSIGFI(kte) = DSIGFI(kte-1)
-
- DO j = jts,jte
- CALL ACM2D(j=J,xtime=XTIME, dtpbl=DTPBL, sigmaf=SIGMAF, sigmah=SIGMAH &
- ,dsigfi=DSIGFI,dsighi=DSIGHI,dsigh=DSIGH &
- ,us=u3d(ims,kms,j),vs=v3d(ims,kms,j) &
- ,theta=th3d(ims,kms,j),tt=t3d(ims,kms,j) &
- ,qvs=qv3d(ims,kms,j),qcs=qc3d(ims,kms,j) &
- ,qis=qi3d(ims,kms,j),dzf=DZ8W(ims,kms,j) &
- ,densx=RR3D(ims,kms,j) &
- ,utnp=rublten(ims,kms,j),vtnp=rvblten(ims,kms,j) &
- ,ttnp=rthblten(ims,kms,j),qvtnp=rqvblten(ims,kms,j) &
- ,qctnp=rqcblten(ims,kms,j),qitnp=rqiblten(ims,kms,j) &
- ,cpd=cpd,g=g,rovcp=rovcp,rd=rd,rdt=rdt &
- ,psfcpa=psfc(ims,j),ust=ust(ims,j) &
- ,pbl=pblh(ims,j) &
- ,regime=regime(ims,j),psim=psim(ims,j) &
- ,hfx=hfx(ims,j),qfx=qfx(ims,j) &
- ,tg=tsk(ims,j),gz1oz0=gz1oz0(ims,j) &
- ,wspd=wspd(ims,j) ,klpbl=kpbl2d(ims,j) &
- ,mut=mut(ims,j) &
- ,ep1=ep1,karman=karman &
- ,ids=ids,ide=ide, jds=jds,jde=jde, kds=kds,kde=kde &
- ,ims=ims,ime=ime, jms=jms,jme=jme, kms=kms,kme=kme &
- ,its=its,ite=ite, jts=jts,jte=jte, kts=kts,kte=kte )
- ENDDO
- END SUBROUTINE ACMPBL
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- SUBROUTINE ACM2D(j,XTIME, DTPBL, sigmaf, sigmah &
- ,dsigfi,dsighi,dsigh &
- ,us,vs,theta,tt,qvs,qcs,qis &
- ,dzf,densx,utnp,vtnp,ttnp,qvtnp,qctnp,qitnp &
- ,cpd,g,rovcp,rd,rdt,psfcpa,ust &
- ,pbl,regime,psim &
- ,hfx,qfx,tg,gz1oz0,wspd ,klpbl &
- ,mut &
- ,ep1,karman &
- ,ids,ide, jds,jde, kds,kde &
- ,ims,ime, jms,jme, kms,kme &
- ,its,ite, jts,jte, kts,kte )
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- IMPLICIT NONE
- !.......Arguments
- !... Real
- REAL, DIMENSION( 0:kte ), INTENT(IN) :: SIGMAF
- REAL, DIMENSION( kms:kme ), INTENT(IN) :: SIGMAH
- REAL, DIMENSION( kts:kte ), INTENT(IN) :: DSIGH, DSIGHI, DSIGFI
- REAL , INTENT(IN) :: DTPBL, G, RD,ep1,karman,CPD,ROVCP,RDT
- REAL , DIMENSION( ims:ime ), INTENT(INOUT) :: PBL, UST
-
- REAL , DIMENSION( ims:ime, kms:kme ), INTENT(IN) :: US,VS, THETA, TT, &
- QVS, QCS, QIS, DENSX
- REAL, DIMENSION( ims:ime, kms:kme ), intent(in) :: DZF
- REAL, DIMENSION( ims:ime, kms:kme ), intent(inout) :: utnp, &
- vtnp, &
- ttnp, &
- qvtnp, &
- qctnp, &
- qitnp
- real, dimension( ims:ime ), intent(in ) :: psfcpa
- real, dimension( ims:ime ), intent(in ) :: tg
- real, dimension( ims:ime ), intent(inout) :: regime
- real, dimension( ims:ime ), intent(in) :: wspd, psim, gz1oz0
- real, dimension( ims:ime ), intent(in) :: hfx, qfx
- real, dimension( ims:ime ), intent(in) :: mut
- !... Integer
- INTEGER, DIMENSION( ims:ime ), INTENT(OUT):: KLPBL
- INTEGER, INTENT(IN) :: XTIME
- integer, intent(in ) :: ids,ide, jds,jde, kds,kde, &
- ims,ime, jms,jme, kms,kme, &
- its,ite, jts,jte, kts,kte, j
- !--------------------------------------------------------------------
- !--Local
- INTEGER I, K
- INTEGER :: KPBLHT
- INTEGER, DIMENSION( its:ite ) :: KPBLH, NOCONV
- !... Real
- REAL :: TVCON, WSS, TCONV, TH1, TOG, DTMP, WSSQ
- REAL :: psix, THV1
- REAL, DIMENSION( its:ite ) :: FINT, PSTAR, CPAIR
- REAL, DIMENSION( its:ite, kts:kte ) :: THETAV, RIB, &
- EDDYZ, UX, VX, THETAX, &
- QVX, QCX, QIX, ZA
- REAL, DIMENSION( its:ite, 0:kte ) :: ZF
- REAL, DIMENSION( its:ite) :: WST, TST, QST, USTM, TSTV
- REAL, DIMENSION( its:ite ) :: PBLSIG, MOL
- REAL :: FINTT, ZMIX, UMIX, VMIX
- REAL :: TMPFX, TMPVTCON, TMPP, TMPTHS, TMPTH1, TMPVCONV, WS1, DTH
- REAL :: A,TST12,RL,ZFUNC
- ! REAL, PARAMETER :: KARMAN = 0.4
- !... Integer
- INTEGER :: KL, jtf, ktf, itf, KMIX, KSRC
- !...
- character*256 :: message
- !-----initialize vertical tendencies and
- DO i = its,ite
- DO k = kts,kte
- utnp(i,k) = 0.
- vtnp(i,k) = 0.
- ttnp(i,k) = 0.
- ENDDO
- ENDDO
- DO k = kts,kte
- DO i = its,ite
- qvtnp(i,k) = 0.
- ENDDO
- ENDDO
- DO k = kts,kte
- DO i = its,ite
- qctnp(i,k) = 0.
- qitnp(i,k) = 0.
- ENDDO
- ENDDO
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !!! Compute Micromet Scaling variables, not availiable in WRF for ACM
- DO I = its,ite
- CPAIR(I) = CPD * (1.0 + 0.84 * QVS(I,1)) ! J/(K KG)
- TMPFX = HFX(I) / (cpair(i) * DENSX(I,1))
- TMPVTCON = 1.0 + EP1 * QVS(I,1) ! COnversion factor for virtual temperature
- WS1 = SQRT(US(I,1)**2 + VS(I,1)**2) ! Level 1 wind speed
- TST(I) = -TMPFX / UST(I)
- QST(I) = -QFX(I) / (UST(I)*DENSX(I,1))
- USTM(I) = UST(I) * WS1 / wspd(i)
- THV1 = TMPVTCON * THETA(I,1)
- TSTV(I) = TST(I)*TMPVTCON + THV1*EP1*QST(I)
- IF(ABS(TSTV(I)).LT.1.0E-6) THEN
- TSTV(I) = SIGN(1.0E-6,TSTV(I))
- ENDIF
- MOL(I) = THV1 * UST(i)**2/(KARMAN*G*TSTV(I))
- WST(I) = UST(I) * (PBL(I)/(KARMAN*ABS(MOL(I)))) ** 0.333333
- PSTAR(I) = MUT(I)/1000. ! P* in cb
- ENDDO
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !... Compute PBL height
- !... compute the height of full- and half-sigma level above ground level
- DO I = its,ite
- ZF(I,0) = 0.0
- KLPBL(I) = 1
- ENDDO
- DO K = kts, kte
- DO I = its,ite
- ZF(I,K) = DZF(I,K) + ZF(I,K-1)
- ZA(I,K) = 0.5 * (ZF(I,K) + ZF(I,K-1))
- ENDDO
- ENDDO
- DO K = kts, kte
- DO I = its,ite
- TVCON = 1.0 + EP1 * QVS(I,K)
- THETAV(I,K) = THETA(I,K) * TVCON
- ENDDO
- ENDDO
- !... COMPUTE PBL WHERE RICHARDSON NUMBER = RIC (0.25) HOLTSLAG ET AL 1990
- DO 100 I = its,ite
- DO K = 1,kte
- KSRC = K
- IF (SIGMAF(K).lT.0.9955) GO TO 69
- ENDDO
- 69 CONTINUE
- TH1 = 0.0
- DO K = 1,KSRC
- TH1 = TH1 + THETAV(I,K)
- ENDDO
- TH1 = TH1/KSRC
- IF(MOL(I).LT.0.0 .AND. XTIME.GT.1) then
- WSS = (UST(I) ** 3 + 0.6 * WST(I) ** 3) ** 0.33333
- TCONV = -8.5 * UST(I) * TSTV(I) / WSS
- TH1 = TH1 + TCONV
- ENDIF
- 99 KMIX = 1
- DO K = 1,kte
- DTMP = THETAV(I,K) - TH1
- IF (DTMP.LT.0.0) KMIX = K
- ENDDO
- IF(KMIX.GT.1) THEN
- FINTT = (TH1 - THETAV(I,KMIX)) / (THETAV(I,KMIX+1) &
- - THETAV(I,KMIX))
- ZMIX = FINTT * (ZA(I,KMIX+1)-ZA(I,KMIX)) + ZA(I,KMIX)
- UMIX = FINTT * (US(I,KMIX+1)-US(I,KMIX)) + US(I,KMIX)
- VMIX = FINTT * (VS(I,KMIX+1)-VS(I,KMIX)) + VS(I,KMIX)
- ELSE
- ZMIX = ZA(I,1)
- UMIX = US(I,1)
- VMIX = VS(I,1)
- ENDIF
- DO K = KMIX,kte
- DTMP = THETAV(I,K) - TH1
- TOG = 0.5 * (THETAV(I,K) + TH1) / G
- WSSQ = (US(I,K)-UMIX)**2 &
- + (VS(I,K)-VMIX)**2
- IF (KMIX == 1) WSSQ = WSSQ + 100.*UST(I)*UST(I)
- WSSQ = MAX( WSSQ, 0.1 )
- RIB(I,K) = ABS(ZA(I,K)-ZMIX) * DTMP / (TOG * WSSQ)
- IF (RIB(I,K) .GE. RIC) GO TO 201
- ENDDO
- write (message, *)' RIBX never exceeds RIC, RIB(i,kte) = ',rib(i,5), &
- ' THETAV(i,1) = ',thetav(i,1),' MOL=',mol(i), &
- ' TCONV = ',TCONV,' WST = ',WST(I), &
- ' KMIX = ',kmix,' UST = ',UST(I), &
- ' TST = ',TST(I),' U,V = ',US(I,1),VS(I,1), &
- ' I,J=',I,J
- CALL wrf_error_fatal ( message )
- 201 CONTINUE
- KPBLH(I) = K
- 100 CONTINUE
- DO I = its,ite
- IF (KPBLH(I) .NE. 1) THEN
- !---------INTERPOLATE BETWEEN LEVELS -- jp 7/93
- FINT(I) = (RIC - RIB(I,KPBLH(I)-1)) / (RIB(I,KPBLH(I)) - &
- RIB(I,KPBLH(I)-1))
- IF (FINT(I) .GT. 0.5) THEN
- KPBLHT = KPBLH(I)
- FINT(I) = FINT(I) - 0.5
- ELSE
- KPBLHT = KPBLH(I) - 1
- FINT(I) = FINT(I) + 0.5
- ENDIF
- PBL(I) = FINT(I) * (ZF(I,KPBLHT) - ZF(I,KPBLHT-1)) + &
- ZF(I,KPBLHT-1)
- KLPBL(I) = KPBLHT
- PBLSIG(I) = FINT(I) * DSIGH(KPBLHT) + SIGMAF(KPBLHT-1) ! sigma at PBL height
- ELSE
- KLPBL(I) = 1
- PBL(I) = ZF(I,1)
- PBLSIG(I) = SIGMAF(1)
- ENDIF
- ENDDO
- DO I = its,ite
- NOCONV(I) = 0
-
- ! Check for CBL and identify conv. vs. non-conv cells
- IF (PBL(I) / MOL(I) .LT. -0.02 .AND. KLPBL(I) .GT. 3 &
- .AND. THETAV(I,1) .GT. THETAV(I,2) .AND. XTIME .GT. 1) THEN
- NOCONV(I) = 1
- REGIME(I) = 4.0 ! FREE CONVECTIVE - ACM
- ENDIF
- ENDDO
- !... Calculate Kz
- CALL EDDYX(DTPBL, ZF, ZA, MOL, PBL, UST, &
- US, VS, TT, THETAV, DENSX, PSTAR, &
- QVS, QCS, QIS, DSIGFI, G, RD, CPAIR, &
- EDDYZ, its,ite, kts,kte,ims,ime, kms,kme)
- CALL ACM(DTPBL, PSTAR, NOCONV, SIGMAF, DSIGH, DSIGHI, J, &
- KLPBL, PBL, PBLSIG, MOL, UST, &
- TST, QST, USTM, EDDYZ, DENSX, &
- US, VS, THETA, QVS, QCS, QIS, &
- UX, VX, THETAX, QVX, QCX, QIX, &
- ids,ide, jds,jde, kds,kde, &
- ims,ime, jms,jme, kms,kme, &
- its,ite, jts,jte, kts,kte)
- !... Calculate tendency due to PBL parameterization
- DO K = kts, kte
- DO I = its, ite
- UTNP(I,K) = UTNP(I,K) + (UX(I,K) - US(I,K)) * RDT
- VTNP(I,K) = VTNP(I,K) + (VX(I,K) - VS(I,K)) * RDT
- TTNP(I,K) = TTNP(I,K) + (THETAX(I,K) - THETA(I,K)) * RDT
- QVTNP(I,K) = QVTNP(I,K) + (QVX(I,K) - QVS(I,K)) * RDT
- QCTNP(I,K) = QCTNP(I,K) + (QCX(I,K) - QCS(I,K)) * RDT
- QITNP(I,K) = QITNP(I,K) + (QIX(I,K) - QIS(I,K)) * RDT
- ENDDO
- ENDDO
- END SUBROUTINE ACM2D
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- SUBROUTINE ACMINIT(RUBLTEN,RVBLTEN,RTHBLTEN,RQVBLTEN, &
- RQCBLTEN,RQIBLTEN,P_QI,P_FIRST_SCALAR, &
- restart, allowed_to_read , &
- ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte )
- !-----------------------------------------------------------------------
- !
- ! This subroutine is for preparing ACM PBL variables.
- ! Called from module_physics_init.F
- !
- ! REVISION HISTORY:
- ! AX 3/2005 - Originally developed
- !-----------------------------------------------------------------------
- ! ARGUMENT LIST:
- !
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- IMPLICIT NONE
- !
- LOGICAL , INTENT(IN) :: restart , allowed_to_read
- INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde, &
- ims, ime, jms, jme, kms, kme, &
- its, ite, jts, jte, kts, kte
- INTEGER , INTENT(IN) :: P_QI,P_FIRST_SCALAR
- ! REAL , DIMENSION( kms:kme ), INTENT(IN) :: SHALF
- REAL , DIMENSION( ims:ime , kms:kme , jms:jme ) , INTENT(OUT) :: &
- RUBLTEN, &
- RVBLTEN, &
- RTHBLTEN, &
- RQVBLTEN, &
- RQCBLTEN, &
- RQIBLTEN
- !... Local Variables
- INTEGER :: i, j, k, itf, jtf, ktf
- !
- 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
- RUBLTEN(i,k,j)=0.
- RVBLTEN(i,k,j)=0.
- RTHBLTEN(i,k,j)=0.
- RQVBLTEN(i,k,j)=0.
- RQCBLTEN(i,k,j)=0.
- ENDDO
- ENDDO
- ENDDO
- ENDIF
- IF (P_QI .ge. P_FIRST_SCALAR .and. .not.restart) THEN
- DO j=jts,jtf
- DO k=kts,ktf
- DO i=its,itf
- RQIBLTEN(i,k,j)=0.
- ENDDO
- ENDDO
- ENDDO
- ENDIF
- END SUBROUTINE acminit
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- !-------------------------------------------------------------------
- SUBROUTINE EDDYX(DTPBL, ZF, ZA, MOL, PBL, UST, &
- US, VS, TT, THETAV, DENSX, PSTAR, &
- QVS, QCS, QIS, DSIGFI, G, RD, CPAIR, &
- EDDYZ, its,ite, kts,kte,ims,ime,kms,kme )
- !**********************************************************************
- ! Two methods for computing Kz:
- ! 1. Boundary scaling similar to Holtslag and Boville (1993)
- ! 2. Local Kz computed as function of local Richardson # and vertical
- ! wind shear, similar to LIU & CARROLL (1996)
- !
- !**********************************************************************
- !
- !-- DTPBL time step of the minor loop for the land-surface/pbl model
- !-- ZF height of full sigma level
- !-- ZA height of half sigma level
- !-- MOL Monin-Obukhov length in 1D form
- !-- PBL PBL height in 1D form
- !-- UST friction velocity U* in 1D form (m/s)
- !-- US U wind
- !-- VS V wind
- !-- TT temperature
- !-- THETAV potential virtual temperature
- !-- DENSX dry air density (kg/m^3)
- !-- PSTAR P*=Psfc-Ptop
- !-- QVS water vapor mixing ratio (Kg/Kg)
- !-- QCS cloud mixing ratio (Kg/Kg)
- !-- QIS ice mixing ratio (Kg/Kg)
- !-- DSIGFI inverse of sigma layer delta
- !-- G gravity
- !-- RD gas constant for dry air (j/kg/k)
- !-- CPAIR specific heat of moist air (M^2 S^-2 K^-1)
- !-- EDDYZ eddy diffusivity KZ
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- IMPLICIT NONE
- !.......Arguments
-
- !... Integer
- INTEGER, INTENT(IN) :: its,ite, kts,kte,ims,ime,kms,kme
- !... Real
- REAL , DIMENSION( ims:ime ), INTENT(IN) :: PBL, UST
- REAL , INTENT(IN) :: DTPBL, G, RD
- REAL , DIMENSION( kts:kte ), INTENT(IN) :: DSIGFI
- REAL , DIMENSION( its:ite ), INTENT(IN) :: MOL, PSTAR, CPAIR
- REAL , DIMENSION( ims:ime, kms:kme ), INTENT(IN) :: US,VS, TT, &
- QVS, QCS, QIS, DENSX
- REAL, DIMENSION( its:ite, kts:kte ), INTENT(IN) :: ZA, THETAV
- REAL, DIMENSION( its:ite, 0:kte ) , INTENT(IN) :: ZF
-
- REAL , DIMENSION( its:ite, kts:kte ), INTENT(OUT) :: EDDYZ
- !.......Local variables
- !... Integer
- INTEGER :: ILX, KL, KLM, K, I
- !... Real
- REAL :: ZOVL, PHIH, WT, ZSOL, ZFUNC, DZF, SS, GOTH, EDYZ
- REAL :: RI, QMEAN, TMEAN, XLV, ALPH, CHI, ZK, SQL, DENSF, KZO
- REAL :: FH
- !... Parameters
- REAL, PARAMETER :: RV = 461.5
- REAL, PARAMETER :: RC = 0.25
- REAL, PARAMETER :: RLAM = 80.0
- REAL, PARAMETER :: GAMH = 16.0 !15.0 ! Holtslag and Boville (1993)
- REAL, PARAMETER :: BETAH = 5.0 ! Holtslag and Boville (1993)
- REAL, PARAMETER :: KARMAN = 0.4
- REAL, PARAMETER :: EDYZ0 = 0.01 ! New Min Kz
- ! REAL, PARAMETER :: EDYZ0 = 0.1
- !-- IMVDIF imvdif=1 for moist adiabat vertical diffusion
- INTEGER, PARAMETER :: imvdif = 1
- !
- ILX = ite
- KL = kte
- KLM = kte - 1
-
- DO K = kts,KLM
- DO I = its,ILX
- EDYZ = 0.0
- ZOVL = 0.0
- DZF = ZA(I,K+1) - ZA(I,K)
- KZO = EDYZ0
- !--------------------------------------------------------------------------
- IF (ZF(I,K) .LT. PBL(I)) THEN
- ZOVL = ZF(I,K) / MOL(I)
- IF (ZOVL .LT. 0.0) THEN
- IF (ZF(I,K) .LT. 0.1 * PBL(I)) THEN
- PHIH = 1.0 / SQRT(1.0 - GAMH * ZOVL)
- WT = UST(I) / PHIH
- ELSE
- ZSOL = 0.1 * PBL(I) / MOL(I)
- PHIH = 1.0 / SQRT(1.0 - GAMH * ZSOL)
- WT = UST(I) / PHIH
- ENDIF
- ELSE IF (ZOVL .LT. 1.0) THEN
- PHIH = 1.0 + BETAH * ZOVL
- WT = UST(I) / PHIH
- ELSE
- PHIH = BETAH + ZOVL
- WT = UST(I) / PHIH
- ENDIF
- ZFUNC = ZF(I,K) * (1.0 - ZF(I,K) / PBL(I)) ** 2
- EDYZ = KARMAN * WT * ZFUNC
- ENDIF
- !--------------------------------------------------------------------------
- SS = ((US(I,K+1) - US(I,K)) ** 2 + (VS(I,K+1) - VS(I,K)) ** 2) &
- / (DZF * DZF) + 1.0E-9
- GOTH = 2.0 * G / (THETAV(I,K+1) + THETAV(I,K))
- RI = GOTH * (THETAV(I,K+1) - THETAV(I,K)) / (DZF * SS)
- !--------------------------------------------------------------------------
- ! Adjustment to vert diff in Moist air
- IF(imvdif.eq.1)then
- IF ((QCS(I,K)+QIS(I,K)) .GT. 0.01E-3 .OR. (QCS(I,K+1)+ &
- QIS(I,K+1)) .GT. 0.01E-3) THEN
- QMEAN = 0.5 * (QVS(I,K) + QVS(I,K+1))
- TMEAN = 0.5 * (TT(I,K) + TT(I,K+1))
- XLV = (2.501 - 0.00237 * (TMEAN - 273.15)) * 1.E6
- ALPH = XLV * QMEAN / RD / TMEAN
- CHI = XLV * XLV * QMEAN / CPAIR(I) / RV / TMEAN / TMEAN
- RI = (1.0 + ALPH) * (RI -G * G / SS / TMEAN / CPAIR(I) * &
- ((CHI - ALPH) / (1.0 + CHI)))
- ENDIF
- ENDIF
- !--------------------------------------------------------------------------
-
- ZK = 0.4 * ZF(I,K)
- SQL = (ZK * RLAM / (RLAM + ZK)) ** 2
-
- IF (RI .GE. 0.0) THEN
- IF (ZF(I,K).LT.PBL(I).AND.ZOVL.GT.0.0) THEN
- FH = MAX((1.-ZF(I,K)/PBL(I))**2,0.01) * PHIH **(-2)
- SQL = ZK ** 2
- ELSE
- FH = (MAX(1.-RI/RC,0.01))**2
- ENDIF
- EDDYZ(I,K) = KZO + SQRT(SS) * FH * SQL
- ELSE
- EDDYZ(I,K) = KZO + SQRT(SS * (1.0 - 25.0 * RI)) * SQL
- ENDIF
-
- IF(EDYZ.GT.EDDYZ(I,K)) THEN
- EDDYZ(I,K) = EDYZ
- ENDIF
- EDDYZ(I,K) = MIN(1000.0,EDDYZ(I,K))
- EDDYZ(I,K) = MAX(KZO,EDDYZ(I,K))
- DENSF = 0.5 * (DENSX(I,K+1) + DENSX(I,K))
- EDDYZ(I,K) = EDDYZ(I,K) * (DENSF * G / PSTAR(I)) ** 2 * &
- DTPBL * DSIGFI(K)*1E-6
- ENDDO ! for I loop
- ENDDO ! for k loop
- !
- DO I = its,ILX
- EDDYZ(I,KL) = 0.0 ! EDDYZ(I,KLM) -- changed jp 3/08
- ENDDO
- END SUBROUTINE EDDYX
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- !-------------------------------------------------------------------
- SUBROUTINE ACM (DTPBL, PSTAR, NOCONV, SIGMAF, DSIGH, DSIGHI, JX, &
- KLPBL, PBL, PBLSIG, MOL, UST, &
- TST, QST, USTM, EDDYZ, DENSX, &
- US, VS, THETA, QVS, QCS, QIS, &
- UX, VX, THETAX, QVX, QCX, QIX, &
- ids,ide, jds,jde, kds,kde, &
- ims,ime, jms,jme, kms,kme, &
- its,ite, jts,jte, kts,kte)
- !**********************************************************************
- ! PBL model called the Asymmetric Convective Model, Version 2 (ACM2)
- ! -- See top of module for summary and references
- !
- !---- REVISION HISTORY:
- ! AX 3/2005 - developed WRF version based on ACM2 in the MM5 PX LSM
- ! JP and RG 8/2006 - updates
- !
- !**********************************************************************
- ! ARGUMENTS:
- !-- DTPBL PBL time step
- !-- PSTAR Psurf - Ptop in cb
- !-- NOCONV If free convection =0, no; =1, yes
- !-- SIGMAF Sigma for full layer
- !-- DSIGH Sigma thickness
- !-- DSIGHI Inverse of sigma thickness
- !-- JX N-S index
- !-- KLPBL PBL level at K index
- !-- PBL PBL height in m
- !-- PBLSIG Sigma level for PBL
- !-- MOL Monin-Obukhov length in 1D form
- !-- UST U* in 1D form
- !-- TST Theta* in 1D form
- !-- QST Q* in 1D form
- !-- USTM U* for computation of momemtum flux
- !-- EDDYZ eddy diffusivity KZ
- !-- DENSX dry air density (kg/m^3)
- !-- US U wind
- !-- VS V wind
- !-- THETA potential temperature
- !-- QVS water vapor mixing ratio (Kg/Kg)
- !-- QCS cloud mixing ratio (Kg/Kg)
- !-- QIS ice mixing ratio (Kg/Kg)
- !-- UX new U wind
- !-- VX new V wind
- !-- THETAX new potential temperature
- !-- QVX new water vapor mixing ratio (Kg/Kg)
- !-- QCX new cloud mixing ratio (Kg/Kg)
- !-- QIX new ice mixing ratio (Kg/Kg)
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- IMPLICIT NONE
- !.......Arguments
- !... Integer
- INTEGER, INTENT(IN) :: ids,ide, jds,jde, kds,kde, &
- ims,ime, jms,jme, kms,kme, &
- its,ite, jts,jte, kts,kte, JX
- INTEGER, DIMENSION( its:ite ), INTENT(IN) :: NOCONV
- INTEGER, DIMENSION( ims:ime ), INTENT(IN) :: KLPBL
- !... Real
- REAL , DIMENSION( ims:ime ), INTENT(IN) :: PBL, UST
- REAL , INTENT(IN) :: DTPBL
- REAL , DIMENSION( its:ite ), INTENT(IN) :: PSTAR, PBLSIG, &
- MOL, TST, &
- QST, USTM
- REAL , DIMENSION( kts:kte ), INTENT(IN) :: DSIGHI, DSIGH
- REAL , DIMENSION( 0:kte ), INTENT(IN) :: SIGMAF
- REAL , DIMENSION( its:ite, kts:kte ), INTENT(INOUT) :: EDDYZ
- REAL , DIMENSION( ims:ime, kms:kme ), INTENT(IN) :: US,VS, THETA, &
- QVS, QCS, QIS, DENSX
- REAL , DIMENSION( its:ite, kts:kte ), INTENT(OUT) :: UX, VX, THETAX, &
- QVX, QCX, QIX
- !.......Local variables
- !... Parameters
- INTEGER, PARAMETER :: NSP = 6
- !
- !......ACM2 Parameters
- ! INTEGER, PARAMETER :: IFACM = 0
- !
- REAL, PARAMETER :: G1000 = 9.8 * 1.0E-3
- REAL, PARAMETER :: XX = 0.5 ! FACTOR APPLIED TO CONV MIXING TIME STEP
- REAL, PARAMETER :: KARMAN = 0.4
- !... Integer
- INTEGER :: ILX, KL, KLM, I, K, NSPX, NLP, NL, JJ, L
- INTEGER :: KCBLMX
- INTEGER, DIMENSION( its:ite ) :: KCBL
- !... Real
- REAL :: G1000I, MBMAX, HOVL, MEDDY, MBAR
- REAL :: EKZ, RZ, FM, WSPD, DTS, DTRAT, F1
- REAL, DIMENSION( its:ite ) :: PSTARI, FSACM, DTLIM
- REAL, DIMENSION( kts:kte, its:ite) :: MBARKS, MDWN
- REAL, DIMENSION( 1:NSP, its:ite ) :: FS, BCBOTN
- REAL, DIMENSION( kts:kte ) :: XPLUS, XMINUS
- REAL DELC
- REAL, DIMENSION( 1:NSP,its:ite,kts:kte ) :: VCI
- REAL, DIMENSION( kts:kte ) :: AI, BI, CI, EI !, Y
- REAL, DIMENSION( 1:NSP,kts:kte ) :: DI, UI
- !
- !--Start Exicutable ----
- ILX = ite
- KL = kte
- KLM = kte - 1
- G1000I = 1.0 / G1000
- KCBLMX = 0
- MBMAX = 0.0
- !---COMPUTE ACM MIXING RATE
- DO I = its, ILX
- DTLIM(I) = DTPBL
- PSTARI(I) = 1.0 / PSTAR(I)
- KCBL(I) = 1
- FSACM(I) = 0.0
- IF (NOCONV(I) .EQ. 1) THEN
- KCBL(I) = KLPBL(I)
- !-------MBARKS IS UPWARD MIXING RATE; MDWN IS DOWNWARD MIXING RATE
- !--New couple ACM & EDDY-------------------------------------------------------------
- HOVL = -PBL(I) / MOL(I)
- FSACM(I) = 1./(1.+((KARMAN/(HOVL))**0.3333)/(0.72*KARMAN))
- MEDDY = EDDYZ(I,1) / (DTPBL * (PBLSIG(I) - SIGMAF(1)))
- MBAR = MEDDY * FSACM(I)
- DO K = kts,KCBL(I)-1
- EDDYZ(I,K) = EDDYZ(I,K) * (1.0 - FSACM(I))
- ENDDO
- MBMAX = AMAX1(MBMAX,MBAR)
- DO K = kts+1,KCBL(I)
- MBARKS(K,I) = MBAR
- MDWN(K,I) = MBAR * (PBLSIG(I) - SIGMAF(K-1)) * DSIGHI(K)
- ENDDO
- MBARKS(1,I) = MBAR
- MBARKS(KCBL(I),I) = MDWN(KCBL(I),I)
- MDWN(KCBL(I)+1,I) = 0.0
- ENDIF
- ENDDO ! end of I loop
- DO K = kts,KLM
- DO I = its,ILX
- EKZ = EDDYZ(I,K) / DTPBL * DSIGHI(K)
- DTLIM(I) = AMIN1(0.75 / EKZ,DTLIM(I))
- ENDDO
- ENDDO
-
- DO I = its,ILX
- IF (NOCONV(I) .EQ. 1) THEN
- KCBLMX = AMAX0(KLPBL(I),KCBLMX)
- RZ = (SIGMAF(KCBL(I)) - SIGMAF(1)) * DSIGHI(1)
- DTLIM(I) = AMIN1(XX / (MBARKS(1,I) * RZ),DTLIM(I))
- ENDIF
- ENDDO
- DO K = kts,KL
- DO I = its,ILX
- VCI(1,I,K) = THETA(I,K)
- VCI(2,I,K) = QVS(I,K)
- VCI(3,I,K) = US(I,K)
- VCI(4,I,K) = VS(I,K)
- ! -- Also mix cloud water and ice IF necessary
- ! IF (IMOISTX.NE.1.AND.IMOISTX.NE.3) THEN !!! Check other PBL models
- VCI(5,I,K) = QCS(I,K)
- VCI(6,I,K) = QIS(I,K)
- ENDDO
- ENDDO
- NSPX=6
- DO I = its,ILX
- FS(1,I) = -UST(I) * TST(I) * DENSX(I,1) * PSTARI(I)
- FS(2,I) = -UST(I) * QST(I) * DENSX(I,1) * PSTARI(I)
- FM = -USTM(I) * USTM(I) * DENSX(I,1) * PSTARI(I)
- WSPD = SQRT(US(I,1) * US(I,1) + VS(I,1) * VS(I,1)) + 1.E-9
- FS(3,I) = FM * US(I,1) / WSPD
- FS(4,I) = FM * VS(I,1) / WSPD
- FS(5,I) = 0.0
- FS(6,I) = 0.0 ! SURFACE FLUXES OF CLOUD WATER AND ICE = 0
- ENDDO
- !
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- DO I = its,ILX
- NLP = INT(DTPBL / DTLIM(I) + 1.0)
- DTS = (DTPBL / NLP)
- DTRAT = DTS / DTPBL
- DO NL = 1,NLP ! LOOP OVER SUB TIME LOOP
- !-- COMPUTE ARRAY ELEMENTS THAT ARE INDEPENDANT OF SPECIES
- DO K = kts,KL
- AI(K) = 0.0
- BI(K) = 0.0
- CI(K) = 0.0
- EI(K) = 0.0
- ENDDO
- DO K = 2, KCBL(I)
- EI(K-1) = -CRANKP * MDWN(K,I) * DTS * DSIGH(K) * DSIGHI(K-1)
- BI(K) = 1.0 + CRANKP * MDWN(K,I) * DTS
- AI(K) = -CRANKP * MBARKS(K,I) * DTS
- ENDDO
- EI(1) = EI(1) -EDDYZ(I,1) * CRANKP * DSIGHI(1 )* DTRAT
- AI(2) = AI(2) -EDDYZ(I,1) * CRANKP * DSIGHI(2) * DTRAT
- DO K = KCBL(I)+1, KL
- BI(K) = 1.0
- ENDDO
- DO K = 2,KL
- XPLUS(K) = EDDYZ(I,K) * DSIGHI(K) * DTRAT
- XMINUS(K) = EDDYZ(I,K-1) * DSIGHI(K) * DTRAT
- CI(K) = - XMINUS(K) * CRANKP
- EI(K) = EI(K) - XPLUS(K) * CRANKP
- BI(K) = BI(K) + XPLUS(K) * CRANKP + XMINUS(K) * CRANKP
- ENDDO
- IF (NOCONV(I) .EQ. 1) THEN
- BI(1) = 1.0 + CRANKP * MBARKS(1,I) * (PBLSIG(I) - SIGMAF(1)) * &
- DTS * DSIGHI(1) + EDDYZ(I,1) * DSIGHI(1) * CRANKP * DTRAT
- ELSE
- BI(1) = 1.0 + EDDYZ(I,1) * DSIGHI(1) * CRANKP * DTRAT
- ENDIF
- DO K = 1,KL
- DO L = 1,NSPX
- DI(L,K) = 0.0
- ENDDO
- ENDDO
- !
- !** COMPUTE TENDENCY OF CBL CONCENTRATIONS - SEMI-IMPLICIT SOLUTION
- DO K = 2,KCBL(I)
- DO L = 1,NSPX
- DELC = DTS * (MBARKS(K,I) * VCI(L,I,1) - MDWN(K,I) * &
- VCI(L,I,K) + DSIGH(K+1) * DSIGHI(K) * &
- MDWN(K+1,I) * VCI(L,I,K+1))
- DI(L,K) = VCI(L,I,K) + (1.0 - CRANKP) * DELC
- ENDDO
- ENDDO
- DO K = KCBL(I)+1, KL
- DO L = 1,NSPX
- DI(L,K) = VCI(L,I,K)
- ENDDO
- ENDDO
- DO K = 2,KL
- IF (K .EQ. KL) THEN
- DO L = 1,NSPX
- DI(L,K) = DI(L,K) - (1.0 - CRANKP) * XMINUS(K) * &
- (VCI(L,I,K) - VCI(L,I,K-1))
- ENDDO
- ELSE
- DO L = 1,NSPX
- DI(L,K) = DI(L,K) + (1.0 - CRANKP) * XPLUS(K) * &
- (VCI(L,I,K+1) - VCI(L,I,K)) - &
- (1.0 - CRANKP) * XMINUS(K) * &
- (VCI(L,I,K) - VCI(L,I,K-1))
- ENDDO
- ENDIF
- ENDDO
- IF (NOCONV(I) .EQ. 1) THEN
- DO L = 1,NSPX
- F1 = -G1000I * (MBARKS(1,I) * &
- (PBLSIG(I) - SIGMAF(1)) * VCI(L,I,1) - &
- MDWN(2,I) * VCI(L,I,2) * DSIGH(2))
- DI(L,1) = VCI(L,I,1) - G1000 * (FS(L,I) - (1.0 - CRANKP) &
- * F1) * DSIGHI(1) * DTS
- ENDDO
- ELSE
- DO L = 1,NSPX
- DI(L,1) = VCI(L,I,1) - G1000 * FS(L,I) * DSIGHI(1) * DTS
- ENDDO
- ENDIF
- DO L = 1,NSPX
- DI(L,1) = DI(L,1) + (1.0 - CRANKP) * EDDYZ(I,1) * DSIGHI(1) &
- * DTRAT * (VCI(L,I,2) - VCI(L,I,1))
- ENDDO
- IF ( NOCONV(I) .EQ. 1 ) THEN
- CALL MATRIX (AI, BI, CI, DI, EI, UI, KL, NSPX)
- ELSE
- CALL TRI (CI, BI, EI, DI, UI, KL, NSPX)
- END IF
- !
- !-- COMPUTE NEW THETAV AND Q
- DO K = 1,KL
- DO L = 1,NSPX
- VCI(L,I,K) = UI(L,K)
- ENDDO
- ENDDO
- ENDDO ! END I LOOP
- ENDDO ! END SUB TIME LOOP
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !
- DO K = kts,KL
- DO I = its,ILX
- THETAX(I,K) = VCI(1,I,K)
- QVX(I,K) = VCI(2,I,K)
- UX(I,K) = VCI(3,I,K)
- VX(I,K) = VCI(4,I,K)
- ENDDO
- ENDDO
- DO K = kts,KL
- DO I = its,ILX
- QCX(I,K) = VCI(5,I,K)
- QIX(I,K) = VCI(6,I,K)
- ENDDO
- ENDDO
- END SUBROUTINE ACM
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- SUBROUTINE MATRIX(A,B,C,D,E,X,KL,NSP)
-
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- IMPLICIT NONE
- !
- !-- Bordered band diagonal matrix solver for ACM2
- !-- ACM2 Matrix is in this form:
- ! B1 E1
- ! A2 B2 E2
- ! A3 C3 B3 E3
- ! A4 C4 B4 E4
- ! A5 C5 B5 E5
- ! A6 C6 B6
- !--Upper Matrix is
- ! U11 U12
- ! U22 U23
- ! U33 U34
- ! U44 U45
- ! U55 U56
- ! U66
- !--Lower Matrix is:
- ! 1
- ! L21 1
- ! L31 L32 1
- ! L41 L42 L43 1
- ! L51 L52 L53 L54 1
- ! L61 L62 L63 L64 L65 1
- !---------------------------------------------------------
- !...Arguments
- INTEGER, INTENT(IN) :: KL
- INTEGER, INTENT(IN) :: NSP
- REAL A(KL),B(KL),E(KL)
- REAL C(KL),D(NSP,KL),X(NSP,KL)
- !...Locals
- REAL Y(NSP,KL),AIJ,SUM
- REAL L(KL,KL),UII(KL),UIIP1(KL),RUII(KL)
- INTEGER I,J,V
- !-- Define Upper and Lower matrices
- L(1,1) = 1.
- UII(1) = B(1)
- RUII(1) = 1./UII(1)
- DO I = 2, KL
- L(I,I) = 1.
- L(I,1) = A(I)/B(1)
- UIIP1(I-1)=E(I-1)
- IF(I.GE.3) THEN
- DO J = 2,I-1
- IF(I.EQ.J+1) THEN
- AIJ = C(I)
- ELSE
- AIJ = 0.
- ENDIF
- L(I,J) = (AIJ-L(I,J-1)*E(J-1))/ &
- (B(J)-L(J,J-1)*E(J-1))
- ENDDO
- ENDIF
- ENDDO
-
- DO I = 2,KL
- UII(I) = B(I)-L(I,I-1)*E(I-1)
- RUII(I) = 1./UII(I)
- ENDDO
-
- !-- Forward sub for Ly=d
- DO V= 1, NSP
- Y(V,1) = D(V,1)
- DO I=2,KL
- SUM = D(V,I)
- DO J=1,I-1
- SUM = SUM - L(I,J)*Y(V,J)
- ENDDO
- Y(V,I) = SUM
- ENDDO
- ENDDO
- !-- Back sub for Ux=y
- DO V= 1, NSP
- X(V,KL) = Y(V,KL)*RUII(KL)
- ENDDO
- DO I = KL-1,1,-1
- DO V= 1, NSP
- X(V,I) = (Y(V,I)-UIIP1(I)*X(V,I+1))*RUII(I)
- ENDDO
- ENDDO
- END SUBROUTINE MATRIX
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- SUBROUTINE TRI ( L, D, U, B, X,KL,NSP)
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- ! FUNCTION:
- ! Solves tridiagonal system by Thomas algorithm.
- ! The associated tri-diagonal system is stored in 3 arrays
- ! D : diagonal
- ! L : sub-diagonal
- ! U : super-diagonal
- ! B : right hand side function
- ! X : return solution from tridiagonal solver
- ! [ D(1) U(1) 0 0 0 ... 0 ]
- ! [ L(2) D(2) U(2) 0 0 ... . ]
- ! [ 0 L(3) D(3) U(3) 0 ... . ]
- ! [ . . . . . ] X(i) = B(i)
- ! [ . . . . 0 ]
- ! [ . . . . ]
- ! [ 0 L(n) D(n) ]
- !-----------------------------------------------------------------------
- IMPLICIT NONE
- ! Arguments:
- INTEGER, INTENT(IN) :: KL
- INTEGER, INTENT(IN) :: NSP
- REAL L( KL ) ! subdiagonal
- REAL D(KL) ! diagonal
- REAL U( KL ) ! superdiagonal
- REAL B(NSP,KL ) ! R.H. side
- REAL X( NSP,KL ) ! solution
- ! Local Variables:
- REAL GAM( KL )
- REAL BET
- INTEGER V, K
- ! Decomposition and forward substitution:
- BET = 1.0 / D( 1 )
- DO V = 1, NSP
- X( V,1 ) = BET * B(V,1 )
- ENDDO
- DO K = 2, KL
- GAM(K ) = BET * U( K-1 )
- BET = 1.0 / ( D( K ) - L( K ) * GAM( K ) )
- DO V = 1, NSP
- X( V, K ) = BET * ( B( V,K ) - L( K ) * X( V,K-1 ) )
- ENDDO
- ENDDO
- ! Back-substitution:
- DO K = KL - 1, 1, -1
- DO V = 1, NSP
- X( V,K ) = X( V,K ) - GAM( K+1 ) * X( V,K+1 )
- ENDDO
- ENDDO
-
- END SUBROUTINE TRI
- !-----------------------------------------------------------------------
- !-----------------------------------------------------------------------
- END MODULE module_bl_acm
-