source: trunk/LMDZ.GENERIC/libf/aeronostd/photolysis_asis.F90 @ 2537

Last change on this file since 2537 was 1796, checked in by bclmd, 7 years ago

Adding photochemistry to LMDZ Generic

  • Property svn:executable set to *
File size: 16.6 KB
Line 
1!==========================================================================
2
3      subroutine photolysis_asis(nlayer, ngrid,                                 &
4                                 lswitch, press, temp, sza, fractcol, tauref,   &
5                                 zmmean, dist_sol, rmco2, rmo3, v_phot)
6
7!==========================================================================
8
9      use comcstfi_mod
10      use callkeys_mod
11
12      implicit none
13
14#include "chimiedata.h"
15
16!==========================================================================
17!     input:
18!==========================================================================
19       
20      integer, intent(in) :: nlayer ! number of atmospheric layers
21      integer,intent(in) :: ngrid   ! number of atmospheric columns
22      integer :: lswitch            ! interface level between chemistries
23      real :: press(nlayer)         ! pressure (hPa)
24      real :: temp(nlayer)          ! temperature (K)
25      real :: sza                   ! solar zenith angle (deg)
26      real :: fractcol              ! day fraction
27      real :: tauref                ! optical depth at 7 hpa
28      real :: zmmean(nlayer)        ! mean molecular mass (g)
29      real :: dist_sol              ! sun distance (AU)
30      real :: rmco2(nlayer)         ! co2 mixing ratio
31      real :: rmo3(nlayer)          ! ozone mixing ratio
32
33!==========================================================================
34!     output: interpolated photodissociation rates (s-1)
35!==========================================================================
36
37      real (kind = 8), dimension(nlayer,nb_phot_max) :: v_phot
38
39!==========================================================================
40!     local:
41!==========================================================================
42
43      integer :: icol, ij, indsza, indtau, indcol, indozo, indtemp,     &
44                 iozo, isza, itau, it, l
45
46      integer :: j_o2_o, j_o2_o1d, j_co2_o, j_co2_o1d, j_o3_o1d,        &
47                 j_o3_o, j_h2o, j_hdo, j_h2o2, j_ho2, j_no, j_no2,      &
48                 j_hno3, j_hno4,                                        &
49                 j_ch4_ch3_h, j_ch4_1ch2_h2, j_ch4_3ch2_h_h,            &
50                 j_ch4_ch_h2_h, j_ch3o2h, j_ch2o_hco, j_ch2o_co,        &
51                 j_ch3oh, j_c2h6, j_hcl, j_hocl, j_clo, j_so2, j_so,    &
52                 j_h2s, j_so3
53
54      real :: col(nlayer)                 ! overhead air column   (molecule cm-2)
55      real :: colo3(nlayer)               ! overhead ozone column (molecule cm-2)
56      real :: poids(2,2,2,2,2)            ! 5D interpolation weights
57      real :: tref                        ! temperature  at 1.9 hPa in the gcm (K)
58      real :: table_temp(ntemp)           ! temperatures at 1.9 hPa in jmars   (K)
59      real :: cinf, csup, cicol, ciozo, cisza, citemp, citau
60      real :: colo3min, dp, coef
61      real :: ratio_o3(nlayer)
62      real :: tau
63      real :: j(nlayer,nd)
64
65!==========================================================================
66!     day/night criterion
67!==========================================================================
68
69      if (sza <= 95.) then
70
71!==========================================================================
72!     temperatures at 1.9 hPa in lookup table
73!==========================================================================
74     
75      table_temp(1) = 226.2
76      table_temp(2) = 206.2
77      table_temp(3) = 186.2
78      table_temp(4) = 169.8
79
80!==========================================================================
81!     interpolation in solar zenith angle
82!==========================================================================
83 
84      indsza = nsza - 1
85      do isza = 1,nsza
86         if (szatab(isza) >= sza) then
87            indsza = isza - 1
88            indsza = max(indsza, 1)
89            exit
90         end if
91      end do
92      cisza = (sza - szatab(indsza))  &
93             /(szatab(indsza + 1) - szatab(indsza))
94
95!==========================================================================
96!     interpolation in dust (tau)
97!==========================================================================
98
99      tau = min(tauref, tautab(ntau))
100      tau = max(tau, tautab(1))
101
102      indtau = ntau - 1
103      do itau = 1,ntau
104         if (tautab(itau) >= tau) then
105            indtau = itau - 1
106            indtau = max(indtau, 1)
107            exit
108         end if
109      end do
110      citau = (tau - tautab(indtau))     &
111             /(tautab(indtau + 1) - tautab(indtau))
112
113!==========================================================================
114!     co2 and ozone columns
115!==========================================================================
116
117!     co2 column at model top (molecule.cm-2)
118
119      col(lswitch-1) = 6.022e22*rmco2(lswitch-1)*press(lswitch-1)*100.  &
120                       /(zmmean(lswitch-1)*g)
121
122!     ozone column at model top
123
124      colo3(lswitch-1) = 0.
125
126!     co2 and ozone columns for other levels (molecule.cm-2)
127
128      do l = lswitch-2,1,-1
129         dp = (press(l) - press(l+1))*100.
130         col(l) = col(l+1) + (rmco2(l+1) + rmco2(l))*0.5   &
131                             *6.022e22*dp/(zmmean(l)*g)
132         col(l) = min(col(l), colairtab(1))
133         colo3(l) = colo3(l+1) + (rmo3(l+1) + rmo3(l))*0.5 &
134                                 *6.022e22*dp/(zmmean(l)*g)
135      end do
136
137!     ratio ozone column/minimal theoretical column (0.1 micron-atm)
138
139!     ro3 = 7.171e-10 is the o3 mixing ratio for a uniform
140!     profile giving a column 0.1 micron-atmosphere at
141!     a surface pressure of 10 hpa.
142
143      do l = 1,lswitch-1
144         colo3min    = col(l)*7.171e-10
145         ratio_o3(l) = colo3(l)/colo3min
146         ratio_o3(l) = min(ratio_o3(l), table_ozo(nozo)*10.)
147         ratio_o3(l) = max(ratio_o3(l), 1.)
148      end do
149
150!==========================================================================
151!     temperature dependence
152!==========================================================================
153
154!     1) search for temperature at 1.9 hPa (tref): vertical interpolation
155
156      tref = temp(1)
157      do l = (lswitch-1)-1,1,-1
158         if (press(l) > 1.9) then
159            cinf = (press(l) - 1.9)/(press(l) - press(l+1))
160            csup = 1. - cinf
161            tref = cinf*temp(l+1) + csup*temp(l)
162            exit
163         end if
164      end do
165
166!     2) interpolation in temperature
167
168      tref = min(tref,table_temp(1))
169      tref = max(tref,table_temp(ntemp))
170
171      do it = 2, ntemp
172         if (table_temp(it) <= tref) then
173            citemp = (log(tref) - log(table_temp(it)))              &
174                    /(log(table_temp(it-1)) - log(table_temp(it)))
175            indtemp = it - 1
176            exit
177         end if
178      end do
179
180!==========================================================================
181!     loop over vertical levels
182!==========================================================================
183
184      do l = 1,lswitch-1
185
186!     interpolation in air column
187
188         indcol = nz - 1
189         do icol = 1,nz
190            if (colairtab(icol) < col(l)) then
191               indcol = icol - 1
192               exit
193            end if
194         end do
195         cicol = (log(col(l)) - log(colairtab(indcol + 1)))              &
196                /(log(colairtab(indcol)) - log(colairtab(indcol + 1)))
197
198!     interpolation in ozone column
199
200         indozo = nozo - 1
201         do iozo = 1,nozo
202            if (table_ozo(iozo)*10. >= ratio_o3(l)) then
203               indozo = iozo - 1
204               indozo = max(indozo, 1)
205               exit
206            end if
207         end do
208         ciozo = (ratio_o3(l) - table_ozo(indozo)*10.)             &
209                /(table_ozo(indozo + 1)*10. - table_ozo(indozo)*10.)
210
211!     4-dimensional interpolation weights
212
213!     poids(temp,sza,co2,o3,tau)
214
215         poids(1,1,1,1,1) = citemp*(1.-cisza)*cicol*(1.-ciozo)*(1.-citau)
216         poids(1,1,1,2,1) = citemp*(1.-cisza)*cicol*ciozo*(1.-citau)
217         poids(1,1,2,1,1) = citemp*(1.-cisza)*(1.-cicol)*(1.-ciozo)*(1.-citau)
218         poids(1,1,2,2,1) = citemp*(1.-cisza)*(1.-cicol)*ciozo*(1.-citau)
219         poids(1,2,1,1,1) = citemp*cisza*cicol*(1.-ciozo)*(1.-citau)
220         poids(1,2,1,2,1) = citemp*cisza*cicol*ciozo*(1.-citau)
221         poids(1,2,2,1,1) = citemp*cisza*(1.-cicol)*(1.-ciozo)*(1.-citau)
222         poids(1,2,2,2,1) = citemp*cisza*(1.-cicol)*ciozo*(1.-citau)
223         poids(2,1,1,1,1) = (1.-citemp)*(1.-cisza)*cicol*(1.-ciozo)*(1.-citau)
224         poids(2,1,1,2,1) = (1.-citemp)*(1.-cisza)*cicol*ciozo*(1.-citau)
225         poids(2,1,2,1,1) = (1.-citemp)*(1.-cisza)*(1.-cicol)*(1.-ciozo)*(1.-citau)
226         poids(2,1,2,2,1) = (1.-citemp)*(1.-cisza)*(1.-cicol)*ciozo*(1.-citau)
227         poids(2,2,1,1,1) = (1.-citemp)*cisza*cicol*(1.-ciozo)*(1.-citau)
228         poids(2,2,1,2,1) = (1.-citemp)*cisza*cicol*ciozo*(1.-citau)
229         poids(2,2,2,1,1) = (1.-citemp)*cisza*(1.-cicol)*(1.-ciozo)*(1.-citau)
230         poids(2,2,2,2,1) = (1.-citemp)*cisza*(1.-cicol)*ciozo*(1.-citau)
231!
232         poids(1,1,1,1,2) = citemp*(1.-cisza)*cicol*(1.-ciozo)*citau
233         poids(1,1,1,2,2) = citemp*(1.-cisza)*cicol*ciozo*citau
234         poids(1,1,2,1,2) = citemp*(1.-cisza)*(1.-cicol)*(1.-ciozo)*citau
235         poids(1,1,2,2,2) = citemp*(1.-cisza)*(1.-cicol)*ciozo*citau
236         poids(1,2,1,1,2) = citemp*cisza*cicol*(1.-ciozo)*citau
237         poids(1,2,1,2,2) = citemp*cisza*cicol*ciozo*citau
238         poids(1,2,2,1,2) = citemp*cisza*(1.-cicol)*(1.-ciozo)*citau
239         poids(1,2,2,2,2) = citemp*cisza*(1.-cicol)*ciozo*citau
240         poids(2,1,1,1,2) = (1.-citemp)*(1.-cisza)*cicol*(1.-ciozo)*citau
241         poids(2,1,1,2,2) = (1.-citemp)*(1.-cisza)*cicol*ciozo*citau
242         poids(2,1,2,1,2) = (1.-citemp)*(1.-cisza)*(1.-cicol)*(1.-ciozo)*citau
243         poids(2,1,2,2,2) = (1.-citemp)*(1.-cisza)*(1.-cicol)*ciozo*citau
244         poids(2,2,1,1,2) = (1.-citemp)*cisza*cicol*(1.-ciozo)*citau
245         poids(2,2,1,2,2) = (1.-citemp)*cisza*cicol*ciozo*citau
246         poids(2,2,2,1,2) = (1.-citemp)*cisza*(1.-cicol)*(1.-ciozo)*citau
247         poids(2,2,2,2,2) = (1.-citemp)*cisza*(1.-cicol)*ciozo*citau
248
249!     4-dimensional interpolation in the lookup table
250
251         do ij = 1,nd
252            j(l,ij) =                                                                &
253            poids(1,1,1,1,1)*jphot(indtemp,indsza,indcol,indozo,indtau,ij)           &
254          + poids(1,1,1,2,1)*jphot(indtemp,indsza,indcol,indozo+1,indtau,ij)         &
255          + poids(1,1,2,1,1)*jphot(indtemp,indsza,indcol+1,indozo,indtau,ij)         &
256          + poids(1,1,2,2,1)*jphot(indtemp,indsza,indcol+1,indozo+1,indtau,ij)       &
257          + poids(1,2,1,1,1)*jphot(indtemp,indsza+1,indcol,indozo,indtau,ij)         &
258          + poids(1,2,1,2,1)*jphot(indtemp,indsza+1,indcol,indozo+1,indtau,ij)       &
259          + poids(1,2,2,1,1)*jphot(indtemp,indsza+1,indcol+1,indozo,indtau,ij)       &
260          + poids(1,2,2,2,1)*jphot(indtemp,indsza+1,indcol+1,indozo+1,indtau,ij)     &
261          + poids(2,1,1,1,1)*jphot(indtemp+1,indsza,indcol,indozo,indtau,ij)         &
262          + poids(2,1,1,2,1)*jphot(indtemp+1,indsza,indcol,indozo+1,indtau,ij)       &
263          + poids(2,1,2,1,1)*jphot(indtemp+1,indsza,indcol+1,indozo,indtau,ij)       &
264          + poids(2,1,2,2,1)*jphot(indtemp+1,indsza,indcol+1,indozo+1,indtau,ij)     &
265          + poids(2,2,1,1,1)*jphot(indtemp+1,indsza+1,indcol,indozo,indtau,ij)       &
266          + poids(2,2,1,2,1)*jphot(indtemp+1,indsza+1,indcol,indozo+1,indtau,ij)     &
267          + poids(2,2,2,1,1)*jphot(indtemp+1,indsza+1,indcol+1,indozo,indtau,ij)     &
268          + poids(2,2,2,2,1)*jphot(indtemp+1,indsza+1,indcol+1,indozo+1,indtau,ij)   &
269!
270          + poids(1,1,1,1,2)*jphot(indtemp,indsza,indcol,indozo,indtau+1,ij)         &
271          + poids(1,1,1,2,2)*jphot(indtemp,indsza,indcol,indozo+1,indtau+1,ij)       &
272          + poids(1,1,2,1,2)*jphot(indtemp,indsza,indcol+1,indozo,indtau+1,ij)       &
273          + poids(1,1,2,2,2)*jphot(indtemp,indsza,indcol+1,indozo+1,indtau+1,ij)     &
274          + poids(1,2,1,1,2)*jphot(indtemp,indsza+1,indcol,indozo,indtau+1,ij)       &
275          + poids(1,2,1,2,2)*jphot(indtemp,indsza+1,indcol,indozo+1,indtau+1,ij)     &
276          + poids(1,2,2,1,2)*jphot(indtemp,indsza+1,indcol+1,indozo,indtau+1,ij)     &
277          + poids(1,2,2,2,2)*jphot(indtemp,indsza+1,indcol+1,indozo+1,indtau+1,ij)   &
278          + poids(2,1,1,1,2)*jphot(indtemp+1,indsza,indcol,indozo,indtau+1,ij)       &
279          + poids(2,1,1,2,2)*jphot(indtemp+1,indsza,indcol,indozo+1,indtau+1,ij)     &
280          + poids(2,1,2,1,2)*jphot(indtemp+1,indsza,indcol+1,indozo,indtau+1,ij)     &
281          + poids(2,1,2,2,2)*jphot(indtemp+1,indsza,indcol+1,indozo+1,indtau+1,ij)   &
282          + poids(2,2,1,1,2)*jphot(indtemp+1,indsza+1,indcol,indozo,indtau+1,ij)     &
283          + poids(2,2,1,2,2)*jphot(indtemp+1,indsza+1,indcol,indozo+1,indtau+1,ij)   &
284          + poids(2,2,2,1,2)*jphot(indtemp+1,indsza+1,indcol+1,indozo,indtau+1,ij)   &
285          + poids(2,2,2,2,2)*jphot(indtemp+1,indsza+1,indcol+1,indozo+1,indtau+1,ij)
286         end do
287
288!     correction for sun distance
289
290         do ij = 1,nd
291!            j(l,ij) = j(l,ij)*(1.52/dist_sol)**2.
292            j(l,ij) = j(l,ij)*(1.0/dist_sol)**2.
293
294            ! Only during daylight.
295            if((ngrid.eq.1))then
296                  j(l,ij)= j(l,ij)* 0.25 ! globally averaged = divide by 4
297            elseif(diurnal .eqv. .false.) then
298                  j(l,ij)= j(l,ij) * fractcol
299            endif
300         end do
301
302!==========================================================================
303!     end of loop over vertical levels
304!==========================================================================
305
306      end do
307
308      else
309
310!==========================================================================
311!     night
312!==========================================================================
313
314         j(:,:) = 0.
315
316      end if
317
318! photodissociation rates numbering in the lookup table
319
320! jmars.20140930
321
322
323      j_o2_o         =  1      ! o2 + hv     -> o + o
324      j_o2_o1d       =  2      ! o2 + hv     -> o + o(1d)
325      j_co2_o        =  3      ! co2 + hv    -> co + o
326      j_co2_o1d      =  4      ! co2 + hv    -> co + o(1d)
327      j_o3_o1d       =  5      ! o3 + hv     -> o2 + o(1d)
328      j_o3_o         =  6      ! o3 + hv     -> o2 + o
329      j_h2o          =  7      ! h2o + hv    -> h + oh
330      j_h2o2         =  8      ! h2o2 + hv   -> oh + oh
331      j_ho2          =  9      ! ho2 + hv    -> oh + o
332      j_no           =  10     ! no + hv     -> n + o
333      j_no2          =  11     ! no2 + hv    -> no + o
334      j_hno3         =  12     ! hno3 + hv   -> no2 + oh
335      j_hno4         =  13     ! hno4 + hv   -> no2 + ho2
336
337! jmars.20111014
338
339!     j_o2_o         =  1      ! o2 + hv     -> o + o
340!     j_o2_o1d       =  2      ! o2 + hv     -> o + o(1d)
341!     j_co2_o        =  3      ! co2 + hv    -> co + o
342!     j_co2_o1d      =  4      ! co2 + hv    -> co + o(1d)
343!     j_o3_o1d       =  5      ! o3 + hv     -> o2 + o(1d)
344!     j_o3_o         =  6      ! o3 + hv     -> o2 + o
345!     j_h2o          =  7      ! h2o + hv    -> h + oh
346!     j_hdo          =  8      ! hdo + hv    -> d + oh
347!     j_h2o2         =  9      ! h2o2 + hv   -> oh + oh
348!     j_ho2          =  10     ! ho2 + hv    -> oh + o
349!     j_no2          =  11     ! no2 + hv    -> no + o
350!     j_ch4_ch3_h    =  12     ! ch4 + hv    -> ch3 + h
351!     j_ch4_1ch2_h2  =  13     ! ch4 + hv    -> 1ch2 + h2
352!     j_ch4_3ch2_h_h =  14     ! ch4 + hv    -> 3ch2 + h + h
353!     j_ch4_ch_h2_h  =  15     ! ch4 + hv    -> ch + h2 + h
354!     j_ch3o2h       =  16     ! ch3o2h + hv -> ch3o + oh
355!     j_ch2o_hco     =  17     ! ch2o + hv   -> h + hco
356!     j_ch2o_co      =  18     ! ch2o + hv   -> h2 + co
357!     j_ch3oh        =  19     ! ch3oh + hv  -> ch3o + h
358!     j_c2h6         =  20     ! c2h6 + hv   -> products
359!     j_hcl          =  21     ! hcl + hv    -> h + cl
360!     j_hocl         =  22     ! hocl + hv   -> oh + cl
361!     j_clo          =  23     ! clo + hv    -> o + cl
362!     j_so2          =  24     ! so2 + hv    -> so + o
363!     j_so           =  25     ! so + hv     -> s + o
364!     j_h2s          =  26     ! h2s + hv    -> hs + s
365!     j_so3          =  27     ! so2 + hv    -> so2 + o
366!     j_hno3         =  28     ! hno3 + hv   -> oh + no2
367!     j_hno4         =  29     ! hno4 + hv   -> ho2 + no2
368
369! fill v_phot array
370
371      v_phot(:,:) = 0.
372
373      do l = 1,lswitch-1
374         v_phot(l, 1) = j(l,j_o2_o)
375         v_phot(l, 2) = j(l,j_o2_o1d)
376         v_phot(l, 3) = j(l,j_co2_o)
377         v_phot(l, 4) = j(l,j_co2_o1d)
378         v_phot(l, 5) = j(l,j_o3_o1d)
379         v_phot(l, 6) = j(l,j_o3_o)
380         v_phot(l, 7) = j(l,j_h2o)
381         v_phot(l, 8) = j(l,j_h2o2)
382         v_phot(l, 9) = j(l,j_ho2)
383         v_phot(l,10) = j(l,j_no)
384         v_phot(l,11) = j(l,j_no2)
385      end do
386
387      return
388      end
389
390!*****************************************************************
Note: See TracBrowser for help on using the repository browser.