source: trunk/LMDZ.TITAN/libf/phytitan/calmufi.F90 @ 3709

Last change on this file since 3709 was 3682, checked in by lrosset, 8 months ago

Titan microphysics and physics : Outputs the nucleation rates and growth rates for the condensible species. (LR)

  • Property svn:executable set to *
File size: 9.3 KB
Line 
1
2
3SUBROUTINE calmufi(dt, plev, zlev, play, zlay, g3d, temp, pq, zdqfi, zdq)
4
5  !! Interface subroutine to YAMMS model for Titan LMDZ GCM.
6  !!
7  !! The subroutine computes the microphysics processes for a single vertical column.
8  !!
9  !! - All input vectors are assumed to be defined from GROUND to TOP of the atmosphere.
10  !! - All output vectors are defined from GROUND to TOP of the atmosphere.
11  !! - Only tendencies are returned.
12  !!
13  !! @important
14  !! The method assumes global initialization of YAMMS model (and extras) has been already
15  !! done elsewhere.
16  !!
17  !! Authors : J.Burgalat, J.Vatant d'Ollone - 2017
18  !! Modified : B. de Batz de Trenquelléon (2023)
19  !!
20  USE MMP_GCM
21  USE tracer_h
22  USE callkeys_mod, only : callclouds
23  USE muphy_diag
24  IMPLICIT NONE
25
26  REAL(kind=8), INTENT(IN) :: dt  !! Physics timestep (s).
27 
28  REAL(kind=8), DIMENSION(:,:), INTENT(IN) :: plev  !! Pressure levels (Pa).
29  REAL(kind=8), DIMENSION(:,:), INTENT(IN) :: zlev  !! Altitude levels (m).
30  REAL(kind=8), DIMENSION(:,:), INTENT(IN) :: play  !! Pressure layers (Pa).
31  REAL(kind=8), DIMENSION(:,:), INTENT(IN) :: zlay  !! Altitude at the center of each layer (m).
32  REAL(kind=8), DIMENSION(:,:), INTENT(IN) :: g3d   !! Latitude-Altitude depending gravitational acceleration (m.s-2).
33  REAL(kind=8), DIMENSION(:,:), INTENT(IN) :: temp  !! Temperature at the center of each layer (K).
34
35  REAL(kind=8), DIMENSION(:,:,:), INTENT(IN)  :: pq    !! Tracers (\(X.kg^{-1}}\)).
36  REAL(kind=8), DIMENSION(:,:,:), INTENT(IN)  :: zdqfi !! Tendency from former processes for tracers (\(X.kg^{-1}}\)).
37  REAL(kind=8), DIMENSION(:,:,:), INTENT(OUT) :: zdq   !! Microphysical tendency for tracers (\(X.kg^{-1}}\)).
38 
39  REAL(kind=8), DIMENSION(:,:,:), ALLOCATABLE :: zq !! Local tracers updated from former processes (\(X.kg^{-1}}\)).
40 
41  REAL(kind=8), DIMENSION(:), ALLOCATABLE :: m0as !! 0th order moment of the spherical mode (\(m^{-2}\)).
42  REAL(kind=8), DIMENSION(:), ALLOCATABLE :: m3as !! 3rd order moment of the spherical mode (\(m^{3}.m^{-2}\)).
43  REAL(kind=8), DIMENSION(:), ALLOCATABLE :: m0af !! 0th order moment of the fractal mode (\(m^{-2}\)).
44  REAL(kind=8), DIMENSION(:), ALLOCATABLE :: m3af !! 3rd order moment of the fractal mode (\(m^{3}.m^{-2}\)).
45
46  REAL(kind=8), DIMENSION(:), ALLOCATABLE   :: m0n  !! 0th order moment of the CCN distribution (\(m^{-2}\)).
47  REAL(kind=8), DIMENSION(:), ALLOCATABLE   :: m3n  !! 3rd order moment of the CCN distribution (\(m^{3}.m^{-2}\)).
48  REAL(kind=8), DIMENSION(:,:), ALLOCATABLE :: m3i  !! 3rd order moments of the ice components (\(m^{3}.m^{-2}\)).
49  REAL(kind=8), DIMENSION(:,:), ALLOCATABLE :: gazs !! Condensible species gazs molar fraction (\(mol.mol^{-1}\)).
50
51  REAL(kind=8), DIMENSION(:), ALLOCATABLE   :: dm0as !! Tendency of the 0th order moment of the spherical mode distribution (\(m^{-2}\)).
52  REAL(kind=8), DIMENSION(:), ALLOCATABLE   :: dm3as !! Tendency of the 3rd order moment of the spherical mode distribution (\(m^{3}.m^{-2}\)).
53  REAL(kind=8), DIMENSION(:), ALLOCATABLE   :: dm0af !! Tendency of the 0th order moment of the fractal mode distribution (\(m^{-2}\)).
54  REAL(kind=8), DIMENSION(:), ALLOCATABLE   :: dm3af !! Tendency of the 3rd order moment of the fractal mode distribution (\(m^{3}.m^{-2}\)).
55  REAL(kind=8), DIMENSION(:), ALLOCATABLE   :: dm0n  !! Tendency of the 0th order moment of the _CCN_ distribution (\(m^{-2}\)).
56  REAL(kind=8), DIMENSION(:), ALLOCATABLE   :: dm3n  !! Tendency of the 3rd order moment of the _CCN_ distribution (\(m^{3}.m^{-2}\)).
57  REAL(kind=8), DIMENSION(:,:), ALLOCATABLE :: dm3i  !! Tendencies of the 3rd order moments of each ice components (\(m^{3}.m^{-2}\)).
58  REAL(kind=8), DIMENSION(:,:), ALLOCATABLE :: dgazs !! Tendencies of each condensible gaz species !(\(mol.mol^{-1}\)).
59
60  REAL(kind=8), DIMENSION(:,:), ALLOCATABLE ::  int2ext !! (\(m^{-2}\)).
61  REAL(kind=8), DIMENSION(:), ALLOCATABLE   :: tmp
62  TYPE(error) :: err
63
64  INTEGER :: ilon, i,nices
65  INTEGER :: nq,nlon,nlay
66
67  ! Read size of arrays
68  nq    = size(pq,DIM=3)
69  nlon  = size(play,DIM=1)
70  nlay  = size(play,DIM=2)
71  nices = size(ices_indx)
72  ! Conversion intensive to extensive
73  ALLOCATE( int2ext(nlon,nlay) ) 
74
75  ! Allocate arrays
76  ALLOCATE( zq(nlon,nlay,nq) )
77
78  ALLOCATE( m0as(nlay) )
79  ALLOCATE( m3as(nlay) )
80  ALLOCATE( m0af(nlay) )
81  ALLOCATE( m3af(nlay) )
82  ALLOCATE( m0n(nlay) )
83  ALLOCATE( m3n(nlay) )
84  ALLOCATE( m3i(nlay,nices) )
85  ALLOCATE( gazs(nlay,nices) )
86
87  ALLOCATE( dm0as(nlay) )
88  ALLOCATE( dm3as(nlay) )
89  ALLOCATE( dm0af(nlay) )
90  ALLOCATE( dm3af(nlay) )
91  ALLOCATE( dm0n(nlay) )
92  ALLOCATE( dm3n(nlay) )
93  ALLOCATE( dm3i(nlay,nices) )
94  ALLOCATE( dgazs(nlay,nices) )
95
96  ! Initialization of zdq here since intent=out and no action performed on every tracers
97  zdq(:,:,:) = 0.D0
98
99  ! Initialize tracers updated with former processes from physics
100  zq(:,:,:) = pq(:,:,:) + zdqfi(:,:,:)*dt
101
102  ! Loop on horizontal grid points
103  DO ilon = 1, nlon
104    ! Convert tracers to extensive ( except for gazs where we work with molar mass ratio )
105    ! We suppose a given order of tracers !
106    int2ext(ilon,:) = ( plev(ilon,1:nlay)-plev(ilon,2:nlay+1) ) / g3d(ilon,1:nlay)
107   
108    ! Check because of the threshold of small tracers values in the dynamics
109    ! WARNING : With this patch it enables to handles the small values required
110    ! by YAMMS, but still it might still leads to some unphysical values of
111    ! radii inside YAMMS, harmless for now, but who might be a problem the day
112    ! you'll want to compute optics from the radii.
113    WHERE (pq(ilon,:,1) > 2.D-200 .AND. pq(ilon,:,2) > 2.D-200) ! Test on both moments to avoid divergences if one hit the threshold but not the other
114      m0as(:) = zq(ilon,:,1) * int2ext(ilon,:)                  ! It can still be a pb if both m0 and m3 has been set to epsilon at the beginning of dynamics
115      m3as(:) = zq(ilon,:,2) * int2ext(ilon,:)                  ! then mixed, even though both are above the threshold, their ratio can be nonsense
116    ELSEWHERE
117      m0as(:) = 0.D0
118      m3as(:) = 0.D0
119    ENDWHERE
120    WHERE (pq(ilon,:,3) > 2.D-200 .AND. pq(ilon,:,4) > 2.D-200)
121      m0af(:) = zq(ilon,:,3) * int2ext(ilon,:)
122      m3af(:) = zq(ilon,:,4) * int2ext(ilon,:)
123    ELSEWHERE
124      m0af(:) = 0.D0
125      m3af(:) = 0.D0
126    ENDWHERE
127   
128    if (callclouds) then ! if call clouds
129      m0n(:) = zq(ilon,:,5) * int2ext(ilon,:)
130      m3n(:) = zq(ilon,:,6) * int2ext(ilon,:)
131      do i=1,nices
132        m3i(:,i)  = zq(ilon,:,ices_indx(i)) * int2ext(ilon,:)
133        gazs(:,i) = zq(ilon,:,gazs_indx(i)) / rat_mmol(gazs_indx(i)) ! For gazs we work on the full tracer array !!
134        ! We use the molar mass ratio from GCM in case there is discrepancy with the mm one
135      enddo
136    endif
137
138    ! Hackin the pressure level
139    tmp = plev(ilon,:)
140    if (tmp(nlay+1) == 0.0) then
141      tmp(nlay+1) = 2*tmp(nlay) - tmp(nlay-1)
142    endif
143
144    ! Initialize YAMMS atmospheric column
145    err = mm_column_init(tmp,zlev(ilon,:),play(ilon,:),zlay(ilon,:),temp(ilon,:)) ; IF (err /= 0) call abort_program(err)
146    ! Initialize YAMMS aerosols moments column
147    err = mm_aerosols_init(m0as,m3as,m0af,m3af) ; IF (err /= 0) call abort_program(err)
148    IF (callclouds) THEN ! call clouds
149      err = mm_clouds_init(m0n,m3n,m3i,gazs) ; IF (err /= 0) call abort_program(err)
150    ENDIF
151
152    ! Check on size (???)
153
154    ! initializes tendencies:
155    dm0as(:) = 0._mm_wp ; dm3as(:) = 0._mm_wp ; dm0af(:) = 0._mm_wp ; dm3af(:) = 0._mm_wp
156    dm0n(:) = 0._mm_wp ; dm3n(:) = 0._mm_wp ; dm3i(:,:) = 0._mm_wp ; dgazs(:,:) = 0._mm_wp
157   
158    ! call microphysics
159    IF (callclouds) THEN ! call clouds
160      IF(.NOT.mm_muphys(dm0as,dm3as,dm0af,dm3af,dm0n,dm3n,dm3i,dgazs)) &
161        call abort_program(error("mm_muphys aborted -> initialization not done !",-1))
162    ELSE
163      IF (.NOT.mm_muphys(dm0as,dm3as,dm0af,dm3af)) &
164        call abort_program(error("mm_muphys aborted -> initialization not done !",-1))
165    ENDIF
166    ! save diags (if no clouds, relevant arrays will be set to 0 !)
167    call mm_diagnostics(dt,mmd_aer_prec(ilon),mmd_aer_s_w(ilon,:),mmd_aer_f_w(ilon,:),mmd_aer_s_flux(ilon,:),mmd_aer_f_flux(ilon,:),  &
168                        mmd_ccn_prec(ilon),mmd_ccn_w(ilon,:),mmd_ccn_flux(ilon,:),mmd_ice_prec(ilon,:),   &
169                        mmd_ice_fluxes(ilon,:,:),mmd_gazs_sat(ilon,:,:),mmd_nrate(ilon,:,:),mmd_grate(ilon,:,:))
170                        ! ADDED ABOVE : Nucleation and growth rates
171    call mm_get_radii(mmd_rc_sph(ilon,:),mmd_rc_fra(ilon,:),mmd_rc_cld(ilon,:))
172
173    ! Convert tracers back to intensives ( except for gazs where we work with molar mass ratio )
174    ! We suppose a given order of tracers !
175 
176    zdq(ilon,:,1) = dm0as(:) / int2ext(ilon,:)
177    zdq(ilon,:,2) = dm3as(:) / int2ext(ilon,:)
178    zdq(ilon,:,3) = dm0af(:) / int2ext(ilon,:)
179    zdq(ilon,:,4) = dm3af(:) / int2ext(ilon,:)
180   
181    if (callclouds) then ! if call clouds
182      zdq(ilon,:,5) = dm0n(:) / int2ext(ilon,:)
183      zdq(ilon,:,6) = dm3n(:) / int2ext(ilon,:)
184      do i=1,nices
185        zdq(ilon,:,ices_indx(i)) = dm3i(:,i) / int2ext(ilon,:)
186        zdq(ilon,:,gazs_indx(i)) = dgazs(:,i) * rat_mmol(gazs_indx(i)) ! For gazs we work on the full tracer array !!
187        ! We use the molar mass ratio from GCM in case there is discrepancy with the mm one
188      enddo
189    endif
190   
191  END DO ! loop on ilon
192
193  ! YAMMS gives a tendency which is integrated for all the timestep but in the GCM
194  ! we want to have routines spitting tendencies in s-1 -> let's divide !
195  zdq(:,:,:) = zdq(:,:,:) / dt
196
197END SUBROUTINE calmufi
Note: See TracBrowser for help on using the repository browser.