source: trunk/LMDZ.TITAN/libf/muphytitan/mm_microphysic.f90 @ 1897

Last change on this file since 1897 was 1897, checked in by jvatant, 7 years ago

Making Titan's hazy again - part II
+ Major updates of J.Burgalat YAMMS library and optical coupling, including :
++ Added the routines for haze optics inside YAMMS
++ Calling rad. transf. with interactive haze is plugged
in but should stay unactive as long as the microphysics is
in test phase : cf "uncoupl_optic_haze" flag : true for now !
++ Also some sanity checks for negative tendencies and
some others upkeep of YAMMS model
+ Also added a temporary CPP key USE_QTEST in physiq_mod
that enables to have microphysical tendencies separated
from dynamics for debugging and test phases
-- JVO and JB

File size: 12.9 KB
Line 
1! Copyright 2013-2015,2017 Université de Reims Champagne-Ardenne
2! Contributor: J. Burgalat (GSMA, URCA)
3! email of the author : jeremie.burgalat@univ-reims.fr
4!
5! This software is a computer program whose purpose is to compute
6! microphysics processes using a two-moments scheme.
7!
8! This library is governed by the CeCILL-B license under French law and
9! abiding by the rules of distribution of free software.  You can  use,
10! modify and/ or redistribute the software under the terms of the CeCILL-B
11! license as circulated by CEA, CNRS and INRIA at the following URL
12! "http://www.cecill.info".
13!
14! As a counterpart to the access to the source code and  rights to copy,
15! modify and redistribute granted by the license, users are provided only
16! with a limited warranty  and the software's author,  the holder of the
17! economic rights,  and the successive licensors  have only  limited
18! liability.
19!
20! In this respect, the user's attention is drawn to the risks associated
21! with loading,  using,  modifying and/or developing or reproducing the
22! software by the user in light of its specific status of free software,
23! that may mean  that it is complicated to manipulate,  and  that  also
24! therefore means  that it is reserved for developers  and  experienced
25! professionals having in-depth computer knowledge. Users are therefore
26! encouraged to load and test the software's suitability as regards their
27! requirements in conditions enabling the security of their systems and/or
28! data to be ensured and,  more generally, to use and operate it in the
29! same conditions as regards security.
30!
31! The fact that you are presently reading this means that you have had
32! knowledge of the CeCILL-B license and that you accept its terms.
33
34!! file: mm_microphysic.f90
35!! brief: Microphysic processes interface module.
36!! author: J. Burgalat
37!! date: 2013-2015,2017
38
39MODULE MM_MICROPHYSIC
40  !! Microphysic processes interface module.
41  USE MM_MPREC
42  USE MM_GLOBALS
43  USE MM_HAZE
44  USE MM_CLOUDS
45  USE MM_METHODS
46  IMPLICIT NONE
47
48  PRIVATE
49
50  PUBLIC :: mm_muphys, mm_diagnostics, mm_get_radii
51
52  !! Interface to main microphysics subroutine.
53  !!
54  !! The interface computes calls either all the microphysics processes ([[mm_microphysic(module):muphys_all(function)]]
55  !! or only aerosols microphysics ([[mm_microphysic(module):muphys_nocld(function)]]) in a single call.
56  INTERFACE mm_muphys
57    MODULE PROCEDURE muphys_all, muphys_nocld
58  END INTERFACE
59
60  CONTAINS
61
62
63   
64  FUNCTION muphys_all(dm0a_s,dm3a_s,dm0a_f,dm3a_f,dm0n,dm3n,dm3i,dgazs) RESULT(ret)
65    !! Compute the evolution of moments tracers through haze and clouds microphysics processes.
66    !!
67    !! This method computes the evolution of all the microphysics tracers, given under the form of moments
68    !! (and molar fraction for cloud condensible species) during a time step.
69    !!
70    !! The method requires that global variables of the model (i.e. variables declared in [[mm_globals(module)]]
71    !! module) are initialized/updated correctly (see [[mm_globals(module):mm_global_init(interface)]],
72    !! [[mm_globals(module):mm_column_init(function)]],[[mm_globals(module):mm_aerosols_init(function)]] and
73    !! [[mm_globals(module):mm_clouds_init(function)]]).
74    !!
75    !! The tendencies returned by the method are defined on the vertical __layers__ of the model from the __GROUND__ to
76    !! the __TOP__ of the atmosphere. They should be added to the input variables used in the initialization methods
77    !! before the latter are called to initialize a new step.
78    !! @note
79    !! __dm3i__ and __dgazs__ are 2D-arrays with vertical __layers__ in the 1st dimension and the number of
80    !! ice components in the 2nd. They share the same _species_ indexing.
81    !!
82    !! It should be a 2D-array with the vertical layers in first dimension and the number of ice components in the second.
83    REAL(kind=mm_wp), INTENT(out), DIMENSION(:)   :: dm0a_s
84      !! Tendency of the 0th order moment of the spherical mode distribution (\(m^{-2}\)).
85    REAL(kind=mm_wp), INTENT(out), DIMENSION(:)   :: dm3a_s
86      !! Tendency of the 3rd order moment of the spherical mode distribution (\(m^{3}.m^{-2}\)).
87    REAL(kind=mm_wp), INTENT(out), DIMENSION(:)   :: dm0a_f
88      !! Tendency of the 0th order moment of the fractal mode distribution (\(m^{-2}\)).
89    REAL(kind=mm_wp), INTENT(out), DIMENSION(:)   :: dm3a_f
90      !! Tendency of the 3rd order moment of the fractal mode distribution (\(m^{3}.m^{-2}\)).
91    REAL(kind=mm_wp), INTENT(out), DIMENSION(:)   :: dm0n
92      !! Tendency of the 0th order moment of the _CCN_ distribution (\(m^{-2}\)).
93    REAL(kind=mm_wp), INTENT(out), DIMENSION(:)   :: dm3n
94      !! Tendency of the 3rd order moment of the _CCN_ distribution (\(m^{3}.m^{-2}\)).
95    REAL(kind=mm_wp), INTENT(out), DIMENSION(:,:) :: dm3i
96      !! Tendencies of the 3rd order moments of each ice components (\(m^{3}.m^{-2}\)).
97    REAL(kind=mm_wp), INTENT(out), DIMENSION(:,:) :: dgazs
98      !! Tendencies of each condensible gaz species (\(mol.mol^{-1}\)).
99    LOGICAL :: ret
100      !! .true. on success (i.e. model has been initialized at least once previously), .false. otherwise.
101    REAL(kind=mm_wp), DIMENSION(SIZE(dm0a_s)) :: zdm0a_f,zdm3a_f
102    INTEGER                                   :: i
103    ! Checks initialization
104    ret = (mm_ini_col.AND.mm_ini_aer.AND.(.NOT.mm_w_clouds.OR.mm_ini_cld))
105    IF (.NOT.ret) RETURN
106    ! Calls haze microphysics (-> m-3)
107    call mm_haze_microphysics(dm0a_s,dm3a_s,dm0a_f,dm3a_f)
108    IF (mm_w_clouds) THEN
109      ! Calls cloud microphysics (-> m-3)
110      call mm_cloud_microphysics(zdm0a_f,zdm3a_f,dm0n,dm3n,dm3i,dgazs)
111      ! add temporary aerosols tendencies (-> m-3)
112      dm0a_f = dm0a_f + zdm0a_f  ; dm3a_f = dm3a_f + zdm3a_f
113      ! reverse directly clouds tendencies (-> m-2)
114      dm0n   = dm0n(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
115      dm3n   = dm3n(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
116      ! sanity check for clouds tendencies
117      WHERE (mm_m0ccn+dm0n < 0) ; dm0n = -mm_m0ccn ; END WHERE
118      WHERE (mm_m3ccn+dm3n < 0) ; dm3n = -mm_m3ccn ; END WHERE
119      DO i=1,mm_nesp
120        dm3i(:,i)  = dm3i(mm_nla:1:-1,i)  * mm_dzlev(mm_nla:1:-1)
121        WHERE (mm_m3ice+dm3i < 0) ; dm3i = -mm_m3ice ; END WHERE
122        dgazs(:,i) = dgazs(mm_nla:1:-1,i)
123        ! no sanity check for gazs, let's prey.
124      ENDDO
125    ELSE
126      dm0n = 0._mm_wp ; dm3n = 0._mm_wp ; dm3i = 0._mm_wp ; dgazs = 0._mm_wp
127    ENDIF
128    ! multiply by altitude thickness and reverse vectors so they go from ground to top :)
129    dm0a_s = dm0a_s(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
130    dm3a_s = dm3a_s(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
131    dm0a_f = dm0a_f(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
132    dm3a_f = dm3a_f(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
133    ! sanity check
134    WHERE (mm_m0aer_s+dm0a_s < 0) ; dm0a_s = -mm_m0aer_s ; END WHERE
135    WHERE (mm_m3aer_s+dm3a_f < 0) ; dm3a_s = -mm_m3aer_s ; END WHERE
136    WHERE (mm_m0aer_f+dm0a_f < 0) ; dm0a_f = -mm_m0aer_f ; END WHERE
137    WHERE (mm_m3aer_f+dm3a_f < 0) ; dm3a_f = -mm_m3aer_f ; END WHERE
138   
139    RETURN
140  END FUNCTION muphys_all
141
142  FUNCTION muphys_nocld(dm0a_s,dm3a_s,dm0a_f,dm3a_f) RESULT(ret)
143    !! Compute the evolution of moments tracers through haze microphysics only.
144    !!
145    !! This method is a __light__ version of [[mm_microphysic(module):muphys_all(function)]] where
146    !! only haze microphysics is computed and its tendencies returned.
147    !!
148    !! The method has the same requirements and remarks than [[mm_microphysic(module):muphys_all(function)]].
149    REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm0a_s
150      !! Tendency of the 0th order moment of the spherical mode distribution (\(m^{-2}\)).
151    REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm3a_s
152      !! Tendency of the 3rd order moment of the spherical mode distribution (\(m^{3}.m^{-2}\)).
153    REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm0a_f
154      !! Tendency of the 0th order moment of the fractal mode distribution (\(m^{-2}\)).
155    REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm3a_f
156      !! Tendency of the 3rd order moment of the fractal mode distribution (\(m^{3}.m^{-2}\)).
157    LOGICAL :: ret
158      !! .true. on succes (i.e. model has been initialized at least once previously), .false. otherwise.
159    ret = (mm_ini_col.AND.mm_ini_aer)
160    IF (.NOT.ret) RETURN
161    IF (mm_w_clouds.AND.mm_debug) THEN
162      WRITE(*,'(a)') "WARNING: clouds microphysics enabled but will not be &
163                     &computed... (wrong interface)"
164    ENDIF
165    ! Calls haze microphysics
166    call mm_haze_microphysics(dm0a_s,dm3a_s,dm0a_f,dm3a_f)
167    ! reverse vectors so they go from ground to top :)
168    dm0a_s = dm0a_s(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
169    dm3a_s = dm3a_s(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
170    dm0a_f = dm0a_f(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
171    dm3a_f = dm3a_f(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
172    ! sanity check
173    WHERE (mm_m0aer_s+dm0a_s < 0) ; dm0a_s = -mm_m0aer_s ; END WHERE
174    WHERE (mm_m3aer_s+dm3a_f < 0) ; dm3a_s = -mm_m3aer_s ; END WHERE
175    WHERE (mm_m0aer_f+dm0a_f < 0) ; dm0a_f = -mm_m0aer_f ; END WHERE
176    WHERE (mm_m3aer_f+dm3a_f < 0) ; dm3a_f = -mm_m3aer_f ; END WHERE
177    RETURN
178  END FUNCTION muphys_nocld
179
180  SUBROUTINE mm_diagnostics(aer_prec,aer_s_flux,aer_f_flux,         &
181                            ccn_prec,ccn_flux, ice_prec,ice_fluxes, &
182                            gazs_sat)
183    !! Get various diagnostic fields of the microphysics.
184    !!
185    !! The current diagnostics saved during microphysic computation are :
186    !!
187    !! - Mass fluxes (aerosols -both mode-, CCN and ices)
188    !! - Precipitations (aerosols -total-, CCN and ices)
189    !! - condensible gazes saturation ratio
190    !!
191    !! @note
192    !! Fluxes values are always negative as they account for sedimentation fluxes. They are set as
193    !! vector (for aerosols and CCN) or 2D-array (with the vertical structure in the first dimension
194    !! and number of species in the second, for ice) and are ordered from __GROUND__ to __TOP__.
195    !!
196    !! @note
197    !! Precipitations are always positive and defined in meters. For ice, it is set as a vector with
198    !! the precipitations of each cloud ice components.
199    !!
200    !! @note
201    !! __ccnprec__, __iceprec__, __icefluxes__ and __gazsat__ are always set to 0 if clouds
202    !! microphysics is disabled (see [[mm_globals(module):mm_w_clouds(variable)]] documentation).
203    REAL(kind=mm_wp), INTENT(out), OPTIONAL                 :: aer_prec   !! Aerosols precipitations (both modes) (m).
204    REAL(kind=mm_wp), INTENT(out), OPTIONAL                 :: ccn_prec   !! CCN precipitations (m).
205    REAL(kind=mm_wp), INTENT(out), OPTIONAL, DIMENSION(:)   :: aer_s_flux !! Spherical aerosol mass flux (\(kg.m^{-2}.s^{-1}\)).
206    REAL(kind=mm_wp), INTENT(out), OPTIONAL, DIMENSION(:)   :: aer_f_flux !! Fractal aerosol mass flux (\(kg.m^{-2}.s^{-1}\)).
207    REAL(kind=mm_wp), INTENT(out), OPTIONAL, DIMENSION(:)   :: ccn_flux   !! CCN mass flux (\(kg.m^{-2}.s^{-1}\)).
208    REAL(kind=mm_wp), INTENT(out), OPTIONAL, DIMENSION(:,:) :: ice_fluxes !! Ice sedimentation fluxes (\(kg.m^{-2}.s^{-1}\)).
209    REAL(kind=mm_wp), INTENT(out), OPTIONAL, DIMENSION(:,:) :: gazs_sat   !! Condensible gaz saturation ratios (--).
210    REAL(kind=mm_wp), INTENT(out), OPTIONAL, DIMENSION(:)   :: ice_prec   !! Ice precipitations (m).
211
212    IF (PRESENT(aer_prec))   aer_prec   = ABS(mm_aer_prec)
213    IF (PRESENT(aer_s_flux)) aer_s_flux = -mm_aer_s_flux(mm_nla:1:-1)
214    IF (PRESENT(aer_f_flux)) aer_f_flux = -mm_aer_f_flux(mm_nla:1:-1)
215
216    IF (mm_w_clouds) THEN
217      IF (PRESENT(ccn_prec))   ccn_prec   = ABS(mm_ccn_prec)
218      IF (PRESENT(ice_prec))   ice_prec   = ABS(mm_ice_prec)
219      IF (PRESENT(ccn_flux))   ccn_flux   = -mm_ccn_flux(mm_nla:1:-1)
220      IF (PRESENT(ice_fluxes)) ice_fluxes = -mm_ice_fluxes(mm_nla:1:-1,:)
221      IF (PRESENT(gazs_sat))   gazs_sat   =  mm_gazs_sat(mm_nla:1:-1,:)
222    ELSE
223      IF (PRESENT(ccn_prec))   ccn_prec   = 0._mm_wp
224      IF (PRESENT(ice_prec))   ice_prec   = 0._mm_wp
225      IF (PRESENT(ccn_flux))   ccn_flux   = 0._mm_wp
226      IF (PRESENT(ice_fluxes)) ice_fluxes = 0._mm_wp
227      IF (PRESENT(gazs_sat))   gazs_sat   = 0._mm_wp
228    ENDIF
229  END SUBROUTINE mm_diagnostics
230
231  SUBROUTINE mm_get_radii(rcsph,rcfra,rccld)
232    !! Get characteristic radii of microphysical tracers on the vertical grid.
233    REAL(kind=mm_wp), INTENT(out), DIMENSION(:), OPTIONAL :: rcsph !! Spherical mode characteristic radius
234    REAL(kind=mm_wp), INTENT(out), DIMENSION(:), OPTIONAL :: rcfra !! Fractal mode characteristic radius
235    REAL(kind=mm_wp), INTENT(out), DIMENSION(:), OPTIONAL :: rccld !! Cloud drops mean radius
236    IF (mm_ini_aer) THEN
237      IF (PRESENT(rcsph)) rcsph = mm_rcs(mm_nla:1:-1)
238      IF (PRESENT(rcfra)) rcfra = mm_rcf(mm_nla:1:-1)
239    ELSE
240      IF (PRESENT(rcsph)) rcsph = 0._mm_wp
241      IF (PRESENT(rcfra)) rcfra = 0._mm_wp
242    ENDIF
243    IF (PRESENT(rccld)) THEN
244      IF (mm_w_clouds.AND.mm_ini_cld) THEN
245        rccld = mm_drad(mm_nla:1:-1)
246      ELSE
247        rccld = 0._mm_wp
248      ENDIF
249    ENDIF
250  END SUBROUTINE mm_get_radii
251
252END MODULE MM_MICROPHYSIC
253
Note: See TracBrowser for help on using the repository browser.