LCOV - code coverage report
Current view: top level - physics/clubb/src/CLUBB_core - precipitation_fraction.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 224 0.0 %
Date: 2025-03-13 18:42:46 Functions: 0 3 0.0 %

          Line data    Source code
       1             : !-------------------------------------------------------------------------
       2             : ! $Id$
       3             : !===============================================================================
       4             : module precipitation_fraction
       5             : 
       6             :   ! Description:
       7             :   ! Sets overall precipitation fraction as well as the precipitation fraction
       8             :   ! in each PDF component.
       9             : 
      10             :   implicit none
      11             : 
      12             :   private
      13             : 
      14             :   public :: precip_fraction
      15             : 
      16             :   private :: component_precip_frac_weighted, &
      17             :              component_precip_frac_specify,  &
      18             :              precip_frac_assert_check
      19             : 
      20             :   integer, parameter, public :: &
      21             :     precip_frac_calc_type = 2  ! Option used to calculate component precip_frac
      22             : 
      23             :   contains
      24             : 
      25             :   !=============================================================================
      26           0 :   subroutine precip_fraction( nz, ngrdcol, &
      27           0 :                               hydromet, cloud_frac, cloud_frac_1, &
      28           0 :                               cloud_frac_2, ice_supersat_frac, &
      29           0 :                               ice_supersat_frac_1, ice_supersat_frac_2, &
      30           0 :                               mixt_frac, clubb_params, &
      31             :                               stats_metadata, &
      32           0 :                               stats_sfc, & 
      33           0 :                               precip_frac, &
      34           0 :                               precip_frac_1, &
      35           0 :                               precip_frac_2, &
      36           0 :                               precip_frac_tol )
      37             : 
      38             :     ! Description:
      39             :     ! Determines (overall) precipitation fraction over the horizontal domain, as
      40             :     ! well as the precipitation fraction within each PDF component, at every
      41             :     ! vertical grid level.
      42             : 
      43             :     ! References:
      44             :     !-----------------------------------------------------------------------
      45             : 
      46             :     use constants_clubb, only: &
      47             :         one,            & ! Constant(s)
      48             :         zero,           &
      49             :         cloud_frac_min, &
      50             :         fstderr
      51             : 
      52             :     use parameter_indices, only: &
      53             :         nparams, & ! Variable(s)
      54             :         iupsilon_precip_frac_rat
      55             : 
      56             :     use parameters_model, only: &
      57             :         hydromet_dim  ! Variable(s)
      58             : 
      59             :     use array_index, only: &
      60             :         l_mix_rat_hm, & ! Variable(s)
      61             :         l_frozen_hm,  &
      62             :         hydromet_tol
      63             : 
      64             :     use stats_type_utilities, only: &
      65             :         stat_update_var_pt  ! Procedure(s)
      66             : 
      67             :     use clubb_precision, only: &
      68             :         core_rknd  ! Variable(s)
      69             : 
      70             :     use error_code, only: &
      71             :         clubb_at_least_debug_level, &   ! Procedure
      72             :         err_code, &                     ! Error Indicator
      73             :         clubb_fatal_error               ! Constant
      74             : 
      75             :     use stats_type, only: &
      76             :         stats ! Type
      77             : 
      78             :     use stats_variables, only: &
      79             :         stats_metadata_type
      80             : 
      81             :     implicit none
      82             : 
      83             :     !------------------------- Input Variables -------------------------
      84             :     integer, intent(in) :: &
      85             :       nz,       & ! Number of model vertical grid levels
      86             :       ngrdcol     ! Number of grid columns
      87             : 
      88             :     real( kind = core_rknd ), dimension(ngrdcol,nz,hydromet_dim), intent(in) :: &
      89             :       hydromet    ! Mean of hydrometeor, hm (overall)           [units vary]
      90             : 
      91             :     real( kind = core_rknd ), dimension(ngrdcol,nz), intent(in) :: &
      92             :       cloud_frac,          & ! Cloud fraction (overall)                      [-]
      93             :       cloud_frac_1,        & ! Cloud fraction (1st PDF component)            [-]
      94             :       cloud_frac_2,        & ! Cloud fraction (2nd PDF component)            [-]
      95             :       ice_supersat_frac,   & ! Ice supersaturation fraction (overall)        [-]
      96             :       ice_supersat_frac_1, & ! Ice supersaturation fraction (1st PDF comp.)  [-]
      97             :       ice_supersat_frac_2, & ! Ice supersaturation fraction (2nd PDF comp.)  [-]
      98             :       mixt_frac              ! Mixture fraction                              [-]
      99             : 
     100             :     real( kind = core_rknd ), dimension(nparams), intent(in) :: &
     101             :       clubb_params    ! Array of CLUBB's tunable parameters    [units vary]
     102             :       
     103             :     type (stats_metadata_type), intent(in) :: &
     104             :       stats_metadata
     105             : 
     106             :     !------------------------- Inout Variables -------------------------
     107             :     type (stats), target, dimension(ngrdcol), intent(inout) :: &
     108             :       stats_sfc
     109             : 
     110             :     !------------------------- Output Variables -------------------------
     111             :     real( kind = core_rknd ), dimension(ngrdcol,nz), intent(out) :: &
     112             :       precip_frac,   & ! Precipitation fraction (overall)               [-]
     113             :       precip_frac_1, & ! Precipitation fraction (1st PDF component)     [-]
     114             :       precip_frac_2    ! Precipitation fraction (2nd PDF component)     [-]
     115             : 
     116             :     real( kind = core_rknd ), dimension(ngrdcol), intent(out) :: &
     117             :       precip_frac_tol    ! Minimum precip. frac. when hydromet. are present  [-]
     118             : 
     119             :     !------------------------- Local Variables -------------------------
     120             : 
     121             :     ! "Maximum allowable" hydrometeor mixing ratio in-precip component mean.
     122             :     real( kind = core_rknd ), parameter :: &
     123             :       max_hm_ip_comp_mean = 0.0025_core_rknd  ! [kg/kg]
     124             : 
     125             :     real( kind = core_rknd ), parameter :: &
     126             :       precip_frac_tol_coef = 0.1_core_rknd  ! Coefficient for precip_frac_tol
     127             : 
     128             :     integer :: &
     129             :       j, k, ivar   ! Loop indices
     130             : 
     131             : 
     132             :     ! Initialize the precipitation fraction variables (precip_frac,
     133             :     ! precip_frac_1, and precip_frac_2) to 0.
     134           0 :     precip_frac(:,:)   = zero
     135           0 :     precip_frac_1(:,:) = zero
     136           0 :     precip_frac_2(:,:) = zero
     137             : 
     138             :     ! Set the minimum allowable precipitation fraction when hydrometeors are
     139             :     ! found at a grid level.
     140           0 :     if ( any( l_frozen_hm ) ) then
     141             :       ! Ice microphysics included.
     142           0 :       do j = 1, ngrdcol
     143           0 :         precip_frac_tol(j) &
     144             :         = max( precip_frac_tol_coef &
     145             :                * max( maxval( cloud_frac(j,:) ), maxval( ice_supersat_frac(j,:) ) ), &
     146           0 :                cloud_frac_min )
     147             :       end do
     148             :     else
     149             :       ! Warm microphysics.
     150           0 :       do j = 1, ngrdcol
     151           0 :         precip_frac_tol(j) = max( precip_frac_tol_coef * maxval( cloud_frac(j,:) ), &
     152           0 :                                 cloud_frac_min )
     153             :       end do
     154             :     endif
     155             :     
     156             :     !!! Find overall precipitation fraction.
     157             :     ! The precipitation fraction is the greatest cloud fraction at or above a
     158             :     ! vertical level.
     159           0 :     if ( any( l_frozen_hm ) ) then
     160             :       
     161             :       ! Ice microphysics included.
     162           0 :       precip_frac(:,nz) = max( cloud_frac(:,nz), ice_supersat_frac(:,nz) )
     163             :       
     164           0 :       do k = nz-1, 1, -1
     165           0 :         precip_frac(:,k) = max( precip_frac(:,k+1), cloud_frac(:,k), &
     166           0 :                                 ice_supersat_frac(:,k) )
     167             :       end do
     168             :       
     169             :     else
     170             :       
     171             :       ! Warm microphysics.
     172           0 :       precip_frac(:,nz) = cloud_frac(:,nz)
     173             :       
     174           0 :       do k = nz-1, 1, -1
     175           0 :         precip_frac(:,k) = max( precip_frac(:,k+1), cloud_frac(:,k) )
     176             :       end do
     177             :       
     178             :     end if
     179             : 
     180             :     !!! Special checks for overall precipitation fraction
     181           0 :     do k = 1, nz, 1
     182           0 :       do j = 1, ngrdcol
     183             : 
     184           0 :         if ( any( hydromet(j,k,:) >= hydromet_tol(:) ) &
     185           0 :             .and. precip_frac(j,k) < precip_frac_tol(j) ) then
     186             : 
     187             :           ! In a scenario where we find any hydrometeor at this grid level, but
     188             :           ! no cloud at or above this grid level, set precipitation fraction to
     189             :           ! a minimum threshold value.
     190           0 :           precip_frac(j,k) = precip_frac_tol(j)
     191             : 
     192           0 :         elseif ( all( hydromet(j,k,:) < hydromet_tol(:) ) ) then
     193             : 
     194             :           ! The means (overall) of every precipitating hydrometeor are all less
     195             :           ! than their respective tolerance amounts.  They are all considered to
     196             :           ! have values of 0.  There are not any hydrometeor species found at
     197             :           ! this grid level.  There is also no cloud at or above this grid
     198             :           ! level, so set precipitation fraction to 0.
     199           0 :           precip_frac(j,k) = zero
     200             : 
     201             :         endif
     202             :         
     203             :       end do
     204             :     enddo ! Special checks for overall precipitation fraction loop: k = 1, nz, 1
     205             : 
     206             : 
     207             :     !!! Find precipitation fraction within each PDF component.
     208             :     !
     209             :     ! The overall precipitation fraction, f_p, is given by the equation:
     210             :     !
     211             :     ! f_p = a * f_p(1) + ( 1 - a ) * f_p(2);
     212             :     !
     213             :     ! where "a" is the mixture fraction (weight of PDF component 1), f_p(1) is
     214             :     ! the precipitation fraction within PDF component 1, and f_p(2) is the
     215             :     ! precipitation fraction within PDF component 2.  Overall precipitation
     216             :     ! fraction is found according the method above, and mixture fraction is
     217             :     ! already determined, leaving f_p(1) and f_p(2) to be solved for.  The
     218             :     ! values for f_p(1) and f_p(2) must satisfy the above equation.
     219           0 :     if ( precip_frac_calc_type == 1 ) then
     220             : 
     221             :       ! Calculatate precip_frac_1 and precip_frac_2 based on the greatest
     222             :       ! weighted cloud_frac_1 at or above a grid level.
     223             :       call component_precip_frac_weighted( nz, ngrdcol, & ! intent(in)
     224             :                                            hydromet(:,:,:), precip_frac(:,:), & ! intent(in)
     225             :                                            cloud_frac_1(:,:), cloud_frac_2(:,:), & ! intent(in)
     226             :                                            ice_supersat_frac_1(:,:), & ! intent(in)
     227             :                                            ice_supersat_frac_2(:,:), mixt_frac(:,:), & !intent(in)
     228             :                                            precip_frac_tol(:), & ! intent(in)
     229             :                                            precip_frac_1(:,:), precip_frac_2(:,:) ) ! intent(out)
     230             :                                             
     231             :     elseif ( precip_frac_calc_type == 2 ) then
     232             : 
     233             :       ! Specified method.
     234             :       call component_precip_frac_specify( nz, ngrdcol, & ! intent(in)
     235             :                                           clubb_params(iupsilon_precip_frac_rat), & ! intent(in)
     236             :                                           hydromet(:,:,:), precip_frac(:,:), & ! intent(in)
     237             :                                           mixt_frac(:,:), precip_frac_tol(:), & ! intent(in)
     238             :                                           precip_frac_1(:,:), precip_frac_2(:,:) ) ! intent(out)
     239             : 
     240             :     else ! Invalid option selected.
     241             : 
     242             :        write(fstderr,*) "Invalid option to calculate precip_frac_1 " &
     243             :                         // "and precip_frac_2."
     244             :        err_code = clubb_fatal_error
     245             :        return
     246             : 
     247             :     endif ! precip_frac_calc_type
     248             : 
     249             : 
     250             :     ! Increase Precipiation Fraction under special conditions.
     251             :     !
     252             :     ! There are scenarios that sometimes occur that require precipitation
     253             :     ! fraction to be boosted.  Precipitation fraction is calculated from cloud
     254             :     ! fraction and ice supersaturation fraction.  For numerical reasons, CLUBB's
     255             :     ! PDF may become entirely subsaturated with respect to liquid and ice,
     256             :     ! resulting in both a cloud fraction of 0 and an ice supersaturation
     257             :     ! fraction of 0.  When this happens, precipitation fraction drops to 0 when
     258             :     ! there aren't any hydrometeors present at that grid level, or to
     259             :     ! precip_frac_tol when there is at least one hydrometeor present at that
     260             :     ! grid level.  However, sometimes there are large values of hydrometeors
     261             :     ! found at that grid level.  When this occurs, the PDF component in-precip
     262             :     ! mean of a hydrometeor can become ridiculously large.  This is because the
     263             :     ! ith PDF component in-precip mean of a hydrometeor, mu_hm_i,  is given by
     264             :     ! the equation:
     265             :     !
     266             :     ! mu_hm_i = hm_i / precip_frac_i;
     267             :     !
     268             :     ! where hm_i is the overall ith PDF component mean of the hydrometeor, and
     269             :     ! precip_frac_i is the ith PDF component precipitation fraction.  When
     270             :     ! precip_frac_i has a value of precip_frac_tol and hm_i is large, mu_hm_i
     271             :     ! can be huge.  This can cause enormous microphysical process rates and
     272             :     ! result in numerical instability.  It is also very inaccurate.
     273             :     !
     274             :     ! In order to limit this problem, the ith PDF component precipitation
     275             :     ! fraction is increased in order to decrease mu_hm_i.  First, an "upper
     276             :     ! limit" is set for mu_hm_i when the hydrometeor is a mixing ratio.  This is
     277             :     ! called max_hm_ip_comp_mean.  At every vertical level and for every
     278             :     ! hydrometeor mixing ratio, a check is made to try to prevent mu_hm_i from
     279             :     ! exceeding the "upper limit".  The check is:
     280             :     !
     281             :     ! hm_i / precip_frac_i ( which = mu_hm_i )  >  max_hm_ip_comp_mean,
     282             :     !
     283             :     ! which can be rewritten:
     284             :     !
     285             :     ! hm_i > precip_frac_i * max_hm_ip_comp_mean.
     286             :     !
     287             :     ! Since hm_i has not been calculated yet, the assumption for this check is
     288             :     ! that all of the hydrometeor is found in one PDF component, which is the
     289             :     ! worst-case scenario in violating this limit.  The check becomes:
     290             :     !
     291             :     ! <hm> / ( mixt_frac * precip_frac_1 )  >  max_hm_ip_comp_mean;
     292             :     !    in PDF comp. 1; and
     293             :     ! <hm> / ( ( 1 - mixt_frac ) * precip_frac_2 )  >  max_hm_ip_comp_mean;
     294             :     !    in PDF comp. 2.
     295             :     !
     296             :     ! These limits can be rewritten as:
     297             :     !
     298             :     ! <hm>  >  mixt_frac * precip_frac_1 * max_hm_ip_comp_mean;
     299             :     !    in PDF comp. 1; and
     300             :     ! <hm>  >  ( 1 - mixt_frac ) * precip_frac_2 * max_hm_ip_comp_mean;
     301             :     !    in PDF comp. 2.
     302             :     !
     303             :     ! When component precipitation fraction is found to be in excess of the
     304             :     ! limit, precip_frac_i is increased to:
     305             :     !
     306             :     ! <hm> / ( mixt_frac * max_hm_ip_comp_mean );
     307             :     !    when the limit is exceeded in PDF comp. 1; and
     308             :     ! <hm> / ( ( 1 - mixt_frac ) * max_hm_ip_comp_mean );
     309             :     !    when the limit is exceeded in PDF comp. 2.
     310             :     !
     311             :     ! Of course, precip_frac_i is not allowed to exceed 1, so when
     312             :     ! <hm> / mixt_frac (or <hm> / ( 1 - mixt_frac )) is already greater than
     313             :     ! max_hm_ip_comp_mean, mu_hm_i will also have to be greater than
     314             :     ! max_hm_ip_comp_mean.  However, the value of mu_hm_i is still reduced when
     315             :     ! compared to what it would have been using precip_frac_tol.  In the event
     316             :     ! that multiple hydrometeor mixing ratios violate the check, the code is set
     317             :     ! up so that precip_frac_i is increased based on the highest hm_i.
     318             :     
     319             : 
     320           0 :    do ivar = 1, hydromet_dim
     321           0 :       if ( l_mix_rat_hm(ivar) ) then
     322           0 :         do k = 1, nz
     323           0 :           do j = 1, ngrdcol
     324             : 
     325             :             ! The hydrometeor is a mixing ratio.
     326             : 
     327           0 :             if ( hydromet(j,k,ivar) >= hydromet_tol(ivar) .and. &
     328             :                  hydromet(j,k,ivar) > mixt_frac(j,k) * precip_frac_1(j,k) &
     329             :                                      * max_hm_ip_comp_mean ) then
     330             : 
     331             :                 ! Increase precipitation fraction in the 1st PDF component.
     332             :                 precip_frac_1(j,k) &
     333             :                 = min( hydromet(j,k,ivar) &
     334           0 :                        / ( mixt_frac(j,k) * max_hm_ip_comp_mean ), one )
     335             : 
     336             :                 ! The value of precip_frac_1 must be at least precip_frac_tol
     337             :                 ! when precipitation is found in the 1st PDF component.
     338           0 :                 precip_frac_1(j,k) = max( precip_frac_1(j,k), precip_frac_tol(j) )
     339             : 
     340             :             endif ! <hm>/(mixt_frac*precip_frac_1) > max_hm_ip_comp_mean
     341             : 
     342           0 :             if ( hydromet(j,k,ivar) >= hydromet_tol(ivar) .and. &
     343             :                   hydromet(j,k,ivar) > ( one - mixt_frac(j,k) ) * precip_frac_2(j,k) &
     344           0 :                                      * max_hm_ip_comp_mean ) then
     345             : 
     346             :                 ! Increase precipitation fraction in the 2nd PDF component.
     347             :                 precip_frac_2(j,k) &
     348             :                 = min( hydromet(j,k,ivar) &
     349           0 :                        / ( ( one - mixt_frac(j,k) ) * max_hm_ip_comp_mean ), one )
     350             : 
     351             :                 ! The value of precip_frac_2 must be at least precip_frac_tol
     352             :                 ! when precipitation is found in the 2nd PDF component.
     353           0 :                 precip_frac_2(j,k) = max( precip_frac_2(j,k), precip_frac_tol(j) )
     354             : 
     355             :             endif ! <hm>/((1-mixt_frac)*precip_frac_2) > max_hm_ip_comp_mean
     356             : 
     357             :           end do
     358             :         end do ! k = 1, nz
     359             :       end if ! l_mix_rat_hm(ivar)
     360             :     end do ! ivar = 1, hydromet_dim
     361             : 
     362             :     ! Recalculate overall precipitation fraction for consistency.
     363             :     precip_frac(:,:) = mixt_frac(:,:) * precip_frac_1(:,:) &
     364           0 :                        + ( one - mixt_frac(:,:) ) * precip_frac_2(:,:)
     365             : 
     366             :     ! Double check that precip_frac_tol <= precip_frac <= 1 when hydrometeors
     367             :     ! are found at a grid level.
     368             :     ! PLEASE DO NOT ALTER precip_frac, precip_frac_1, or precip_frac_2 anymore
     369             :     ! after this point in the code.
     370           0 :     do k = 1, nz, 1
     371           0 :       do j = 1, ngrdcol
     372           0 :         if ( any( hydromet(j,k,:) >= hydromet_tol(:) ) ) then
     373           0 :           precip_frac(j,k) = min( max( precip_frac(j,k), precip_frac_tol(j) ), one )
     374             :         end if ! any( hydromet(k,:) >= hydromet_tol(:) )
     375             :       end do
     376             :     end do ! k = 1, nz, 1
     377             : 
     378             : 
     379             :     ! Statistics
     380           0 :     if ( stats_metadata%l_stats_samp ) then
     381           0 :       if ( stats_metadata%iprecip_frac_tol > 0 ) then
     382           0 :         do j = 1, ngrdcol
     383           0 :           call stat_update_var_pt( stats_metadata%iprecip_frac_tol, 1, precip_frac_tol(j), & ! intent(in)
     384           0 :                                    stats_sfc(j) ) ! intent(inout)
     385             :         end do
     386             :       end if ! stats_metadata%iprecip_frac_tol
     387             :     end if ! stats_metadata%l_stats_samp
     388             : 
     389             : 
     390             :     ! Assertion check for precip_frac, precip_frac_1, and precip_frac_2.
     391           0 :     if ( clubb_at_least_debug_level( 2 ) ) then
     392           0 :       do j = 1, ngrdcol
     393           0 :         call precip_frac_assert_check( nz, hydromet(j,:,:), mixt_frac(j,:), precip_frac(j,:), & !in
     394           0 :                                        precip_frac_1(j,:), precip_frac_2(j,:), & ! intent(in)
     395           0 :                                        precip_frac_tol(j) ) ! intent(in)
     396             :       end do
     397             :     endif
     398             : 
     399           0 :     return
     400             : 
     401             :   end subroutine precip_fraction
     402             : 
     403             :   !=============================================================================
     404             :   subroutine component_precip_frac_weighted( nz, ngrdcol, &
     405             :                                              hydromet, precip_frac, &
     406             :                                              cloud_frac_1, cloud_frac_2, &
     407             :                                              ice_supersat_frac_1, &
     408             :                                              ice_supersat_frac_2, mixt_frac, &
     409             :                                              precip_frac_tol, &
     410             :                                              precip_frac_1, precip_frac_2 )
     411             : 
     412             :     ! Description:
     413             :     ! Set precipitation fraction in each component of the PDF.  The weighted 1st
     414             :     ! PDF component precipitation fraction (weighted_pfrac_1) at a grid level is
     415             :     ! calculated by the greatest value of mixt_frac * cloud_frac_1 at or above
     416             :     ! the relevant grid level.  Likewise, the weighted 2nd PDF component
     417             :     ! precipitation fraction (weighted_pfrac_2) at a grid level is calculated by
     418             :     ! the greatest value of ( 1 - mixt_frac ) * cloud_frac_2 at or above the
     419             :     ! relevant grid level.
     420             :     !
     421             :     ! The fraction weighted_pfrac_1 / ( weighted_pfrac_1 + weighted_pfrac_2 ) is
     422             :     ! the weighted_pfrac_1 fraction.  Multiplying this fraction by overall
     423             :     ! precipitation fraction and then dividing by mixt_frac produces the 1st PDF
     424             :     ! component precipitation fraction (precip_frac_1).  Then, calculate the 2nd
     425             :     ! PDF component precipitation fraction (precip_frac_2) accordingly.
     426             : 
     427             :     ! References:
     428             :     !-----------------------------------------------------------------------
     429             : 
     430             :     use constants_clubb, only: &
     431             :         one,  & ! Constant(s)
     432             :         zero
     433             : 
     434             :     use parameters_model, only: &
     435             :         hydromet_dim  ! Variable(s)
     436             : 
     437             :     use array_index, only: &
     438             :         l_frozen_hm,  & ! Variable(s)
     439             :         hydromet_tol
     440             : 
     441             :     use clubb_precision, only: &
     442             :         core_rknd  ! Variable(s)
     443             : 
     444             :     implicit none
     445             : 
     446             :     ! Input Variables
     447             :     integer, intent(in) :: &
     448             :       nz,      & ! Number of model vertical grid levels
     449             :       ngrdcol    ! Number of grid columns
     450             : 
     451             :     real( kind = core_rknd ), dimension(ngrdcol,nz,hydromet_dim), intent(in) :: &
     452             :       hydromet    ! Mean of hydrometeor, hm (overall)           [units vary]
     453             : 
     454             :     real( kind = core_rknd ), dimension(ngrdcol,nz), intent(in) :: &
     455             :       precip_frac,         & ! Precipitation fraction (overall)              [-]
     456             :       cloud_frac_1,        & ! Cloud fraction (1st PDF component)            [-]
     457             :       cloud_frac_2,        & ! Cloud fraction (2nd PDF component)            [-]
     458             :       ice_supersat_frac_1, & ! Ice supersaturation fraction (1st PDF comp.)  [-]
     459             :       ice_supersat_frac_2, & ! Ice supersaturation fraction (2nd PDF comp.)  [-]
     460             :       mixt_frac              ! Mixture fraction                              [-]
     461             : 
     462             :     real( kind = core_rknd ), dimension(ngrdcol), intent(in) :: &
     463             :       precip_frac_tol    ! Minimum precip. frac. when hydromet. are present  [-]
     464             : 
     465             :     ! Output Variables
     466             :     real( kind = core_rknd ), dimension(ngrdcol,nz), intent(out) :: &
     467             :       precip_frac_1, & ! Precipitation fraction (1st PDF component)     [-]
     468             :       precip_frac_2    ! Precipitation fraction (2nd PDF component)     [-]
     469             : 
     470             :     ! Local Variables
     471             :     real( kind = core_rknd ), dimension(ngrdcol,nz) :: &
     472             :       weighted_pfrac_1, & ! Product of mixt_frac and cloud_frac_1           [-]
     473             :       weighted_pfrac_2    ! Product of ( 1 - mixt_frac ) and cloud_frac_2   [-]
     474             : 
     475             :     integer :: k, j  ! Loop index
     476             : 
     477             : 
     478             :     !!! Find precipitation fraction within PDF component 1.
     479             :     ! The method used to find overall precipitation fraction will also be to
     480             :     ! find precipitation fraction within PDF component 1 and PDF component 2.
     481             :     ! In order to do so, it is assumed (poorly) that PDF component 1 overlaps
     482             :     ! PDF component 1 and that PDF component 2 overlaps PDF component 2 at every
     483             :     ! vertical level in the vertical profile.  
     484             :     
     485             :     ! The weighted precipitation fraction in PDF component 1 is the greatest
     486             :     ! value of the product of mixture fraction (mixt_frac) and 1st PDF
     487             :     ! component cloud fraction at or above a vertical level.  Likewise, the
     488             :     ! weighted precipitation fraction in PDF component 2 is the greatest
     489             :     ! value of the product of ( 1 - mixt_frac ) and 2nd PDF component cloud
     490             :     ! fraction at or above a vertical level.
     491             :     if ( any( l_frozen_hm ) ) then
     492             :       
     493             :       ! Ice microphysics included.
     494             : 
     495             :       ! Weighted precipitation fraction in PDF component 1.
     496             :       weighted_pfrac_1(:,nz) &
     497             :       = max( mixt_frac(:,nz) * cloud_frac_1(:,nz), &
     498             :              mixt_frac(:,nz) * ice_supersat_frac_1(:,nz) )
     499             : 
     500             :       ! Weighted precipitation fraction in PDF component 2.
     501             :       weighted_pfrac_2(:,nz) &
     502             :       = max( ( one - mixt_frac(:,nz) ) * cloud_frac_2(:,nz), &
     503             :              ( one - mixt_frac(:,nz) ) * ice_supersat_frac_2(:,nz) )
     504             :              
     505             :       do k = nz, 1, -1
     506             :         do j = 1, ngrdcol
     507             :           ! Weighted precipitation fraction in PDF component 1.
     508             :           weighted_pfrac_1(j,k) &
     509             :           = max( weighted_pfrac_1(j,k+1), &
     510             :                  mixt_frac(j,k) * cloud_frac_1(j,k), &
     511             :                  mixt_frac(j,k) * ice_supersat_frac_1(j,k) )
     512             : 
     513             :           ! Weighted precipitation fraction in PDF component 2.
     514             :           weighted_pfrac_2(j,k) &
     515             :           = max( weighted_pfrac_2(j,k+1), &
     516             :                  ( one - mixt_frac(j,k) ) * cloud_frac_2(j,k), &
     517             :                  ( one - mixt_frac(j,k) ) * ice_supersat_frac_2(j,k) )
     518             :         end do
     519             :       end do
     520             :       
     521             :       
     522             :     else
     523             :       
     524             :        ! Warm microphysics.
     525             : 
     526             :        ! Weighted precipitation fraction in PDF component 1.
     527             :        weighted_pfrac_1(:,nz) = mixt_frac(:,nz) * cloud_frac_1(:,nz)
     528             : 
     529             :        ! Weighted precipitation fraction in PDF component 2.
     530             :        weighted_pfrac_2(:,nz) = ( one - mixt_frac(:,nz) ) * cloud_frac_2(:,nz)
     531             :        
     532             :       do k = nz, 1, -1
     533             :         do j = 1, ngrdcol
     534             :           ! Weighted precipitation fraction in PDF component 1.
     535             :           weighted_pfrac_1(j,k) &
     536             :           = max( weighted_pfrac_1(j,k+1), &
     537             :                  mixt_frac(j,k) * cloud_frac_1(j,k) )
     538             : 
     539             :           ! Weighted precipitation fraction in PDF component 2.
     540             :           weighted_pfrac_2(j,k) &
     541             :           = max( weighted_pfrac_2(j,k+1), &
     542             :                  ( one - mixt_frac(j,k) ) * cloud_frac_2(j,k) )
     543             :         end do
     544             :       end do
     545             :       
     546             :     end if
     547             :     
     548             : 
     549             :     ! Calculate precip_frac_1 and special cases for precip_frac_1.
     550             :     do k = 1, nz, 1
     551             :       do j = 1, ngrdcol
     552             :         ! Calculate precipitation fraction in the 1st PDF component.
     553             :         if ( weighted_pfrac_1(j,k) + weighted_pfrac_2(j,k) > zero ) then
     554             : 
     555             :           ! Adjust weighted 1st PDF component precipitation fraction by
     556             :           ! multiplying it by a factor.  That factor is overall precipitation
     557             :           ! fraction divided by the sum of the weighted 1st PDF component
     558             :           ! precipitation fraction and the weighted 2nd PDF component
     559             :           ! precipitation fraction.  The 1st PDF component precipitation
     560             :           ! fraction is then found by dividing the adjusted weighted 1st PDF
     561             :           ! component precipitation fraction by mixture fraction.
     562             :           precip_frac_1(j,k) &
     563             :           = weighted_pfrac_1(j,k) &
     564             :             * ( precip_frac(j,k) &
     565             :                 / ( weighted_pfrac_1(j,k) + weighted_pfrac_2(j,k) ) ) &
     566             :             / mixt_frac(j,k)
     567             :         else
     568             : 
     569             :           ! Usually, the sum of the weighted 1st PDF component precipitation
     570             :           ! fraction and the 2nd PDF component precipitation fraction go to 0
     571             :           ! when overall precipitation fraction goes to 0.  Since 1st PDF
     572             :           ! component weighted precipitation fraction is 0, 1st PDF component
     573             :           ! precipitation fraction also 0.
     574             :           precip_frac_1(j,k) = zero
     575             : 
     576             :         end if
     577             :       end do
     578             :     end do
     579             :       
     580             :     do k = 1, nz, 1
     581             :       do j = 1, ngrdcol
     582             :         ! Special cases for precip_frac_1.
     583             :         if ( any( hydromet(j,k,:) >= hydromet_tol(:) ) &
     584             :             .and. precip_frac_1(j,k) &
     585             :                   > min( one, precip_frac(j,k) / mixt_frac(j,k) ) ) then
     586             : 
     587             :           ! Using the above method, it is possible for precip_frac_1 to be
     588             :           ! greater than 1.  For example, the mixture fraction at level k+1 is
     589             :           ! 0.10 and the cloud_frac_1 at level k+1 is 1, resulting in a
     590             :           ! weighted_pfrac_1 of 0.10.  This product is greater than the product
     591             :           ! of mixt_frac and cloud_frac_1 at level k.  The mixture fraction at
     592             :           ! level k is 0.05, resulting in a precip_frac_1 of 2.  The value of
     593             :           ! precip_frac_1 is limited at 1.  The leftover precipitation fraction
     594             :           ! (a result of the decreasing weight of PDF component 1 between the
     595             :           ! levels) is applied to PDF component 2.
     596             :           ! Additionally, when weighted_pfrac_1 at level k is greater than
     597             :           ! overall precipitation fraction at level k, the resulting calculation
     598             :           ! of precip_frac_2 at level k will be negative.
     599             :           precip_frac_1(j,k) = min( one, precip_frac(j,k) / mixt_frac(j,k) )
     600             : 
     601             :         elseif ( any( hydromet(j,k,:) >= hydromet_tol(:) ) &
     602             :                 .and. precip_frac_1(j,k) > zero &
     603             :                 .and. precip_frac_1(j,k) < precip_frac_tol(j) ) then
     604             : 
     605             :           ! In a scenario where we find precipitation in the 1st PDF component
     606             :           ! (it is allowed to have a value of 0 when all precipitation is found
     607             :           ! in the 2nd PDF component) but it is tiny (less than tolerance
     608             :           ! level), boost 1st PDF component precipitation fraction to tolerance
     609             :           ! level.
     610             :           precip_frac_1(j,k) = precip_frac_tol(j)
     611             : 
     612             :         elseif ( all( hydromet(j,k,:) < hydromet_tol(:) ) ) then
     613             : 
     614             :           ! The means (overall) of every precipitating hydrometeor are all less
     615             :           ! than their respective tolerance amounts.  They are all considered to
     616             :           ! have values of 0.  There are not any hydrometeor species found at
     617             :           ! this grid level.  There is also no cloud at or above this grid
     618             :           ! level, so set 1st component precipitation fraction to 0.
     619             :           precip_frac_1(j,k) = zero
     620             : 
     621             :         end if
     622             :       end do
     623             :     end do
     624             : 
     625             : 
     626             :     !!! Find precipitation fraction within PDF component 2.
     627             :     ! The equation for precipitation fraction within PDF component 2 is:
     628             :     !
     629             :     ! f_p(2) = ( f_p - a * f_p(1) ) / ( 1 - a );
     630             :     !
     631             :     ! given the overall precipitation fraction, f_p (calculated above), the
     632             :     ! precipitation fraction within PDF component 1, f_p(1) (calculated above),
     633             :     ! and mixture fraction, a.  Any leftover precipitation fraction from
     634             :     ! precip_frac_1 will be included in this calculation of precip_frac_2.
     635             :     do k = 1, nz, 1
     636             :       do j = 1, ngrdcol
     637             : 
     638             :         if ( any( hydromet(j,k,:) >= hydromet_tol(:) ) ) then
     639             : 
     640             :           ! Calculate precipitation fraction in the 2nd PDF component.
     641             :           precip_frac_2(j,k) &
     642             :           = max( ( precip_frac(j,k) - mixt_frac(j,k) * precip_frac_1(j,k) ) &
     643             :                  / ( one - mixt_frac(j,k) ), &
     644             :                  zero )
     645             : 
     646             :           ! Special cases for precip_frac_2.
     647             :           if ( precip_frac_2(j,k) > one ) then
     648             : 
     649             :              ! Again, it is possible for precip_frac_2 to be greater than 1.
     650             :              ! For example, the mixture fraction at level k+1 is 0.10 and the
     651             :              ! cloud_frac_1 at level k+1 is 1, resulting in a weighted_pfrac_1
     652             :              ! of 0.10.  This product is greater than the product of mixt_frac
     653             :              ! and cloud_frac_1 at level k.  Additionally, precip_frac (overall)
     654             :              ! is 1 for level k.  The mixture fraction at level k is 0.5,
     655             :              ! resulting in a precip_frac_1 of 0.2.  Using the above equation,
     656             :              ! precip_frac_2 is calculated to be 1.8.  The value of
     657             :              ! precip_frac_2 is limited at 1.  The leftover precipitation
     658             :              ! fraction (as a result of the increasing weight of component 1
     659             :              ! between the levels) is applied to PDF component 1.
     660             :              precip_frac_2(j,k) = one
     661             : 
     662             :              ! Recalculate precipitation fraction in the 1st PDF component.
     663             :              precip_frac_1(j,k) &
     664             :              = ( precip_frac(j,k) - ( one - mixt_frac(j,k) ) ) / mixt_frac(j,k)
     665             : 
     666             :              ! Double check precip_frac_1
     667             :              if ( precip_frac_1(j,k) > one ) then
     668             : 
     669             :                 precip_frac_1(j,k) = one
     670             : 
     671             :                 precip_frac_2(j,k) = ( precip_frac(j,k) - mixt_frac(j,k) ) &
     672             :                                    / ( one - mixt_frac(j,k) )
     673             : 
     674             :              elseif ( precip_frac_1(j,k) > zero .and. precip_frac_1(j,k) < precip_frac_tol(j) ) then
     675             : 
     676             :                 precip_frac_1(j,k) = precip_frac_tol(j)
     677             : 
     678             :                 ! fp = a*fp1+(1-a)*fp2 solving for fp2
     679             :                 precip_frac_2(j,k) = precip_frac_1(j,k) &
     680             :                                      * ( ( ( precip_frac(j,k) / precip_frac_1(j,k)) &
     681             :                                          - mixt_frac(j,k) ) / ( one - mixt_frac(j,k) ) )
     682             :                 
     683             :              end if
     684             : 
     685             :           elseif ( precip_frac_2(j,k) > zero &
     686             :                    .and. precip_frac_2(j,k) < precip_frac_tol(j) ) then
     687             : 
     688             :             ! In a scenario where we find precipitation in the 2nd PDF
     689             :             ! component (it is allowed to have a value of 0 when all
     690             :             ! precipitation is found in the 1st PDF component) but it is tiny
     691             :             ! (less than tolerance level), boost 2nd PDF component
     692             :             ! precipitation fraction to tolerance level.
     693             :             precip_frac_2(j,k) = precip_frac_tol(j)
     694             : 
     695             :             ! Recalculate precipitation fraction in the 1st PDF component.
     696             :             precip_frac_1(j,k) &
     697             :              = ( precip_frac(j,k) - ( one - mixt_frac(j,k) ) * precip_frac_2(j,k) ) &
     698             :                / mixt_frac(j,k)
     699             : 
     700             :             ! Double check precip_frac_1
     701             :             if ( precip_frac_1(j,k) > one ) then
     702             : 
     703             :               precip_frac_1(j,k) = one
     704             : 
     705             :               precip_frac_2(j,k) = ( precip_frac(j,k) - mixt_frac(j,k) ) &
     706             :                                    / ( one - mixt_frac(j,k) )
     707             : 
     708             :             elseif ( precip_frac_1(j,k) > zero .and. precip_frac_1(j,k) < precip_frac_tol(j) ) then
     709             : 
     710             :               precip_frac_1(j,k) = precip_frac_tol(j) 
     711             : 
     712             :               ! fp = a*fp1+(1-a)*fp2 solving for fp2
     713             :               precip_frac_2(j,k) = precip_frac_1(j,k) &
     714             :                                    * ( ( ( precip_frac(j,k) / precip_frac_1(j,k)) &
     715             :                                        - mixt_frac(j,k) ) / ( one - mixt_frac(j,k) ) )
     716             : 
     717             :             end if
     718             : 
     719             :           end if ! Special cases for precip_frac_2
     720             : 
     721             :         else ! all( hydromet(k,:) < hydromet_tol(:) )
     722             : 
     723             :           ! The means (overall) of every precipitating hydrometeor are all less
     724             :           ! than their respective tolerance amounts.  They are all considered to
     725             :           ! have values of 0.  There are not any hydrometeor species found at
     726             :           ! this grid level.  There is also no cloud at or above this grid
     727             :           ! level, so set 2nd component precipitation fraction to 0.
     728             :           precip_frac_2(j,k) = zero
     729             : 
     730             :         end if ! any( hydromet(k,:) > hydromet_tol(:) )
     731             :       end do
     732             :     end do
     733             : 
     734             :     return
     735             : 
     736             :   end subroutine component_precip_frac_weighted
     737             : 
     738             :   !=============================================================================
     739           0 :   subroutine component_precip_frac_specify( nz, ngrdcol, &
     740             :                                             upsilon_precip_frac_rat, &
     741           0 :                                             hydromet, precip_frac, &
     742           0 :                                             mixt_frac, precip_frac_tol, &
     743           0 :                                             precip_frac_1, precip_frac_2 )
     744             : 
     745             :     ! Description:
     746             :     ! Calculates the precipitation fraction in each PDF component.
     747             :     !
     748             :     ! The equation for precipitation fraction is:
     749             :     !
     750             :     ! f_p = mixt_frac * f_p(1) + ( 1 - mixt_frac ) * f_p(2);
     751             :     !
     752             :     ! where f_p is overall precipitation fraction, f_p(1) is precipitation
     753             :     ! fraction in the 1st PDF component, f_p(2) is precipitation fraction in the
     754             :     ! 2nd PDF component, and mixt_frac is the mixture fraction.  Using this
     755             :     ! method, a new specified parameter is introduced, upsilon, where:
     756             :     !
     757             :     ! upsilon = mixt_frac * f_p(1) / f_p; and where 0 <= upsilon <= 1.
     758             :     !
     759             :     ! In other words, upsilon is the ratio of mixt_frac * f_p(1) to f_p.  Since
     760             :     ! f_p and mixt_frac are calculated previously, and upsilon is specified,
     761             :     ! f_p(1) can be calculated by:
     762             :     !
     763             :     ! f_p(1) = upsilon * f_p / mixt_frac;
     764             :     !
     765             :     ! and has an upper limit of 1.  The value of f_p(2) can then be calculated
     766             :     ! by:
     767             :     !
     768             :     ! f_p(2) = ( f_p - mixt_frac * f_p(1) ) / ( 1 - mixt_frac );
     769             :     !
     770             :     ! and also has an upper limit of 1.  When upsilon = 1, all of the
     771             :     ! precipitation is found in the 1st PDF component (as long as
     772             :     ! f_p <= mixt_frac, otherwise it would cause f_p(1) to be greater than 1).
     773             :     ! When upsilon = 0, all of the precipitation is found in the 2nd PDF
     774             :     ! component (as long as f_p <= 1 - mixt_frac, otherwise it would cause
     775             :     ! f_p(2) to be greater than 1).  When upsilon is between 0 and 1,
     776             :     ! precipitation is split between the two PDF components accordingly.
     777             : 
     778             :     ! References:
     779             :     !-----------------------------------------------------------------------
     780             : 
     781             :     use constants_clubb, only: &
     782             :         one,  & ! Constant(s)
     783             :         zero, &
     784             :         eps
     785             : 
     786             :     use parameters_model, only: &
     787             :         hydromet_dim  ! Variable(s)
     788             : 
     789             :     use array_index, only: &
     790             :         hydromet_tol  ! Variable(s)
     791             : 
     792             :     use clubb_precision, only: &
     793             :         core_rknd  ! Variable(s)
     794             : 
     795             :     implicit none
     796             : 
     797             :     ! Input Variables
     798             :     integer, intent(in) :: &
     799             :       nz,      & ! Number of model vertical grid levels
     800             :       ngrdcol    ! Number of grid columns
     801             : 
     802             :     real( kind = core_rknd ), intent(in) :: &
     803             :       upsilon_precip_frac_rat    ! ratio mixt_frac*precip_frac_1/precip_frac [-]
     804             : 
     805             :     real( kind = core_rknd ), dimension(ngrdcol,nz,hydromet_dim), intent(in) :: &
     806             :       hydromet    ! Mean of hydrometeor, hm (overall)           [units vary]
     807             : 
     808             :     real( kind = core_rknd ), dimension(ngrdcol,nz), intent(in) :: &
     809             :       precip_frac, & ! Precipitation fraction (overall)                      [-]
     810             :       mixt_frac      ! Mixture fraction                                      [-]
     811             : 
     812             :     real( kind = core_rknd ), dimension(ngrdcol), intent(in) :: &
     813             :       precip_frac_tol    ! Minimum precip. frac. when hydromet. are present  [-]
     814             : 
     815             :     ! Output Variables
     816             :     real( kind = core_rknd ), dimension(ngrdcol,nz), intent(out) :: &
     817             :       precip_frac_1, & ! Precipitation fraction (1st PDF component)     [-]
     818             :       precip_frac_2    ! Precipitation fraction (2nd PDF component)     [-]
     819             : 
     820             :     integer :: k, j  ! Loop index.
     821             : 
     822             : 
     823             :     ! There are hydrometeors found at this grid level.
     824           0 :     if ( abs(upsilon_precip_frac_rat - one) < &
     825             :           abs(upsilon_precip_frac_rat + one) / 2 * eps ) then
     826             : 
     827             : 
     828             :       ! Loop over all vertical levels.
     829           0 :       do k = 1, nz, 1
     830           0 :         do j = 1, ngrdcol
     831             : 
     832           0 :           if ( any( hydromet(j,k,:) >= hydromet_tol(:) ) ) then
     833             :              
     834           0 :             if ( precip_frac(j,k) <= mixt_frac(j,k) ) then
     835             : 
     836             :               ! All the precipitation is found in the 1st PDF component.
     837           0 :               precip_frac_1(j,k) = precip_frac(j,k) / mixt_frac(j,k)
     838           0 :               precip_frac_2(j,k) = zero
     839             : 
     840             :             else ! precip_frac(k) > mixt_frac(k)
     841             : 
     842             :               ! Some precipitation is found in the 2nd PDF component.
     843           0 :               precip_frac_1(j,k) = one
     844             :               precip_frac_2(j,k) = ( precip_frac(j,k) - mixt_frac(j,k) ) &
     845           0 :                                  / ( one - mixt_frac(j,k) )
     846             : 
     847             :               if ( precip_frac_2(j,k) > one &
     848           0 :                    .and. abs(precip_frac(j,k) - one) < abs(precip_frac(j,k) + one) / 2 * eps ) then
     849             : 
     850             :                  ! Set precip_frac_2 = 1.
     851           0 :                  precip_frac_2(j,k) = one
     852             : 
     853           0 :               elseif ( precip_frac_2(j,k) < precip_frac_tol(j) ) then
     854             : 
     855             :                 ! Since precipitation is found in the 2nd PDF component, it
     856             :                 ! must have a value of at least precip_frac_tol.
     857           0 :                 precip_frac_2(j,k) = precip_frac_tol(j)
     858             : 
     859             :                 ! Recalculate precip_frac_1
     860             :                 precip_frac_1(j,k) &
     861             :                  = ( precip_frac(j,k) &
     862             :                      - ( one - mixt_frac(j,k) ) * precip_frac_2(j,k) ) &
     863           0 :                    / mixt_frac(j,k)
     864             : 
     865             :                 ! Double check precip_frac_1
     866           0 :                 if ( precip_frac_1(j,k) > one ) then
     867             : 
     868           0 :                   precip_frac_1(j,k) = one
     869             : 
     870             :                   precip_frac_2(j,k) = ( precip_frac(j,k) - mixt_frac(j,k) ) &
     871           0 :                                        / ( one - mixt_frac(j,k) )
     872             : 
     873           0 :                 elseif ( precip_frac_1(j,k) < precip_frac_tol(j) ) then
     874             : 
     875           0 :                   precip_frac_1(j,k) = precip_frac_tol(j)
     876             : 
     877             :                   ! fp = a*fp1+(1-a)*fp2 solving for fp2
     878             :                   precip_frac_2(j,k) = precip_frac_1(j,k) * &
     879             :                                        ( ( ( precip_frac(j,k) / precip_frac_1(j,k)) &
     880           0 :                                        - mixt_frac(j,k) ) / ( one - mixt_frac(j,k) ) )
     881             : 
     882             :                 end if
     883             : 
     884             :               end if ! precip_frac_2(k) < precip_frac_tol
     885             : 
     886             :             endif ! precip_frac(k) <= mixt_frac(k)
     887             :             
     888             :           else ! all( hydromet(k,:) < hydromet_tol(:) )
     889             :             ! There aren't any hydrometeors found at the grid level.
     890           0 :             precip_frac_1(j,k) = zero
     891           0 :             precip_frac_2(j,k) = zero
     892             :           end if
     893             :           
     894             :         end do
     895             :       end do
     896             : 
     897           0 :     elseif ( abs(upsilon_precip_frac_rat - zero) < &
     898             :           abs(upsilon_precip_frac_rat + zero) / 2 * eps ) then
     899             : 
     900           0 :       do k = 1, nz, 1
     901           0 :         do j = 1, ngrdcol
     902             : 
     903           0 :           if ( any( hydromet(j,k,:) >= hydromet_tol(:) ) ) then
     904             :             
     905           0 :             if ( precip_frac(j,k) <= ( one - mixt_frac(j,k) ) ) then
     906             : 
     907             :               ! All the precipitation is found in the 2nd PDF component.
     908           0 :               precip_frac_1(j,k) = zero
     909           0 :               precip_frac_2(j,k) = precip_frac(j,k) / ( one - mixt_frac(j,k) )
     910             : 
     911             :             else ! precip_frac(k) > ( 1 - mixt_frac(k) )
     912             : 
     913             :               ! Some precipitation is found in the 1st PDF component.
     914             :               precip_frac_1(j,k) = ( precip_frac(j,k) - ( one - mixt_frac(j,k) ) ) &
     915           0 :                                     / mixt_frac(j,k)
     916           0 :               precip_frac_2(j,k) = one
     917             : 
     918             :               if ( precip_frac_1(j,k) > one &
     919           0 :                    .and. abs(precip_frac(j,k) - one) < abs(precip_frac(j,k) + one) / 2 * eps ) then
     920             : 
     921             :                 ! Set precip_frac_1 = 1.
     922           0 :                 precip_frac_1(j,k) = one
     923             : 
     924           0 :               elseif ( precip_frac_1(j,k) < precip_frac_tol(j) ) then
     925             : 
     926             :                 ! Since precipitation is found in the 1st PDF component, it
     927             :                 ! must have a value of at least precip_frac_tol.
     928           0 :                 precip_frac_1(j,k) = precip_frac_tol(j)
     929             : 
     930             :                 ! Recalculate precip_frac_2
     931             :                 precip_frac_2(j,k) = ( precip_frac(j,k) &
     932             :                                        - mixt_frac(j,k) * precip_frac_1(j,k) ) &
     933           0 :                                       / ( one - mixt_frac(j,k) )
     934             : 
     935             :                 ! Double check precip_frac_2
     936           0 :                 if ( precip_frac_2(j,k) > one ) then
     937             : 
     938           0 :                   precip_frac_2(j,k) = one
     939             : 
     940             :                   precip_frac_1(j,k) = ( ( precip_frac(j,k) - one ) + mixt_frac(j,k) ) &
     941           0 :                                        / mixt_frac(j,k)
     942             : 
     943           0 :                 elseif ( precip_frac_2(j,k) < precip_frac_tol(j) ) then
     944             : 
     945           0 :                   precip_frac_2(j,k) = precip_frac_tol(j)
     946             : 
     947             :                   ! fp = a*fp1+(1-a)*fp2 solving for fp1
     948             :                   precip_frac_1(j,k) = ( precip_frac(j,k) - precip_frac_2(j,k) ) / mixt_frac(j,k) &
     949           0 :                                        + precip_frac_2(j,k)
     950             : 
     951             :                 endif
     952             : 
     953             :               end if ! precip_frac_1(k) < precip_frac_tol
     954             : 
     955             :             endif ! precip_frac(k) <= ( 1 - mixt_frac(k) )
     956             :             
     957             :           else ! all( hydromet(k,:) < hydromet_tol(:) )
     958             :             ! There aren't any hydrometeors found at the grid level.
     959           0 :             precip_frac_1(j,k) = zero
     960           0 :             precip_frac_2(j,k) = zero
     961             :           end if
     962             :           
     963             :         end do
     964             :       end do
     965             : 
     966             :     else  ! 0 < upsilon_precip_frac_rat < 1
     967             : 
     968           0 :       do k = 1, nz, 1
     969           0 :         do j = 1, ngrdcol
     970             : 
     971           0 :           if ( any( hydromet(j,k,:) >= hydromet_tol(:) ) ) then
     972             :             ! Precipitation is found in both PDF components.  Each component
     973             :             ! must have a precipitation fraction that is at least
     974             :             ! precip_frac_tol and that does not exceed 1.
     975             : 
     976             :             ! Calculate precipitation fraction in the 1st PDF component.
     977             :             precip_frac_1(j,k) &
     978           0 :             = upsilon_precip_frac_rat * precip_frac(j,k) / mixt_frac(j,k)
     979             : 
     980             :             ! Special cases for precip_frac_1
     981           0 :             if ( precip_frac_1(j,k) > one ) then
     982           0 :               precip_frac_1(j,k) = one
     983           0 :             elseif ( precip_frac_1(j,k) < precip_frac_tol(j) ) then
     984           0 :               precip_frac_1(j,k) = precip_frac_tol(j)
     985             :             endif
     986             : 
     987             :             ! Calculate precipitation fraction in the 2nd PDF component.
     988             :             precip_frac_2(j,k) = ( precip_frac(j,k) &
     989             :                                    - mixt_frac(j,k) * precip_frac_1(j,k) ) &
     990           0 :                                  / ( one - mixt_frac(j,k) )
     991             : 
     992             :             ! Special case for precip_frac_2
     993           0 :             if ( precip_frac_2(j,k) > one ) then
     994             : 
     995             :               ! Set precip_frac_2 to 1.
     996           0 :               precip_frac_2(j,k) = one
     997             : 
     998             :               ! Recalculate precipitation fraction in the 1st PDF component.
     999             :               precip_frac_1(j,k) &
    1000           0 :               = ( precip_frac(j,k) - ( one - mixt_frac(j,k) ) ) / mixt_frac(j,k)
    1001             : 
    1002             :               ! Double check precip_frac_1
    1003           0 :               if ( precip_frac_1(j,k) > one ) then
    1004             : 
    1005           0 :                 precip_frac_1(j,k) = one
    1006             : 
    1007             :                 precip_frac_2(j,k) = ( precip_frac(j,k) - mixt_frac(j,k) ) &
    1008           0 :                                      / ( one - mixt_frac(j,k) )
    1009             : 
    1010           0 :               elseif ( precip_frac_1(j,k) < precip_frac_tol(j) ) then
    1011             : 
    1012           0 :                 precip_frac_1(j,k) = precip_frac_tol(j)
    1013             : 
    1014             :                 ! fp = a*fp1+(1-a)*fp2 solving for fp2
    1015             :                 precip_frac_2(j,k) = precip_frac_1(j,k) &
    1016             :                                      * ( ( ( precip_frac(j,k) / precip_frac_1(j,k)) &
    1017           0 :                                      - mixt_frac(j,k) ) / ( one - mixt_frac(j,k) ) )
    1018             : 
    1019             :               endif
    1020             : 
    1021           0 :             elseif ( precip_frac_2(j,k) < precip_frac_tol(j) ) then
    1022             : 
    1023             :               ! Set precip_frac_2 to precip_frac_tol.
    1024           0 :               precip_frac_2(j,k) = precip_frac_tol(j)
    1025             : 
    1026             :               ! Recalculate precipitation fraction in the 1st PDF component.
    1027             :               precip_frac_1(j,k) = ( precip_frac(j,k) &
    1028             :                                      - ( one - mixt_frac(j,k) ) * precip_frac_2(j,k) ) &
    1029           0 :                                    / mixt_frac(j,k)
    1030             : 
    1031             :               ! Double check precip_frac_1
    1032           0 :               if ( precip_frac_1(j,k) > one ) then
    1033             : 
    1034           0 :                 precip_frac_1(j,k) = one
    1035             : 
    1036             :                 precip_frac_2(j,k) = ( precip_frac(j,k) - mixt_frac(j,k) ) &
    1037           0 :                                      / ( one - mixt_frac(j,k) )
    1038             : 
    1039           0 :               elseif ( precip_frac_1(j,k) < precip_frac_tol(j) ) then
    1040             : 
    1041           0 :                 precip_frac_1(j,k) = precip_frac_tol(j)
    1042             : 
    1043             :                 ! fp = a*fp1+(1-a)*fp2 solving for fp2
    1044             :                 precip_frac_2(j,k) = precip_frac_1(j,k) &
    1045             :                                      * ( ( ( precip_frac(j,k) / precip_frac_1(j,k)) &
    1046           0 :                                      - mixt_frac(j,k) ) / ( one - mixt_frac(j,k) ) )
    1047             : 
    1048             :               end if
    1049             : 
    1050             :             end if ! Special cases for precip_frac_2
    1051             :          
    1052             :           else ! all( hydromet(k,:) < hydromet_tol(:) )
    1053             :             ! There aren't any hydrometeors found at the grid level.
    1054           0 :             precip_frac_1(j,k) = zero
    1055           0 :             precip_frac_2(j,k) = zero
    1056             :           end if
    1057             :           
    1058             :         end do
    1059             :       end do
    1060             : 
    1061             :     end if  ! upsilon_precip_frac_rat
    1062             : 
    1063           0 :     return
    1064             : 
    1065             :   end subroutine component_precip_frac_specify
    1066             : 
    1067             :   !=============================================================================
    1068           0 :   subroutine precip_frac_assert_check( nz, hydromet, mixt_frac, precip_frac, &
    1069           0 :                                        precip_frac_1, precip_frac_2, &
    1070             :                                        precip_frac_tol )
    1071             : 
    1072             :     ! Description:
    1073             :     ! Assertion check for the precipitation fraction code.
    1074             : 
    1075             :     ! References:
    1076             :     !-----------------------------------------------------------------------
    1077             : 
    1078             :     use constants_clubb, only: &
    1079             :         one,     & ! Constant(s)
    1080             :         zero,    &
    1081             :         fstderr, &
    1082             :         eps
    1083             : 
    1084             :     use array_index, only: &
    1085             :         hydromet_tol  ! Variable(s)
    1086             : 
    1087             :     use parameters_model, only: &
    1088             :         hydromet_dim  ! Variable(s)
    1089             : 
    1090             :     use clubb_precision, only: &
    1091             :         core_rknd  ! Variable(s)
    1092             : 
    1093             :     use error_code, only: &
    1094             :         err_code, &                     ! Error Indicator
    1095             :         clubb_fatal_error               ! Constant
    1096             : 
    1097             :     implicit none
    1098             : 
    1099             :     ! Input Variables
    1100             :     integer, intent(in) :: &
    1101             :       nz          ! Number of model vertical grid levels
    1102             : 
    1103             :     real( kind = core_rknd ), dimension(nz,hydromet_dim), intent(in) :: &
    1104             :       hydromet    ! Mean of hydrometeor, hm (overall)           [units vary]
    1105             : 
    1106             :     real( kind = core_rknd ), dimension(nz), intent(in) :: &
    1107             :       mixt_frac,     & ! Mixture fraction                               [-]
    1108             :       precip_frac,   & ! Precipitation fraction (overall)               [-]
    1109             :       precip_frac_1, & ! Precipitation fraction (1st PDF component)     [-]
    1110             :       precip_frac_2    ! Precipitation fraction (2nd PDF component)     [-]
    1111             : 
    1112             :     real( kind = core_rknd ), intent(in) :: &
    1113             :       precip_frac_tol    ! Minimum precip. frac. when hydromet. are present  [-]
    1114             : 
    1115             :     ! Local Variables
    1116             :     integer :: k  ! Loop index
    1117             : 
    1118             : 
    1119             :     ! Loop over all vertical levels.
    1120           0 :     do k = 1, nz, 1
    1121             : 
    1122           0 :        if ( any( hydromet(k,:) >= hydromet_tol(:) ) ) then
    1123             : 
    1124             :           ! Overall precipitation fraction cannot be less than precip_frac_tol
    1125             :           ! when a hydrometeor is present at a grid level.
    1126           0 :           if ( precip_frac(k) < precip_frac_tol ) then
    1127             :              write(fstderr,*) "precip_frac < precip_frac_tol when " &
    1128           0 :                               // "a hydrometeor is present"
    1129           0 :              write(fstderr,*) "level = ", k
    1130           0 :              write(fstderr,*) "precip_frac = ", precip_frac(k), &
    1131           0 :                               "precip_frac_tol = ", precip_frac_tol
    1132           0 :              err_code = clubb_fatal_error
    1133           0 :              return
    1134             :           endif
    1135             : 
    1136             :           ! Overall precipitation fraction cannot exceed 1.
    1137           0 :           if ( precip_frac(k) > one ) then
    1138           0 :              write(fstderr,*) "precip_frac > 1"
    1139           0 :              write(fstderr,*) "level = ", k
    1140           0 :              write(fstderr,*) "precip_frac = ", precip_frac(k)
    1141           0 :              err_code = clubb_fatal_error
    1142           0 :              return
    1143             :           endif
    1144             : 
    1145             :           ! Precipitation fraction in the 1st PDF component is allowed to be 0
    1146             :           ! when all the precipitation is found in the 2nd PDF component.
    1147             :           ! Otherwise, it cannot be less than precip_frac_tol when a hydrometeor
    1148             :           ! is present at a grid level.  In other words, it cannot have a value
    1149             :           ! that is greater than 0 but less than precip_frac_tol
    1150             :           if ( precip_frac_1(k) > zero &
    1151           0 :                .and. precip_frac_1(k) < precip_frac_tol ) then
    1152           0 :              write(fstderr,*) "0 < precip_frac_1 < precip_frac_tol"
    1153           0 :              write(fstderr,*) "level = ", k
    1154           0 :              write(fstderr,*) "precip_frac_1 = ", precip_frac_1(k), &
    1155           0 :                               "precip_frac_tol = ", precip_frac_tol
    1156           0 :              err_code = clubb_fatal_error
    1157           0 :              return
    1158             :           endif
    1159             : 
    1160             :           ! Precipitation fraction in the 1st PDF component cannot exceed 1.
    1161           0 :           if ( precip_frac_1(k) > one ) then
    1162           0 :              write(fstderr,*) "precip_frac_1 > 1"
    1163           0 :              write(fstderr,*) "level = ", k
    1164           0 :              write(fstderr,*) "precip_frac_1 = ", precip_frac_1(k)
    1165           0 :              err_code = clubb_fatal_error
    1166           0 :              return
    1167             :           endif
    1168             : 
    1169             :           ! Precipiation fraction in the 1st PDF component cannot be negative.
    1170           0 :           if ( precip_frac_1(k) < zero ) then
    1171           0 :              write(fstderr,*) "precip_frac_1 < 0"
    1172           0 :              write(fstderr,*) "level = ", k
    1173           0 :              write(fstderr,*) "precip_frac_1 = ", precip_frac_1(k)
    1174           0 :              err_code = clubb_fatal_error
    1175           0 :              return
    1176             :           endif
    1177             : 
    1178             :           ! Precipitation fraction in the 2nd PDF component is allowed to be 0
    1179             :           ! when all the precipitation is found in the 1st PDF component.
    1180             :           ! Otherwise, it cannot be less than precip_frac_tol when a hydrometeor
    1181             :           ! is present at a grid level.  In other words, it cannot have a value
    1182             :           ! that is greater than 0 but less than precip_frac_tol
    1183             :           if ( precip_frac_2(k) > zero &
    1184           0 :                .and. precip_frac_2(k) < precip_frac_tol ) then
    1185           0 :              write(fstderr,*) "0 < precip_frac_2 < precip_frac_tol"
    1186           0 :              write(fstderr,*) "level = ", k
    1187           0 :              write(fstderr,*) "precip_frac_2 = ", precip_frac_2(k), &
    1188           0 :                               "precip_frac_tol = ", precip_frac_tol
    1189           0 :              err_code = clubb_fatal_error
    1190           0 :              return
    1191             :           endif
    1192             : 
    1193             :           ! Precipitation fraction in the 2nd PDF component cannot exceed 1.
    1194           0 :           if ( precip_frac_2(k) > one ) then
    1195           0 :              write(fstderr,*) "precip_frac_2 > 1"
    1196           0 :              write(fstderr,*) "level = ", k
    1197           0 :              write(fstderr,*) "precip_frac_2 = ", precip_frac_2(k)
    1198           0 :              err_code = clubb_fatal_error
    1199           0 :              return
    1200             :           endif
    1201             : 
    1202             :           ! Precipiation fraction in the 2nd PDF component cannot be negative.
    1203           0 :           if ( precip_frac_2(k) < zero ) then
    1204           0 :              write(fstderr,*) "precip_frac_2 < 0"
    1205           0 :              write(fstderr,*) "level = ", k
    1206           0 :              write(fstderr,*) "precip_frac_2 = ", precip_frac_2(k)
    1207           0 :              err_code = clubb_fatal_error
    1208           0 :              return
    1209             :           endif
    1210             : 
    1211             :        else  ! all( hydromet(k,:) < hydromet_tol(:) )
    1212             : 
    1213             :           ! Overall precipitation fraction must be 0 when no hydrometeors are
    1214             :           ! found at a grid level.
    1215           0 :           if ( abs(precip_frac(k)) > eps) then
    1216           0 :              write(fstderr,*) "precip_frac /= 0 when no hydrometeors are found"
    1217           0 :              write(fstderr,*) "level = ", k
    1218           0 :              write(fstderr,*) "precip_frac = ", precip_frac(k)
    1219           0 :              err_code = clubb_fatal_error
    1220           0 :              return
    1221             :           endif
    1222             : 
    1223             :           ! Precipitation fraction in the 1st PDF component must be 0 when no
    1224             :           ! hydrometeors are found at a grid level.
    1225           0 :           if ( abs(precip_frac_1(k)) > eps) then
    1226             :              write(fstderr,*) "precip_frac_1 /= 0 when no hydrometeors " &
    1227           0 :                               // "are found"
    1228           0 :              write(fstderr,*) "level = ", k
    1229           0 :              write(fstderr,*) "precip_frac_1 = ", precip_frac_1(k)
    1230           0 :              err_code = clubb_fatal_error
    1231           0 :              return
    1232             :           endif
    1233             : 
    1234             :           ! Precipitation fraction in the 2nd PDF component must be 0 when no
    1235             :           ! hydrometeors are found at a grid level.
    1236           0 :           if ( abs(precip_frac_2(k)) > eps) then
    1237             :              write(fstderr,*) "precip_frac_2 /= 0 when no hydrometeors " &
    1238           0 :                               // "are found"
    1239           0 :              write(fstderr,*) "level = ", k
    1240           0 :              write(fstderr,*) "precip_frac_2 = ", precip_frac_2(k)
    1241           0 :              err_code = clubb_fatal_error
    1242           0 :              return
    1243             :           endif
    1244             : 
    1245             :        endif  ! any( hydromet(k,:) >= hydromet_tol(:) )
    1246             : 
    1247             :        ! The precipitation fraction equation is:
    1248             :        !
    1249             :        ! precip_frac
    1250             :        !    = mixt_frac * precip_frac_1 + ( 1 - mixt_frac ) * precip_frac_2;
    1251             :        !
    1252             :        ! which means that:
    1253             :        !
    1254             :        ! precip_frac
    1255             :        ! - ( mixt_frac * precip_frac_1 + ( 1 - mixt_frac ) * precip_frac_2 )
    1256             :        ! = 0.
    1257             :        !
    1258             :        ! Check that this is true with numerical round off.
    1259           0 :        if ( ( precip_frac(k) &
    1260             :               - ( mixt_frac(k) * precip_frac_1(k) &
    1261             :                   + ( one - mixt_frac(k) ) * precip_frac_2(k) ) ) &
    1262           0 :             > ( epsilon( precip_frac(k) ) * precip_frac(k) ) ) then
    1263             :           write(fstderr,*) "mixt_frac * precip_frac_1 " &
    1264             :                            // "+ ( 1 - mixt_frac ) * precip_frac_2 " &
    1265           0 :                            // "/= precip_frac within numerical roundoff"
    1266           0 :           write(fstderr,*) "level = ", k
    1267             :           write(fstderr,*) "mixt_frac * precip_frac_1 " &
    1268           0 :                            // "+ ( 1 - mixt_frac ) * precip_frac_2 = ", &
    1269           0 :                            mixt_frac(k) * precip_frac_1(k) &
    1270           0 :                            + ( one - mixt_frac(k) ) * precip_frac_2(k)
    1271           0 :           write(fstderr,*) "precip_frac = ", precip_frac(k)
    1272           0 :           err_code = clubb_fatal_error
    1273           0 :           return
    1274             :        endif
    1275             : 
    1276             :     enddo  ! k = 1, nz, 1
    1277             : 
    1278             : 
    1279             :     return
    1280             : 
    1281             :   end subroutine precip_frac_assert_check
    1282             : 
    1283             : !===============================================================================
    1284             : 
    1285             : end module precipitation_fraction

Generated by: LCOV version 1.14