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

Last change on this file since 3527 was 2899, checked in by emillour, 22 months ago

Generic PCM:
More code tidying: turn aeropacity, aeroptproperties, gfluxi, gfluxv,
sfluxi and sfluxv into modules.
EM

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