SUBROUTINE TSOLVE(ISNOW,FI, 2,7
1 QSWNET,QLWOUT,QTRANS,QSENS,QEVAP,EVAP,
2 TZERO,QZERO,GZERO,QMELT,CDH,CDM,RIB,CFLUX,
3 FTEMP,FVAP,ILMO,UE,H,
4 QSWINV,QSWINI,QLWIN,TPOTA,QA,VA,PADRY,RHOAIR,
5 ALVISG,ALNIRG,CRIB,CPHCH,CEVAP,TADP,TVIRTA,
6 ZOSCLH,ZOSCLM,ZRSLFH,ZRSLFM,ZOH,ZOM,FCOR,
7 GCONST,GCOEFF,TSTART,TRSNOW,
8 IWATER,IEVAP,ITERCT,
9 ISLFD,ILW,ILG,IL1,IL2,JL,
A TSTEP,TVIRTS,EVBETA,Q0SAT,RESID,DCFLXM,CFLUXM,
B JEVAP,W0,TRTOP,A,B,ZOMS,ZOHS,LZZ0,LZZ0T,
C FM,FH,ITER,NITER,KF)
C
C * AUG 19/04 - Y.DELAGE. REGROUP COMMON BLOCKS
C * MAKE DECLARATIONS EXPLICIT
C * NOV 12/02 - Y.DELAGE. REPLACE SECANT METHOD BY NEWTON-RAPHSON SCHEME.
C * LIMIT NUMBER OF ITERATIONS (ITERMX) TO 5 AND
C * APPLY CORRECTIONS IF RESIDUE REMAINS.
C * NOV 07/02 - Y.DELAGE/D.VERSEGHY. NEW CALL TO FLXSURFZ.
C * JUL 26/02 - D.VERSEGHY. SHORTENED CLASS4 COMMON BLOCK.
C * MAR 28/02 - D.VERSEGHY. STREAMLINED SUBROUTINE CALL.
C * BYPASS EVAPORATION EFFICIENCY PARAMETER
C * IN CASES OF CONDENSATION.
C * JAN 18/02 - P.BARTLETT/D.VERSEGHY. NEW "BETA" FORMULATION FOR
C * BARE SOIL EVAPORATION BASED ON LEE AND
C * PIELKE.
C * APR 11/01 - M.LAZARE. SHORTENED "CLASS2" COMMON BLOCK.
C * OCT 06/00 - D.VERSEGHY. CONDITIONAL "IF" IN ITERATION SEQUENCE
C * TO AVOID DIVIDE BY ZERO.
C * DEC 07/99 - A.WU/D.VERSEGHY. NEW SOIL EVAPORATION FORMULATION.
C * JUL 24/97 - D.VERSEGHY. CLASS - VERSION 2.7.
C * REPLACE BISECTION METHOD IN SURFACE
C * TEMPERATURE ITERATION SCHEME WITH
C * SECANT METHOD FOR FIRST TEN ITERATIONS.
C * PASS QZERO,QA,ZOMS,ZOHS TO REVISED
C * DRCOEF (ZOMS AND ZOHS ALSO NEW WORK ARRAYS
C * PASSED TO THIS ROUTINE).
C * JUN 20/97 - D.VERSEGHY. PASS IN NEW "CLASS4" COMMON BLOCK.
C * JAN 02/96 - D.VERSEGHY. CLASS - VERSION 2.5.
C * COMPLETION OF ENERGY BALANCE
C * DIAGNOSTICS. ALSO, PASS SWITCH "ILW"
C * THROUGH SUBROUTINE CALL, SPECIFYING
C * WHETHER QLWIN REPRESENTS INCOMING
C * (ILW=1) OR NET (ILW=2) LONGWAVE
C * RADIATION ABOVE THE GROUND.
C * NOV 30/94 - M.LAZARE. CLASS - VERSION 2.3.
C * NEW DRAG COEFFICIENT AND RELATED FIELDS,
C * NOW DETERMINED IN ROUTINE "DRCOEF"
C * "CFLUX" NOW WORK FIELD INSTEAD OF "CLIMIT".
C * OCT 04/94 - D.VERSEGHY. CHANGE "CALL ABORT" TO "CALL XIT" TO
C * ENABLE RUNNING ON PCS.
C * JAN 24/94 - M.LAZARE. UNFORMATTED I/O COMMENTED OUT IN LOOP 200.
C * JUL 29/93 - D.VERSEGHY. CLASS - VERSION 2.2.
C * REMOVE RE-DEFINITION OF QMELT NEAR END
C * (SINCE DONE ELSEWHERE ALREADY) AND
C * REDEFINE QSWNET FOR DIAGNOSTIC PURPOSES
C * TO INCLUDE TRANSMISSION THROUGH
C * SNOWPACK.
C * OCT 15/92 - D.VERSEGHY/M.LAZARE. CLASS - VERSION 2.1.
C * REVISED AND VECTORIZED CODE
C * FOR MODEL VERSION GCM7.
C * AUG 12/91 - D.VERSEGHY. CODE FOR MODEL VERSION GCM7U -
C * CLASS VERSION 2.0 (WITH CANOPY).
C * APR 11/89 - D.VERSEGHY. ITERATIVE SURFACE TEMPERATURE
C * CALCULATIONS FOR SNOW/SOIL.
C
IMPLICIT NONE
INTEGER ISLFD,ILW,ILG,IL1,IL2,JL,I,ISNOW,NIT,NUMIT,IBAD,ITERMX
REAL QSWNV,QSWNI,DCFLUX,DRDT0,TZEROT,WZERO,BOWEN,QEVAPT
C
C * OUTPUT ARRAYS.
C
REAL QSWNET(ILG), QLWOUT(ILG), QTRANS(ILG), QSENS (ILG),
1 QEVAP (ILG), EVAP (ILG), TZERO (ILG), QZERO (ILG),
2 GZERO (ILG), QMELT (ILG), CDH (ILG), CDM (ILG),
3 RIB (ILG), CFLUX (ILG), FTEMP (ILG), FVAP (ILG),
4 ILMO (ILG), UE (ILG), H (ILG)
C
C * INPUT ARRAYS.
C
REAL FI (ILG), QSWINV(ILG), QSWINI(ILG), QLWIN (ILG),
1 TPOTA (ILG), QA (ILG), VA (ILG), PADRY (ILG),
2 RHOAIR(ILG), ALVISG(ILG), ALNIRG(ILG), CRIB (ILG),
3 CPHCH (ILG), CEVAP (ILG), TADP (ILG), TVIRTA(ILG),
4 ZOSCLH(ILG), ZOSCLM(ILG), ZRSLFH(ILG), ZRSLFM(ILG),
5 ZOH (ILG), ZOM (ILG), GCONST(ILG), GCOEFF(ILG),
6 TSTART(ILG), TRSNOW(ILG), FCOR (ILG)
C
INTEGER IWATER(ILG), IEVAP (ILG)
INTEGER ITERCT(ILG,6,50)
C
C * INTERNAL WORK ARRAYS.
C
REAL TSTEP (ILG), TVIRTS(ILG), EVBETA(ILG), Q0SAT (ILG),
1 RESID (ILG), DCFLXM(ILG), CFLUXM(ILG), W0 (ILG),
2 TRTOP (ILG), A (ILG), B (ILG),
3 ZOMS (ILG), ZOHS (ILG), LZZ0 (ILG), LZZ0T (ILG),
4 FM (ILG), FH (ILG)
C
INTEGER ITER (ILG), NITER (ILG), KF (ILG),
1 JEVAP (ILG)
C
logical prnt
#include "class_com.cdk"
C-----------------------------------------------------------------------
data prnt /.false./
c data prnt /.true./
if(prnt) then
print*,'QSWINV',QSWINV
print*,'QSWINI',QSWINI
print*,'QLWIN',QLWIN
print*,'TPOTA',TPOTA
print*,'QA',QA
print*,'VA',VA
print*,'PADRY',PADRY
print*,'RHOAIR',RHOAIR
print*,'CPHCH',CPHCH
print*,'CEVAP',CEVAP
print*,'TADP',TADP
print*,'TVIRTA',TVIRTA
print*,'ZRSLFH',ZRSLFH
print*,'ZRSLFM',ZRSLFM
print*,'ZOH',ZOH
print*,'ZOM',ZOM
print*,'FCOR',FCOR
print*,'GCONST',GCONST
print*,'GCOEFF',GCOEFF
print*,'TSTART',TSTART
print*,'TRSNOW',TRSNOW
print*,'ISLFD,ILW,ILG,IL1,IL2,JL',ISLFD,ILW,ILG,IL1,IL2,JL
endif
C * INITIALIZATION AND PRE-ITERATION SEQUENCE.
C
ITERMX = 5
DO 50 I=IL1,IL2
ITER(I)=2
IF(FI(I).GT.0.) THEN
IF(ISNOW.EQ.0) THEN
TRTOP(I)=0.
ELSE
TRTOP(I)=TRSNOW(I)
ENDIF
QSWNV=QSWINV(I)*(1.0-ALVISG(I))
QSWNI=QSWINI(I)*(1.0-ALNIRG(I))
QSWNET(I)=QSWNV+QSWNI
QTRANS(I)=QSWNET(I)*TRTOP(I)
QSWNET(I)=QSWNET(I)-QTRANS(I)
QMELT(I)=0.0
TZERO(I)=TSTART(I)
TSTEP(I)=5.0
C
RESID(I)=999999.
DCFLXM(I)=0.
ITER(I)=1
NITER(I)=1
IF(ISNOW.EQ.1) THEN
KF(I)=3
ELSE
KF(I)=6
ENDIF
ENDIF
50 CONTINUE
C
C * ITERATION SECTION.
C * LOOP IS REPEATED UNTIL SOLUTIONS HAVE BEEN FOUND FOR ALL POINTS
C * ON THE CURRENT LATITUDE CIRCLE(S).
C
100 CONTINUE
C
NUMIT=0
NIT=0
DO 150 I=IL1,IL2
IF(FI(I).GT.0. .AND. ITER(I).EQ.1) THEN
CFLUXM(I)=CFLUX(I)
IF(TZERO(I).GE.TFREZ) THEN
A(I)=17.269
B(I)=35.86
ELSE
A(I)=21.874
B(I)=7.66
ENDIF
W0(I)=0.622*611.0*EXP(A(I)*(TZERO(I)-TFREZ)/
1 (TZERO(I)-B(I)))/PADRY(I)
Q0SAT(I)=W0(I)/(1.0+W0(I))
IF(IWATER(I).GT.0 .OR. ISNOW.EQ.1 .OR. QA(I).GT.Q0SAT(I))
1 THEN
EVBETA(I)=1.0
QZERO(I)=Q0SAT(I)
ELSEIF(IEVAP(I).GT.0.) THEN
EVBETA(I)=CEVAP(I)
QZERO(I)=EVBETA(I)*Q0SAT(I)+(1.0-EVBETA(I))*QA(I)
IF(QZERO(I).LT.QA(I)) THEN
EVBETA(I)=0.0
QZERO(I)=QA(I)
ENDIF
ELSE
EVBETA(I)=0.0
QZERO(I)=QA(I)
ENDIF
TVIRTS(I)=TZERO(I)*(1.0+0.61*QZERO(I))
NIT=NIT+1
ENDIF
150 CONTINUE
C
IF(NIT.GT.0) THEN
C
C * CALCULATE SURFACE DRAG COEFFICIENTS (STABILITY-DEPENDENT) AND
C * OTHER RELATED QUANTITIES.
C
IF(ISLFD.LT.2) THEN
CALL DRCOEF
(CDM,CDH,RIB,CFLUX,QZERO,QA,ZOSCLM,ZOSCLH,
1 CRIB,TVIRTS,TVIRTA,VA,ZOMS,ZOHS,FI,ITER,
2 ILG,IL1,IL2)
ELSE
CALL FLXSURFZ
(CDM,CDH,CFLUX,RIB,FTEMP,FVAP,ILMO,
1 UE,FCOR,TPOTA,QA,ZRSLFM,ZRSLFH,VA,
2 TZERO,QZERO,H,ZOM,ZOH,
3 LZZ0,LZZ0T,FM,FH,ILG,ITER,JL )
ENDIF
C
C * REMAINING CALCULATIONS.
C
DO 175 I=IL1,IL2
IF(FI(I).GT.0. .AND. ITER(I).EQ.1) THEN
GZERO(I)=GCOEFF(I)*TZERO(I)+GCONST(I)
QSENS(I)=RHOAIR(I)*SPHAIR*CFLUX(I)*(TZERO(I)-TPOTA(I))
EVAP(I)=RHOAIR(I)*CFLUX(I)*(QZERO(I)-QA(I))
QEVAP(I)=CPHCH(I)*EVAP(I)
IF(ILW.EQ.2) THEN
QLWOUT(I)=0.0
ELSE
QLWOUT(I)=SBC*TZERO(I)*TZERO(I)*TZERO(I)*TZERO(I)
ENDIF
RESID(I)=QSWNET(I)+QLWIN(I)-QLWOUT(I)-QSENS(I)-QEVAP(I)-
1 GZERO(I)
IF(ABS(RESID(I)).LT.1.0) ITER(I)=0
IF(FI(I).GT.0. .AND. NITER(I).EQ.ITERMX) ITER(I)=-1
ENDIF
C
175 CONTINUE
DO 185 I=IL1,IL2
IF(FI(I).GT.0. .AND. ITER(I).EQ.1) THEN
IF(NITER(I).GT.1) THEN
DCFLUX=(CFLUX(I)-CFLUXM(I))/
1 SIGN(MAX(.001,ABS(TSTEP(I))),TSTEP(I))
IF(ABS(TVIRTA(I)-TVIRTS(I)).LT.0.4)
1 DCFLUX=MAX(DCFLUX,0.8*DCFLXM(I))
DCFLXM(I)=DCFLUX
ELSE
DCFLUX=0.
ENDIF
DRDT0= -4*SBC*TZERO(I)**3*(2-ILW)
1 -RHOAIR(I)*SPHAIR*(CFLUX(I)+MAX(0.,TZERO(I)-TPOTA(I))
1 *DCFLUX) -GCOEFF(I)
2 +CPHCH(I)*RHOAIR(I)*(CFLUX(I)*W0(I)*A(I)
3 *EVBETA(I)*(B(I)-TFREZ)/((TZERO(I)-B(I))*(1+W0(I)))**2
4 -(QZERO(I)-QA(I))*DCFLUX)
TSTEP(I)=-RESID(I)/DRDT0
TSTEP(I)=max(-10.,min(5.,TSTEP(I)))
TZERO(I)=TZERO(I)+TSTEP(I)
NITER(I)=NITER(I)+1
NUMIT=NUMIT+1
ENDIF
185 CONTINUE
ENDIF
IF(NUMIT.GT.0) GO TO 100
C
C * IF CONVERGENCE HAS NOT BEEN REACHED, CALCULATE TEMPERATURE AND
C * FLUXES ASSUMING NEUTRAL STABILITY AND USING BOWEN RATIO APPROACH
C
DO 195 I=IL1,IL2
JEVAP(I)=0
NUMIT=0
IF(FI(I).GT.0. .AND.ITER(I).EQ.-1) THEN
TZEROT=TVIRTA(I)/(1.0+0.61*QZERO(I))
IF(TZEROT.LT.TZERO(I)+5..AND.ABS(RESID(I)).GT.25.) THEN
TZERO(I)=TZEROT
IF(TZERO(I).GE.TFREZ) THEN
A(I)=17.269
B(I)=35.86
ELSE
A(I)=21.874
B(I)=7.66
ENDIF
WZERO=0.622*611.0*EXP(A(I)*(TZERO(I)-TFREZ)/
1 (TZERO(I)-B(I)))/PADRY(I)
Q0SAT(I)=WZERO/(1.0+WZERO)
QZERO(I)=EVBETA(I)*Q0SAT(I)+(1-EVBETA(I))*QA(I)
GZERO(I)=GCOEFF(I)*TZERO(I)+GCONST(I)
IF(ILW.EQ.2) THEN
QLWOUT(I)=0.0
ELSE
QLWOUT(I)=SBC*TZERO(I)*TZERO(I)*TZERO(I)*TZERO(I)
ENDIF
RESID(I)=QSWNET(I)+QLWIN(I)-QLWOUT(I)-GZERO(I)
QEVAPT=CPHCH(I)*(QZERO(I)-QA(I))
BOWEN=SPHAIR*(TZERO(I)-TPOTA(I))/
1 SIGN(MAX(ABS(QEVAPT),1.E-6),QEVAPT)
QEVAP(I)=RESID(I)/SIGN(MAX(ABS(1+BOWEN),0.1),1+BOWEN)
QSENS(I)=RESID(I)-QEVAP(I)
RESID(I)=0.
EVAP(I)=QEVAP(I)/CPHCH(I)
TVIRTS(I)=TZERO(I)*(1.0+0.61*QZERO(I))
JEVAP(I)=1
NUMIT=NUMIT+1
ENDIF
ENDIF
195 CONTINUE
C
IF(NUMIT.GT.0) THEN
IF(ISLFD.LT.2) THEN
CALL DRCOEF
(CDM,CDH,RIB,CFLUX,QZERO,QA,ZOSCLM,ZOSCLH,
1 CRIB,TVIRTS,TVIRTA,VA,ZOMS,ZOHS,FI,JEVAP,
2 ILG,IL1,IL2)
ELSE
CALL FLXSURFZ
(CDM,CDH,CFLUX,RIB,FTEMP,FVAP,ILMO,
1 UE,FCOR,TPOTA,QA,ZRSLFM,ZRSLFH,VA,
2 TZERO,QZERO,H,ZOM,ZOH,
3 LZZ0,LZZ0T,FM,FH,ILG,JEVAP,JL )
ENDIF
ENDIF
C
C do I=IL1,IL2
C if(jevap(i).eq.1) print196,'TSOLVE: RESID>25',
C 1 I,JL,VA(I),QEVAP(I),QSENS(I)
C ENDDO
C 196 FORMAT(A18,2I5,3F10.2)
IBAD=0
DO 200 I=IL1,IL2
IF(FI(I).GT.0. .AND. (TZERO(I).LT.173.16 .OR.
1 TZERO(I).GT.373.16)) THEN
IBAD=I
ENDIF
200 CONTINUE
C
C
IF(IBAD.NE.0) THEN
WRITE(6,6275) IBAD,JL,TZERO(IBAD),NITER(IBAD),ISNOW
6275 FORMAT('0BAD ITERATION TEMPERATURE',3X,2I3,F16.2,2I4)
WRITE(6,6280) QSWNET(IBAD),QLWIN(IBAD),QSENS(IBAD),
1 QEVAP(IBAD),GZERO(IBAD),CFLUX(IBAD),RIB(IBAD)
6280 FORMAT(2X,7F12.4)
CALL XIT
('TSOLVE',-1)
ENDIF
C
C * POST-ITERATION CLEAN-UP.
C
NIT=0
DO 300 I=IL1,IL2
IF(((IWATER(I).EQ.1 .AND. TZERO(I).LT.TFREZ) .OR.
1 (IWATER(I).EQ.2 .AND. TZERO(I).GT.TFREZ)) .AND.
2 FI(I).GT.0.) THEN
TZERO(I)=TFREZ
WZERO=0.622*611.0/PADRY(I)
QZERO(I)=WZERO/(1.0+WZERO)
EVBETA(I)=1.0
TVIRTS(I)=TZERO(I)*(1.0+0.61*QZERO(I))
ITER(I)=1
NIT=NIT+1
ELSE
ITER(I)=0
ENDIF
300 CONTINUE
C
IF(NIT.GT.0) THEN
C
C * CALCULATE SURFACE DRAG COEFFICIENTS (STABILITY-DEPENDENT) AND
C * OTHER RELATED QUANTITIES.
C
IF(ISLFD.LT.2) THEN
CALL DRCOEF
(CDM,CDH,RIB,CFLUX,QZERO,QA,ZOSCLM,ZOSCLH,
1 CRIB,TVIRTS,TVIRTA,VA,ZOMS,ZOHS,FI,ITER,
2 ILG,IL1,IL2)
ELSE
CALL FLXSURFZ
(CDM,CDH,CFLUX,RIB,FTEMP,FVAP,ILMO,
1 UE,FCOR,TPOTA,QA,ZRSLFM,ZRSLFH,VA,
2 TZERO,QZERO,H,ZOM,ZOH,
3 LZZ0,LZZ0T,FM,FH,ILG,ITER,JL )
ENDIF
ENDIF
C
C * REMAINING CALCULATIONS.
C
DO 350 I=IL1,IL2
IF(FI(I).GT.0. .AND. ITER(I).EQ.1) THEN
GZERO(I)=GCOEFF(I)*TZERO(I)+GCONST(I)
QSENS(I)=RHOAIR(I)*SPHAIR*CFLUX(I)*(TZERO(I)-TPOTA(I))
EVAP(I)=RHOAIR(I)*CFLUX(I)*(QZERO(I)-QA(I))
IF(EVAP(I).LT.0. .AND. TZERO(I).GE.TADP(I)) EVAP(I)=0.0
QEVAP(I)=CPHCH(I)*EVAP(I)
IF(ILW.EQ.2) THEN
QLWOUT(I)=0.0
ELSE
QLWOUT(I)=SBC*TZERO(I)*TZERO(I)*TZERO(I)*TZERO(I)
ENDIF
QMELT(I)=QSWNET(I)+QLWIN(I)-QLWOUT(I)-QSENS(I)-QEVAP(I)-
1 GZERO(I)
RESID(I)=0.0
ENDIF
C
IF(FI(I).GT.0.) THEN
GZERO(I)=GZERO(I)+RESID(I)*0.5
QSENS(I)=QSENS(I)+RESID(I)*0.5
QSWNET(I)=QSWNET(I)+QTRANS(I)
EVAP(I)=EVAP(I)/RHOW
ITERCT(I,KF(I),NITER(I))=ITERCT(I,KF(I),NITER(I))+1
ENDIF
350 CONTINUE
C
RETURN
END