Ignore:
Timestamp:
Nov 12, 2025, 2:00:58 PM (5 weeks ago)
Author:
debatzbr
Message:

Pluto PCM: Implementation of a microphysical model for clouds in moments.
BBT

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/LMDZ.PLUTO/libf/muphypluto/mp2m_microphysics.F90

    r3951 r3957  
    88    !
    99    !     The module contains two methods:
    10     !        - mm_muphys(m3as_prod,dm0a_s,dm3a_s,dm0a_f,dm3a_f)
    11     !        - mm_diagnostics(dt,aer_prec,aer_s_w,aer_f_w,aer_s_flux,aer_f_flux,rc_sph,rc_fra)
     10    !        - mm_muphys
     11    !        - mm_diagnostics
    1212    !
    1313    !     Authors
     
    2020    USE MP2M_GLOBALS
    2121    USE MP2M_HAZE
     22    USE MP2M_CLOUDS
    2223    USE MP2M_METHODS
    2324    IMPLICIT NONE
    2425   
    2526    PUBLIC :: mm_muphys, mm_diagnostics
     27
     28    !! Interface to main microphysics subroutine:
     29    !! Computes either all the microphysics processes [[muphys_all]]
     30    !! or only aerosols microphysics [[muphys_nocld]] in a single call.
     31    INTERFACE mm_muphys
     32      MODULE PROCEDURE muphys_all,muphys_nocld
     33    END INTERFACE mm_muphys
    2634 
    2735    CONTAINS
    2836 
    29     FUNCTION mm_muphys(m3as_prod,dm0a_s,dm3a_s,dm0a_f,dm3a_f) RESULT(ret)
     37    FUNCTION muphys_all(m3as_prod,dm0as,dm3as,dm0af,dm3af,dm0ccn,dm3ccn,dm3ices,dmugases) RESULT(ret)
    3038        !! Compute the evolution of moments tracers through haze microphysics processes.
    3139        !!
     
    4452        REAL(kind=mm_wp), INTENT(in), DIMENSION(:) :: m3as_prod
    4553        ! Tendency of the 0th order moment of the spherical mode distribution (m-2).
    46         REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm0a_s
     54        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:) :: dm0as
    4755        ! Tendency of the 3rd order moment of the spherical mode distribution (m3.m-2).
    48         REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm3a_s
     56        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:) :: dm3as
    4957        ! Tendency of the 0th order moment of the fractal mode distribution (m-2).
    50         REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm0a_f
     58        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:) :: dm0af
    5159        ! Tendency of the 3rd order moment of the fractal mode distribution (m3.m-2).
    52         REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm3a_f
     60        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:) :: dm3af
     61        ! Tendency of the 0th order moment of the CCN distribution (m-2).
     62        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:)   :: dm0ccn
     63        ! Tendency of the 3rd order moment of the CCN distribution (m3.m-2).
     64        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:)   :: dm3ccn
     65        ! Tendency of the 3rd order moment of each ice components (m3.m-2).
     66        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:,:) :: dm3ices
     67        ! Tendencies of each condensible gaz species (mol.mol-1).
     68        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:,:) :: dmugases
     69
     70        ! .true. on succes (i.e. model has been initialized at least once previously), .false. otherwise.
     71        LOGICAL :: ret
     72       
     73        ! Local variables.
     74        INTEGER :: i
     75        ! Production of the spherical aerosols (m3.m-3).
     76        REAL(kind=mm_wp), DIMENSION(:), ALLOCATABLE :: m3a_s_prod
     77        ! Tendencies related to haze model (X/m3).
     78        REAL(kind=mm_wp), DIMENSION(SIZE(dm0as)) :: Hdm0as,Hdm3as,Hdm0af,Hdm3af
     79        ! Tendencies related to cloud model (X/m3).
     80        REAL(kind=mm_wp), DIMENSION(SIZE(dm0as)) :: Cdm0as,Cdm3as,Cdm0af,Cdm3af
     81       
     82        ALLOCATE(m3a_s_prod(mm_nla))
     83
     84        ! Sanity check for initialization
     85        ret = (mm_ini_col.AND.mm_ini_aer)
     86        if (.NOT.ret) then
     87            return
     88        endif
     89        if (mm_call_clouds.AND.mm_debug) then
     90            write(*,'(a)') "[MM_DEBUG - muphys_nocld] Clouds microphysics enabled but will not be computed... (wrong interface)"
     91        endif
     92     
     93        ! Reverse vectors so they go from top to ground
     94        ! @note: mm_dzlev is already from top to ground
     95        m3a_s_prod = m3as_prod(mm_nla:1:-1) / mm_dzlev(:)
     96
     97        ! Calls haze microphysics (/!\ tendencies in X/m-3)
     98        call mm_haze_microphysics(m3a_s_prod,Hdm0as,Hdm3as,Hdm0af,Hdm3af)
     99
     100        ! Calls cloud microphysics (/!\ tendencies in X/m-3)
     101        if (mm_call_clouds) then
     102            call mm_cloud_microphysics(Hdm0as,Hdm3as,Hdm0af,Hdm3af,&
     103                                       Cdm0as,Cdm3as,Cdm0af,Cdm3af,&
     104                                       dm0ccn,dm3ccn,dm3ices,dmugases)
     105
     106            ! Multiply by altitude thickness and reverse vectors so they go from ground to top (--> m-2)
     107            dm0ccn = dm0ccn(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
     108            dm3ccn = dm3ccn(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
     109            do i = 1, mm_nesp
     110                dm3ices(:,i)  = dm3ices(mm_nla:1:-1,i) * mm_dzlev(mm_nla:1:-1)
     111                dmugases(:,i) = dmugases(mm_nla:1:-1,i)
     112            enddo
     113         
     114        else
     115            Cdm0as(:) = 0._mm_wp ; Cdm3as(:) = 0._mm_wp ; Cdm0af(:) = 0._mm_wp ; Cdm3af(:) = 0._mm_wp
     116            dm0ccn(:) = 0._mm_wp ; dm3ccn(:) = 0._mm_wp ; dm3ices(:,:) = 0._mm_wp ; dmugases(:,:) = 0._mm_wp
     117        endif ! end of mm_call_clouds
     118       
     119        ! Multiply by altitude thickness and reverse vectors so they go from ground to top (--> m-2)
     120        dm0as = (Hdm0as(mm_nla:1:-1) + Cdm0as(mm_nla:1:-1)) * mm_dzlev(mm_nla:1:-1)
     121        dm3as = (Hdm3as(mm_nla:1:-1) + Cdm3as(mm_nla:1:-1)) * mm_dzlev(mm_nla:1:-1)
     122        dm0af = (Hdm0af(mm_nla:1:-1) + Cdm0af(mm_nla:1:-1)) * mm_dzlev(mm_nla:1:-1)
     123        dm3af = (Hdm3af(mm_nla:1:-1) + Cdm3af(mm_nla:1:-1)) * mm_dzlev(mm_nla:1:-1)
     124       
     125        RETURN
     126    END FUNCTION muphys_all
     127   
     128   
     129    FUNCTION muphys_nocld(m3as_prod,dm0as,dm3as,dm0af,dm3af) RESULT(ret)
     130        !! Compute the evolution of moments tracers through haze microphysics processes.
     131        !!
     132        !! This method computes the evolution of all the microphysics tracers, given under the form
     133        !! of moments during a time step.
     134        !!
     135        !! The method requires that global variables of the model (i.e. variables declared in mm_globals
     136        !! module) are initialized/updated correctly (see mm_global_init, mm_column_init, and mm_aerosols_init).
     137        !!
     138        !! The tendencies returned by the method are defined on the vertical __layers__ of the model from the __GROUND__ to
     139        !! the __TOP__ of the atmosphere. They should be added to the input variables used in the initialization methods
     140        !! before the latter are called to initialize a new step.
     141        !!
     142
     143        ! Production of the 3rd order moment of the spherical mode distribution (m3.m-2).
     144        REAL(kind=mm_wp), INTENT(in), DIMENSION(:) :: m3as_prod
     145        ! Tendency of the 0th order moment of the spherical mode distribution (m-2).
     146        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:) :: dm0as
     147        ! Tendency of the 3rd order moment of the spherical mode distribution (m3.m-2).
     148        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:) :: dm3as
     149        ! Tendency of the 0th order moment of the fractal mode distribution (m-2).
     150        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:) :: dm0af
     151        ! Tendency of the 3rd order moment of the fractal mode distribution (m3.m-2).
     152        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:) :: dm3af
    53153
    54154        ! .true. on succes (i.e. model has been initialized at least once previously), .false. otherwise.
     
    60160        ALLOCATE(m3a_s_prod(mm_nla))
    61161       
     162        ! Sanity check for initialization
    62163        ret = (mm_ini_col.AND.mm_ini_aer)
    63        
    64         IF (.NOT.ret) RETURN
     164        if (.NOT.ret) then
     165            return
     166        endif
     167        if (mm_call_clouds.AND.mm_debug) then
     168            write(*,'(a)') "[MM_DEBUG - muphys_nocld] Clouds microphysics enabled but will not be computed... (wrong interface)"
     169        endif
    65170     
    66171        ! Reverse vectors so they go from top to ground
     
    69174
    70175        ! Calls haze microphysics
    71         call mm_haze_microphysics(m3a_s_prod,dm0a_s,dm3a_s,dm0a_f,dm3a_f)
    72        
    73         ! Reverse vectors so they go from ground to top
    74         dm0a_s = dm0a_s(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
    75         dm3a_s = dm3a_s(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
    76         dm0a_f = dm0a_f(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
    77         dm3a_f = dm3a_f(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
     176        call mm_haze_microphysics(m3a_s_prod,dm0as,dm3as,dm0af,dm3af)
     177       
     178        ! Multiply by altitude thickness and reverse vectors so they go from ground to top (--> m-2)
     179        dm0as = dm0as(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
     180        dm3as = dm3as(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
     181        dm0af = dm0af(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
     182        dm3af = dm3af(mm_nla:1:-1) * mm_dzlev(mm_nla:1:-1)
    78183       
    79184        RETURN
    80     END FUNCTION mm_muphys
    81 
    82 
    83     SUBROUTINE mm_diagnostics(dt,aer_s_prec,aer_f_prec,aer_s_w,aer_f_w,aer_s_flux,aer_f_flux,rc_sph,rc_fra)
     185    END FUNCTION muphys_nocld
     186
     187
     188    SUBROUTINE mm_diagnostics(dt,aer_s_prec,aer_f_prec,aer_s_w,aer_f_w,aer_s_flux,aer_f_flux,rc_sph,rc_fra,&
     189                              ccn_prec,ice_prec,cld_w,ccn_flux,ice_fluxes,rcld,gas_sat,n_rate,g_rate)
    84190        !! Get various diagnostic fields of the microphysics.
    85191        !!
     
    91197        !! Precipitation are always positive and defined in kg.m-2.s-1.
    92198        !!
    93 
    94199        ! Physics timestep (s).
    95200        REAL(kind=8), INTENT(IN) :: dt
    96201
     202        ! Haze related:
     203        !~~~~~~~~~~~~~~
    97204        ! Aerosol precipitation (kg.m-2.s-1).
    98         REAL(kind=mm_wp), INTENT(out), OPTIONAL :: aer_s_prec
    99         REAL(kind=mm_wp), INTENT(out), OPTIONAL :: aer_f_prec
    100 
     205        REAL(kind=mm_wp), INTENT(inout), OPTIONAL :: aer_s_prec
     206        REAL(kind=mm_wp), INTENT(inout), OPTIONAL :: aer_f_prec
    101207        ! Aerosol settling velocity (m.s-1).
    102         REAL(kind=mm_wp), INTENT(out), DIMENSION(:), OPTIONAL :: aer_s_w
    103         REAL(kind=mm_wp), INTENT(out), DIMENSION(:), OPTIONAL :: aer_f_w
    104 
     208        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:), OPTIONAL :: aer_s_w
     209        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:), OPTIONAL :: aer_f_w
    105210        ! Aerosol mass flux (kg.m-2.s-1).
    106         REAL(kind=mm_wp), INTENT(out), DIMENSION(:), OPTIONAL :: aer_s_flux
    107         REAL(kind=mm_wp), INTENT(out), DIMENSION(:), OPTIONAL :: aer_f_flux
    108 
     211        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:), OPTIONAL :: aer_s_flux
     212        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:), OPTIONAL :: aer_f_flux
    109213        ! Aerosol characteristic radius (m).
    110         REAL(kind=mm_wp), INTENT(out), DIMENSION(:), OPTIONAL :: rc_sph
    111         REAL(kind=mm_wp), INTENT(out), DIMENSION(:), OPTIONAL :: rc_fra
    112 
     214        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:), OPTIONAL :: rc_sph
     215        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:), OPTIONAL :: rc_fra
     216
     217        ! Clouds related:
     218        !~~~~~~~~~~~~~~~~
     219        ! Cloud condensation nuclei precipitation (kg.m-2.s-1).
     220        REAL(kind=mm_wp), INTENT(inout), OPTIONAL                 :: ccn_prec
     221        ! Ice precipitation (kg.m-2.s-1).
     222        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:), OPTIONAL   :: ice_prec
     223        ! Cloud drop (CCN + ices) settling velocity (m.s-1).
     224        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:), OPTIONAL   :: cld_w
     225        ! Cloud condensation nuclei mass flux (kg.m-2.s-1).
     226        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:), OPTIONAL   :: ccn_flux
     227        ! Ice mass fluxes (kg.m-2.s-1).
     228        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:,:), OPTIONAL :: ice_fluxes
     229        ! Cloud drop (CCN + ices) radius (m).
     230        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:), OPTIONAL   :: rcld
     231        ! Cloud related diagnostics.
     232        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:,:), OPTIONAL :: gas_sat ! Condensible gaz saturation ratios.
     233        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:,:), OPTIONAL :: n_rate  ! Condensible gaz nucleation rates (m-2.s-1).
     234        REAL(kind=mm_wp), INTENT(inout), DIMENSION(:,:), OPTIONAL :: g_rate  ! Ice growth rates (m2.s-1).
     235
     236        ! Haze related:
     237        !~~~~~~~~~~~~~~
    113238        IF (PRESENT(aer_s_prec)) aer_s_prec = ABS(mm_aers_prec) / dt
    114239        IF (PRESENT(aer_f_prec)) aer_f_prec = ABS(mm_aerf_prec) / dt
     
    124249            IF (PRESENT(rc_sph)) rc_sph = 0._mm_wp
    125250            IF (PRESENT(rc_fra)) rc_fra = 0._mm_wp
    126         ENDIF   
     251        ENDIF
     252
     253        ! Clouds related:
     254        !~~~~~~~~~~~~~~~~
     255        IF (mm_call_clouds) THEN
     256            IF (PRESENT(ccn_prec))   ccn_prec   = ABS(mm_ccn_prec) / dt
     257            IF (PRESENT(ice_prec))   ice_prec   = ABS(mm_ice_prec) / dt
     258            IF (PRESENT(cld_w))      cld_w      = mm_cld_vsed(mm_nla:1:-1)
     259            IF (PRESENT(ccn_flux))   ccn_flux   = mm_ccn_flux(mm_nla:1:-1)
     260            IF (PRESENT(ice_fluxes)) ice_fluxes = mm_ice_fluxes(mm_nla:1:-1,:)
     261            IF (PRESENT(rcld))       rcld       = mm_drad(mm_nla:1:-1)
     262            IF (PRESENT(gas_sat))    gas_sat    = mm_gas_sat(mm_nla:1:-1,:)
     263            IF (PRESENT(n_rate))     n_rate     = mm_nrate(mm_nla:1:-1,:)
     264            IF (PRESENT(g_rate))     g_rate     = mm_grate(mm_nla:1:-1,:)
     265        ELSE
     266            IF (PRESENT(ccn_prec))   ccn_prec   = 0._mm_wp
     267            IF (PRESENT(ice_prec))   ice_prec   = 0._mm_wp
     268            IF (PRESENT(cld_w))      cld_w      = 0._mm_wp
     269            IF (PRESENT(ccn_flux))   ccn_flux   = 0._mm_wp
     270            IF (PRESENT(ice_fluxes)) ice_fluxes = 0._mm_wp
     271            IF (PRESENT(rcld))       rcld       = 0._mm_wp
     272            IF (PRESENT(gas_sat))    gas_sat    = 0._mm_wp
     273            IF (PRESENT(n_rate))     n_rate     = 0._mm_wp
     274            IF (PRESENT(g_rate))     g_rate     = 0._mm_wp
     275        ENDIF ! end of mm_call_clouds
     276
    127277    END SUBROUTINE mm_diagnostics
    128278
Note: See TracChangeset for help on using the changeset viewer.