My Project
 All Classes Files Functions Variables Macros
o3_chem_m.F90
Go to the documentation of this file.
1 ! $Id$
2 module o3_chem_m
3 
4  IMPLICIT none
5 
6  private o3_prod
7 
8 contains
9 
10  subroutine o3_chem(julien, gmtime, t_seri, zmasse, pdtphys, rlat, rlon, q)
11 
12  ! This procedure evolves the ozone mass fraction through a time
13  ! step taking only chemistry into account.
14 
15  ! All the 2-dimensional arrays are on the partial "physics" grid.
16  ! Their shape is "(/klon, llm/)".
17  ! Index "(i, :)" is for longitude "rlon(i)", latitude "rlat(i)".
18 
19  use assert_m, only: assert
20  use dimphy, only: klon
21  use regr_pr_comb_coefoz_m, only: c_Mob, a4_mass, a2, r_het_interm
22 
23  integer, intent(in):: julien ! jour julien, 1 <= julien <= 360
24  real, intent(in):: gmtime ! heure de la journée en fraction de jour
25  real, intent(in):: t_seri(:, :) ! (klon, llm) temperature, in K
26 
27  real, intent(in):: zmasse(:, :) ! (klon, llm)
28  ! (column-density of mass of air in a cell, in kg m-2)
29  ! "zmasse(:, k)" is for layer "k".)
30 
31  real, intent(in):: pdtphys ! time step for physics, in s
32 
33  REAL, intent(in):: rlat(:), rlon(:)
34  ! (longitude and latitude of each horizontal position, in degrees)
35 
36  real, intent(inout):: q(:, :) ! (klon, llm) mass fraction of ozone
37  ! "q(:, k)" is at middle of layer "k".)
38 
39  ! Variables local to the procedure:
40  include "dimensions.h"
41  include "comconst.h"
42  ! (for "pi")
43  integer k
44 
45  real c(klon, llm)
46  ! (constant term during a time step in the net mass production
47  ! rate of ozone by chemistry, per unit mass of air, in s-1)
48  ! "c(:, k)" is at middle of layer "k".)
49 
50  real b(klon, llm)
51  ! (coefficient of "q" in the net mass production
52  ! rate of ozone by chemistry, per unit mass of air, in s-1)
53  ! "b(:, k)" is at middle of layer "k".)
54 
55  real dq_o3_chem(klon, llm)
56  ! (variation of ozone mass fraction due to chemistry during a time step)
57  ! "dq_o3_chem(:, k)" is at middle of layer "k".)
58 
59  real earth_long
60  ! (longitude vraie de la Terre dans son orbite solaire, par
61  ! rapport au point vernal (21 mars), en degrés)
62 
63  real pmu0(klon) ! mean of cosine of solar zenith angle during "pdtphys"
64  real trash1
65  real trash2(klon)
66 
67  !-------------------------------------------------------------
68 
69  call assert(klon == (/size(q, 1), size(t_seri, 1), size(zmasse, 1), &
70  size(rlat), size(rlon)/), "o3_chem klon")
71  call assert(llm == (/size(q, 2), size(t_seri, 2), size(zmasse, 2)/), &
72  "o3_chem llm")
73 
74  c = c_mob + a4_mass * t_seri
75 
76  ! Compute coefficient "b":
77 
78  ! Heterogeneous chemistry is only at low temperature:
79  where (t_seri < 195.)
80  b = r_het_interm
81  elsewhere
82  b = 0.
83  end where
84 
85  ! Heterogeneous chemistry is only during daytime:
86  call orbite(real(julien), earth_long, trash1)
87  call zenang(earth_long, gmtime, pdtphys, rlat, rlon, pmu0, trash2)
88  forall (k = 1: llm)
89  where (pmu0 <= cos(87. / 180. * pi)) b(:, k) = 0.
90  end forall
91 
92  b = b + a2
93 
94  ! Midpoint method:
95 
96  ! Trial step to the midpoint:
97  dq_o3_chem = o3_prod(q, zmasse, c, b) * pdtphys / 2
98  ! "Real" step across the whole interval:
99  dq_o3_chem = o3_prod(q + dq_o3_chem, zmasse, c, b) * pdtphys
100  q = q + dq_o3_chem
101 
102  ! Confine the mass fraction:
103  q = min(max(q, 0.), .01)
104 
105  end subroutine o3_chem
106 
107  !*************************************************
108 
109  function o3_prod(q, zmasse, c, b)
110 
111  ! This function computes the production rate of ozone by chemistry.
112 
113  ! All the 2-dimensional arrays are on the partial "physics" grid.
114  ! Their shape is "(/klon, llm/)".
115  ! Index "(i, :)" is for longitude "rlon(i)", latitude "rlat(i)".
116 
117  use regr_pr_comb_coefoz_m, only: a6_mass
118  use assert_m, only: assert
119  use dimphy, only: klon
120 
121  real, intent(in):: q(:, :) ! mass fraction of ozone
122  ! "q(:, k)" is at middle of layer "k".)
123 
124  real, intent(in):: zmasse(:, :)
125  ! (column-density of mass of air in a layer, in kg m-2)
126  ! ("zmasse(:, k)" is for layer "k".)
127 
128  real, intent(in):: c(:, :)
129  ! (constant term during a time step in the net mass production
130  ! rate of ozone by chemistry, per unit mass of air, in s-1)
131  ! "c(:, k)" is at middle of layer "k".)
132 
133  real, intent(in):: b(:, :)
134  ! (coefficient of "q" in the net mass production rate of ozone by
135  ! chemistry, per unit mass of air, in s-1)
136  ! ("b(:, k)" is at middle of layer "k".)
137 
138  include "dimensions.h"
139 
140  real o3_prod(klon, llm)
141  ! (net mass production rate of ozone by chemistry, per unit mass
142  ! of air, in s-1)
143  ! ("o3_prod(:, k)" is at middle of layer "k".)
144 
145  ! Variables local to the procedure:
146 
147  real sigma_mass(klon, llm)
148  ! (mass column-density of ozone above point, in kg m-2)
149  ! ("sigma_mass(:, k)" is at middle of layer "k".)
150 
151  integer k
152 
153  !-------------------------------------------------------------------
154 
155  call assert(klon == (/size(q, 1), size(zmasse, 1), size(c, 1), &
156  size(b, 1)/), "o3_prod 1")
157  call assert(llm == (/size(q, 2), size(zmasse, 2), size(c, 2), &
158  size(b, 2)/), "o3_prod 2")
159 
160  ! Compute the column-density above the base of layer
161  ! "k", and, as a first approximation, take it as column-density
162  ! above the middle of layer "k":
163  sigma_mass(:, llm) = zmasse(:, llm) * q(:, llm) ! top layer
164  do k = llm - 1, 1, -1
165  sigma_mass(:, k) = sigma_mass(:, k+1) + zmasse(:, k) * q(:, k)
166  end do
167 
168  o3_prod = c + b * q + a6_mass * sigma_mass
169 
170  end function o3_prod
171 
172 end module o3_chem_m