source: LMDZ4/trunk/libf/phylmd/o3_chem_m.F90 @ 5447

Last change on this file since 5447 was 1403, checked in by Laurent Fairhead, 14 years ago

Merged LMDZ4V5.0-dev branch changes r1292:r1399 to trunk.

Validation:
Validation consisted in compiling the HEAD revision of the trunk,
LMDZ4V5.0-dev branch and the merged sources and running different
configurations on local and SX8 machines comparing results.

Local machine: bench configuration, 32x24x11, gfortran

  • IPSLCM5A configuration (comparison between trunk and merged sources):
    • numerical convergence on dynamical fields over 3 days
    • start files are equivalent (except for RN and PB fields)
    • daily history files equivalent
  • MH07 configuration, new physics package (comparison between LMDZ4V5.0-dev branch and merged sources):
    • numerical convergence on dynamical fields over 3 days
    • start files are equivalent (except for RN and PB fields)
    • daily history files equivalent

SX8 machine (brodie), 96x95x39 on 4 processors:

  • IPSLCM5A configuration:
    • start files are equivalent (except for RN and PB fields)
    • monthly history files equivalent
  • MH07 configuration:
    • start files are equivalent (except for RN and PB fields)
    • monthly history files equivalent

Changes to the makegcm and create_make_gcm scripts to take into account
main programs in F90 files


Fusion de la branche LMDZ4V5.0-dev (r1292:r1399) au tronc principal

Validation:
La validation a consisté à compiler la HEAD de le trunk et de la banche
LMDZ4V5.0-dev et les sources fusionnées et de faire tourner le modéle selon
différentes configurations en local et sur SX8 et de comparer les résultats

En local: 32x24x11, config bench/gfortran

  • pour une config IPSLCM5A (comparaison tronc/fusion):
    • convergence numérique sur les champs dynamiques après 3 jours
    • restart et restartphy égaux (à part sur RN et Pb)
    • fichiers histoire égaux
  • pour une config nlle physique (MH07) (comparaison LMDZ4v5.0-dev/fusion):
    • convergence numérique sur les champs dynamiques après 3 jours
    • restart et restartphy égaux
    • fichiers histoire équivalents

Sur brodie, 96x95x39 sur 4 proc:

  • pour une config IPSLCM5A:
    • restart et restartphy égaux (à part sur RN et PB)
    • pas de différence dans les fichiers histmth.nc
  • pour une config MH07
    • restart et restartphy égaux (à part sur RN et PB)
    • pas de différence dans les fichiers histmth.nc

Changement sur makegcm et create_make-gcm pour pouvoir prendre en compte des
programmes principaux en *F90

File size: 5.3 KB
RevLine 
[1379]1! $Id$
2module o3_chem_m
3
4  IMPLICIT none
5
6  private o3_prod
7
8contains
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
172end module o3_chem_m
Note: See TracBrowser for help on using the repository browser.