source: trunk/LMDZ.GENERIC/libf/phystd/gfluxi.F @ 2613

Last change on this file since 2613 was 2283, checked in by jvatant, 5 years ago

Set the temperature boundaries and step for Planck function integration as input in callphys.def, for more flexibility.

+ User can now set them by tplanckmin, tplanckmax and dtplanck
+ Default values are a wide range 30-1500K
+ Add a sanity check in callcorrk instead of leaving out-of-bounds planckir indexes.

--JVO

File size: 8.7 KB
RevLine 
[135]1      SUBROUTINE GFLUXI(NLL,TLEV,NW,DW,DTAU,TAUCUM,W0,COSBAR,UBARI,
2     *                  RSF,BTOP,BSURF,FTOPUP,FMIDP,FMIDM)
[2056]3     
[135]4      use radinc_h
5      use radcommon_h, only: planckir
[1384]6      use comcstfi_mod, only: pi
[2056]7     
8      IMPLICIT NONE
9     
10!-----------------------------------------------------------------------
11!  THIS SUBROUTINE TAKES THE OPTICAL CONSTANTS AND BOUNDARY CONDITIONS
12!  FOR THE INFRARED FLUX AT ONE WAVELENGTH AND SOLVES FOR THE FLUXES AT
13!  THE LEVELS.  THIS VERSION IS SET UP TO WORK WITH LAYER OPTICAL DEPTHS
14!  MEASURED FROM THE TOP OF EACH LAYER.  THE TOP OF EACH LAYER HAS 
15!  OPTICAL DEPTH ZERO.  IN THIS SUB LEVEL N IS ABOVE LAYER N. THAT IS LAYER N
16!  HAS LEVEL N ON TOP AND LEVEL N+1 ON BOTTOM. OPTICAL DEPTH INCREASES
17!  FROM TOP TO BOTTOM.  SEE C.P. MCKAY, TGM NOTES.
18!  THE TRI-DIAGONAL MATRIX SOLVER IS DSOLVER AND IS DOUBLE PRECISION SO MANY
19!  VARIABLES ARE PASSED AS SINGLE THEN BECOME DOUBLE IN DSOLVER
20!
21! NLL            = NUMBER OF LEVELS (NLAYERS + 1) MUST BE LESS THAT NL (101)
22! TLEV(L_LEVELS) = ARRAY OF TEMPERATURES AT GCM LEVELS
23! WAVEN          = WAVELENGTH FOR THE COMPUTATION
24! DW             = WAVENUMBER INTERVAL
25! DTAU(NLAYER)   = ARRAY OPTICAL DEPTH OF THE LAYERS
26! W0(NLEVEL)     = SINGLE SCATTERING ALBEDO
27! COSBAR(NLEVEL) = ASYMMETRY FACTORS, 0=ISOTROPIC
28! UBARI          = AVERAGE ANGLE, MUST BE EQUAL TO 0.5 IN IR
29! RSF            = SURFACE REFLECTANCE
30! BTOP           = UPPER BOUNDARY CONDITION ON IR INTENSITY (NOT FLUX)
31! BSURF          = SURFACE EMISSION = (1-RSFI)*PLANCK, INTENSITY (NOT FLUX)
32! FP(NLEVEL)     = UPWARD FLUX AT LEVELS
33! FM(NLEVEL)     = DOWNWARD FLUX AT LEVELS
34! FMIDP(NLAYER)  = UPWARD FLUX AT LAYER MIDPOINTS
35! FMIDM(NLAYER)  = DOWNWARD FLUX AT LAYER MIDPOINTS
36!-----------------------------------------------------------------------
37     
[135]38      INTEGER NLL, NLAYER, L, NW, NT, NT2
39      REAL*8  TERM, CPMID, CMMID
40      REAL*8  PLANCK
41      REAL*8  EM,EP
42      REAL*8  COSBAR(L_NLAYRAD), W0(L_NLAYRAD), DTAU(L_NLAYRAD)
43      REAL*8  TAUCUM(L_LEVELS), DTAUK
44      REAL*8  TLEV(L_LEVELS)
45      REAL*8  WAVEN, DW, UBARI, RSF
46      REAL*8  BTOP, BSURF, FMIDP(L_NLAYRAD), FMIDM(L_NLAYRAD)
[2056]47      REAL*8  B0(L_NLAYRAD)
48      REAL*8  B1(L_NLAYRAD)
49      REAL*8  ALPHA(L_NLAYRAD)
[1420]50      REAL*8  LAMDA(L_NLAYRAD),XK1(L_NLAYRAD),XK2(L_NLAYRAD)
51      REAL*8  GAMA(L_NLAYRAD),CP(L_NLAYRAD),CM(L_NLAYRAD)
52      REAL*8  CPM1(L_NLAYRAD),CMM1(L_NLAYRAD),E1(L_NLAYRAD)
[2056]53      REAL*8  E2(L_NLAYRAD)
54      REAL*8  E3(L_NLAYRAD)
55      REAL*8  E4(L_NLAYRAD)
[135]56      REAL*8  FTOPUP, FLUXUP, FLUXDN
[2056]57      REAL*8 :: TAUMAX = L_TAUMAX
[135]58
[2056]59! AB : variables for interpolation
60      REAL*8 C1
61      REAL*8 C2
62      REAL*8 P1
63      REAL*8 P2
64     
65!=======================================================================
66!     WE GO WITH THE HEMISPHERIC CONSTANT APPROACH IN THE INFRARED
67     
[135]68      NLAYER = L_NLAYRAD
69
70      DO L=1,L_NLAYRAD-1
[804]71
[2056]72!-----------------------------------------------------------------------
[804]73! There is a problem when W0 = 1
74!         open(888,file='W0')
75!           if ((W0(L).eq.0.).or.(W0(L).eq.1.)) then
76!             write(888,*) W0(L), L, 'gfluxi'
77!           endif
78! Prevent this with an if statement:
[2056]79!-----------------------------------------------------------------------
80         if (W0(L).eq.1.D0) then
81            W0(L) = 0.99999D0
82         endif
83         
84         ALPHA(L) = SQRT( (1.0D0-W0(L))/(1.0D0-W0(L)*COSBAR(L)) )
85         LAMDA(L) = ALPHA(L)*(1.0D0-W0(L)*COSBAR(L))/UBARI
86         
[2283]87         NT    = int(TLEV(2*L)*NTfac)   - NTstart+1
88         NT2   = int(TLEV(2*L+2)*NTfac) - NTstart+1
[2056]89         
90! AB : PLANCKIR(NW,NT) is replaced by P1, the linear interpolation result for a temperature NT
91! AB : idem for PLANCKIR(NW,NT2) and P2
92         C1 = TLEV(2*L) * NTfac - int(TLEV(2*L) * NTfac)
93         C2 = TLEV(2*L+2)*NTfac - int(TLEV(2*L+2)*NTfac)
94         P1 = (1.0D0 - C1) * PLANCKIR(NW,NT) + C1 * PLANCKIR(NW,NT+1)
95         P2 = (1.0D0 - C2) * PLANCKIR(NW,NT2) + C2 * PLANCKIR(NW,NT2+1)
96         B1(L) = (P2 - P1) / DTAU(L)
97         B0(L) = P1
[135]98      END DO
[2056]99     
100!     Take care of special lower layer
101     
[135]102      L        = L_NLAYRAD
[804]103
104      if (W0(L).eq.1.) then
[959]105          W0(L) = 0.99999D0
[804]106      end if
[2056]107     
[959]108      ALPHA(L) = SQRT( (1.0D0-W0(L))/(1.0D0-W0(L)*COSBAR(L)) )
109      LAMDA(L) = ALPHA(L)*(1.0D0-W0(L)*COSBAR(L))/UBARI
[2056]110     
[995]111      ! Tsurf is used for 1st layer source function
112      ! -- same results for most thin atmospheres
113      ! -- and stabilizes integrations
[2283]114      NT    = int(TLEV(2*L+1)*NTfac) - NTstart+1
[995]115      !! For deep, opaque, thick first layers (e.g. Saturn)
116      !! what is below works much better, not unstable, ...
117      !! ... and actually fully accurate because 1st layer temp (JL)
[2283]118      !NT    = int(TLEV(2*L)*NTfac) - NTstart+1
[995]119      !! (or this one yields same results
[2283]120      !NT    = int( (TLEV(2*L)+TLEV(2*L+1))*0.5*NTfac ) - NTstart+1
[2056]121     
[2283]122      NT2   = int(TLEV(2*L)*NTfac)   - NTstart+1
[2056]123     
124! AB : PLANCKIR(NW,NT) is replaced by P1, the linear interpolation result for a temperature NT
125! AB : idem for PLANCKIR(NW,NT2) and P2
126      C1 = TLEV(2*L+1)*NTfac - int(TLEV(2*L+1)*NTfac)
127      C2 = TLEV(2*L) * NTfac - int(TLEV(2*L) * NTfac)
128      P1 = (1.0D0 - C1) * PLANCKIR(NW,NT) + C1 * PLANCKIR(NW,NT+1)
129      P2 = (1.0D0 - C2) * PLANCKIR(NW,NT2) + C2 * PLANCKIR(NW,NT2+1)
130      B1(L) = (P1 - P2) / DTAU(L)
131      B0(L) = P2
132     
[135]133      DO L=1,L_NLAYRAD
[2056]134         GAMA(L) = (1.0D0-ALPHA(L))/(1.0D0+ALPHA(L))
135         TERM    = UBARI/(1.0D0-W0(L)*COSBAR(L))
136         
137! CPM1 AND CMM1 ARE THE CPLUS AND CMINUS TERMS EVALUATED
138! AT THE TOP OF THE LAYER, THAT IS ZERO OPTICAL DEPTH
139         
140         CPM1(L) = B0(L)+B1(L)*TERM
141         CMM1(L) = B0(L)-B1(L)*TERM
142         
143! CP AND CM ARE THE CPLUS AND CMINUS TERMS EVALUATED AT THE
144! BOTTOM OF THE LAYER.  THAT IS AT DTAU OPTICAL DEPTH.
145! JL18 put CP and CM after the calculation of CPM1 and CMM1 to avoid unecessary calculations.
146         
147         CP(L) = CPM1(L) +B1(L)*DTAU(L)
148         CM(L) = CMM1(L) +B1(L)*DTAU(L)
[135]149      END DO
[2056]150     
151! NOW CALCULATE THE EXPONENTIAL TERMS NEEDED
152! FOR THE TRIDIAGONAL ROTATED LAYERED METHOD
153! WARNING IF DTAU(J) IS GREATER THAN ABOUT 35 (VAX)
154! WE CLIP IT TO AVOID OVERFLOW.
155     
[135]156      DO L=1,L_NLAYRAD
[2056]157        EP    = EXP( MIN((LAMDA(L)*DTAU(L)),TAUMAX)) ! CLIPPED EXPONENTIAL
[959]158        EM    = 1.0D0/EP
[135]159        E1(L) = EP+GAMA(L)*EM
160        E2(L) = EP-GAMA(L)*EM
161        E3(L) = GAMA(L)*EP+EM
162        E4(L) = GAMA(L)*EP-EM
163      END DO
[2056]164     
165!      B81=BTOP  ! RENAME BEFORE CALLING DSOLVER - used to be to set
166!      B82=BSURF ! them to real*8 - but now everything is real*8
167!      R81=RSF   ! so this may not be necessary
[135]168
[2056]169! DOUBLE PRECISION TRIDIAGONAL SOLVER
170     
[135]171      CALL DSOLVER(NLAYER,GAMA,CP,CM,CPM1,CMM1,E1,E2,E3,E4,BTOP,
172     *             BSURF,RSF,XK1,XK2)
[2056]173     
174! NOW WE CALCULATE THE FLUXES AT THE MIDPOINTS OF THE LAYERS.
175     
[135]176      DO L=1,L_NLAYRAD-1
[2056]177         DTAUK = TAUCUM(2*L+1)-TAUCUM(2*L)
178         EP    = EXP(MIN(LAMDA(L)*DTAUK,TAUMAX)) ! CLIPPED EXPONENTIAL
179         EM    = 1.0D0/EP
180         TERM  = UBARI/(1.D0-W0(L)*COSBAR(L))
181         
182! CP AND CM ARE THE CPLUS AND CMINUS TERMS EVALUATED AT THE
183! BOTTOM OF THE LAYER.  THAT IS AT DTAU  OPTICAL DEPTH
184         
185         CPMID    = B0(L)+B1(L)*DTAUK +B1(L)*TERM
186         CMMID    = B0(L)+B1(L)*DTAUK -B1(L)*TERM
187         FMIDP(L) = XK1(L)*EP + GAMA(L)*XK2(L)*EM + CPMID
188         FMIDM(L) = XK1(L)*EP*GAMA(L) + XK2(L)*EM + CMMID
189         
190! FOR FLUX WE INTEGRATE OVER THE HEMISPHERE TREATING INTENSITY CONSTANT
191         
192         FMIDP(L) = FMIDP(L)*PI
193         FMIDM(L) = FMIDM(L)*PI
[135]194      END DO
[2056]195     
196! And now, for the special bottom layer
[135]197
198      L    = L_NLAYRAD
199
200      EP   = EXP(MIN((LAMDA(L)*DTAU(L)),TAUMAX)) ! CLIPPED EXPONENTIAL
[959]201      EM   = 1.0D0/EP
202      TERM = UBARI/(1.D0-W0(L)*COSBAR(L))
[135]203
[2056]204! CP AND CM ARE THE CPLUS AND CMINUS TERMS EVALUATED AT THE
205! BOTTOM OF THE LAYER.  THAT IS AT DTAU  OPTICAL DEPTH
[135]206
207      CPMID    = B0(L)+B1(L)*DTAU(L) +B1(L)*TERM
208      CMMID    = B0(L)+B1(L)*DTAU(L) -B1(L)*TERM
209      FMIDP(L) = XK1(L)*EP + GAMA(L)*XK2(L)*EM + CPMID
210      FMIDM(L) = XK1(L)*EP*GAMA(L) + XK2(L)*EM + CMMID
211 
[2056]212! FOR FLUX WE INTEGRATE OVER THE HEMISPHERE TREATING INTENSITY CONSTANT
213     
[135]214      FMIDP(L) = FMIDP(L)*PI
215      FMIDM(L) = FMIDM(L)*PI
[2056]216     
217! FLUX AT THE PTOP LEVEL
218     
[959]219      EP   = 1.0D0
220      EM   = 1.0D0
221      TERM = UBARI/(1.0D0-W0(1)*COSBAR(1))
[2056]222     
223! CP AND CM ARE THE CPLUS AND CMINUS TERMS EVALUATED AT THE
224! BOTTOM OF THE LAYER.  THAT IS AT DTAU  OPTICAL DEPTH
225     
[135]226      CPMID  = B0(1)+B1(1)*TERM
227      CMMID  = B0(1)-B1(1)*TERM
[2056]228     
[135]229      FLUXUP = XK1(1)*EP + GAMA(1)*XK2(1)*EM + CPMID
230      FLUXDN = XK1(1)*EP*GAMA(1) + XK2(1)*EM + CMMID
[2056]231     
232! FOR FLUX WE INTEGRATE OVER THE HEMISPHERE TREATING INTENSITY CONSTANT
233     
[135]234      FTOPUP = (FLUXUP-FLUXDN)*PI
[2056]235     
236     
[135]237      RETURN
238      END
Note: See TracBrowser for help on using the repository browser.