@@ -25,7 +25,8 @@ module microp_aero
2525use spmd_utils, only: masterproc
2626use ppgrid, only: pcols, pver, pverp
2727use ref_pres, only: top_lev = > trop_cloud_top_lev
28- use physconst, only: rair
28+ use physconst, only: rair, gravit, tmelt, cpair, rh2o, rhoh2o, latvap, &
29+ r_universal, mwh2o
2930use constituents, only: cnst_get_ind
3031use physics_types, only: physics_state, physics_ptend, physics_ptend_init, physics_ptend_sum, &
3132 physics_state_copy, physics_update
@@ -48,6 +49,10 @@ module microp_aero
4849use hetfrz_classnuc_cam, only: hetfrz_classnuc_cam_readnl, hetfrz_classnuc_cam_register, hetfrz_classnuc_cam_init, &
4950 hetfrz_classnuc_cam_calc
5051
52+ use compute_subgrid_vertical_velocity, only: compute_subgrid_vertical_velocity_tke_run, &
53+ compute_subgrid_vertical_velocity_kvh_run
54+ use scale_subgrid_vertical_velocity, only: scale_subgrid_vertical_velocity_run
55+
5156use cam_history, only: addfld, add_default, outfld
5257use cam_logfile, only: iulog
5358use cam_abortutils, only: endrun
@@ -312,7 +317,8 @@ subroutine microp_aero_init(phys_state,pbuf2d)
312317 aero_props_bulk = > null ()
313318 end do
314319
315- call ndrop_bam_init(masterproc, iulog)
320+ call ndrop_bam_init(masterproc, iulog, &
321+ mwh2o= mwh2o, r_universal= r_universal, tmelt= tmelt, rhoh2o= rhoh2o)
316322
317323 ! Set module-level props object for BAM (used by nucleate_ice_cam)
318324 aero_props_obj = > aero_props_bulk
@@ -524,7 +530,6 @@ subroutine microp_aero_run ( &
524530 real (r8 ) :: cldliqf(pcols,pver) ! fractional of total cloud that is liquid
525531 real (r8 ) :: qcld ! total cloud water
526532 real (r8 ) :: nctend_mixnuc(pcols,pver)
527- real (r8 ) :: dum ! temporary dummy variable
528533 real (r8 ) :: dmc, ssmc, so4mc ! variables for modal scheme.
529534
530535 ! BAM diagnostic output from ndrop_bam_run
@@ -558,7 +563,6 @@ subroutine microp_aero_run ( &
558563 ncol = state1% ncol
559564
560565 itim_old = pbuf_old_tim_idx()
561- call pbuf_get_field(pbuf, ast_idx, ast, start= (/ 1 ,1 ,itim_old/ ), kount= (/ pcols,pver,1 / ))
562566
563567 call pbuf_get_field(pbuf, npccn_idx, npccn)
564568
@@ -634,7 +638,6 @@ subroutine microp_aero_run ( &
634638 ! cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
635639 ! More refined computation of sub-grid vertical velocity
636640 ! Set to be zero at the surface by initialization.
637-
638641 select case (trim (eddy_scheme))
639642 case (' diag_TKE' )
640643 call pbuf_get_field(pbuf, tke_idx, tke)
@@ -643,42 +646,50 @@ subroutine microp_aero_run ( &
643646 call pbuf_get_field(pbuf, wp2_idx, wp2, start= (/ 1 ,1 ,itim_old/ ),kount= (/ pcols,pverp,1 / ))
644647 allocate (tke(pcols,pverp))
645648 tke(:ncol,:) = (3._r8 / 2._r8 )* wp2(:ncol,:)
646-
647649 case default
648650 call pbuf_get_field(pbuf, kvh_idx, kvh)
649651 end select
650652
651- ! Set minimum values above top_lev.
652- wsub(:ncol,:top_lev-1 ) = wsub_min
653- wsubi(:ncol,:top_lev-1 ) = wsubi_min
654-
655- do k = top_lev, pver
656- do i = 1 , ncol
657-
658- select case (trim (eddy_scheme))
659- case (' diag_TKE' , ' CLUBB_SGS' )
660- wsub(i,k) = sqrt (0.5_r8 * (tke(i,k) + tke(i,k+1 ))* (2._r8 / 3._r8 ))
661- wsub(i,k) = min (wsub(i,k),10._r8 )
662- case default
663- ! get sub-grid vertical velocity from diff coef.
664- ! following morrison et al. 2005, JAS
665- ! assume mixing length of 30 m
666- dum = (kvh(i,k) + kvh(i,k+1 ))/ 2._r8 / 30._r8
667- ! use maximum sub-grid vertical vel of 10 m/s
668- dum = min (dum, 10._r8 )
669- ! set wsub to value at current vertical level
670- wsub(i,k) = dum
671- end select
672-
673- wsubi(i,k) = max (wsubi_min, wsub(i,k)) * wsubi_scale
674- if (.not. use_preexisting_ice) then
675- wsubi(i,k) = min (wsubi(i,k), 0.2_r8 )
676- endif
677-
678- wsub(i,k) = max (wsub_min, wsub(i,k)) * wsub_scale
653+ ! Compute raw wsub from TKE or KVH via CCPP-ized routines
654+ wsub(:,:) = 0._r8
655+ select case (trim (eddy_scheme))
656+ case (' diag_TKE' , ' CLUBB_SGS' )
657+ call compute_subgrid_vertical_velocity_tke_run( &
658+ ncol = ncol, &
659+ pver = pver, &
660+ top_lev = top_lev, &
661+ tke = tke(:ncol,:pverp), &
662+ wsub = wsub(:ncol,:pver), &
663+ errmsg = errmsg, &
664+ errflg = errflg)
665+ if (errflg /= 0 ) call endrun(' compute_subgrid_vertical_velocity_tke_run: ' // errmsg)
666+ case default
667+ call compute_subgrid_vertical_velocity_kvh_run( &
668+ ncol = ncol, &
669+ pver = pver, &
670+ top_lev = top_lev, &
671+ kvh = kvh(:ncol,:pverp), &
672+ wsub = wsub(:ncol,:pver), &
673+ errmsg = errmsg, &
674+ errflg = errflg)
675+ if (errflg /= 0 ) call endrun(' compute_subgrid_vertical_velocity_kvh_run: ' // errmsg)
676+ end select
679677
680- end do
681- end do
678+ ! Apply min/max/scale and derive wsubi (for ice nucleation)
679+ call scale_subgrid_vertical_velocity_run( &
680+ ncol = ncol, &
681+ pver = pver, &
682+ top_lev = top_lev, &
683+ wsub_min = wsub_min, &
684+ wsubi_min = wsubi_min, &
685+ wsub_scale = wsub_scale, &
686+ wsubi_scale = wsubi_scale, &
687+ use_preexisting_ice = use_preexisting_ice, &
688+ wsub = wsub(:ncol,:pver), &
689+ wsubi = wsubi(:ncol,:pver), &
690+ errmsg = errmsg, &
691+ errflg = errflg)
692+ if (errflg /= 0 ) call endrun(' scale_subgrid_vertical_velocity_run: ' // errmsg)
682693
683694 call outfld(' WSUB' , wsub, pcols, lchnk)
684695 call outfld(' WSUBI' , wsubi, pcols, lchnk)
@@ -697,18 +708,8 @@ subroutine microp_aero_run ( &
697708 call physics_ptend_sum(ptend_loc, ptend_all, ncol)
698709 call physics_update(state1, ptend_loc, deltatin)
699710
700- ! cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
701- ! get liquid cloud fraction, check for minimum
702-
703- do k = top_lev, pver
704- do i = 1 , ncol
705- lcldm(i,k) = max (ast(i,k), mincld)
706- end do
707- end do
708-
709711 ! cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
710712 ! Droplet Activation
711-
712713 if (clim_modal_aero .or. clim_carma_aero) then
713714
714715 ! for modal or carma aerosol
@@ -737,6 +738,8 @@ subroutine microp_aero_run ( &
737738
738739 ! If not using preexsiting ice, then only use cloudbourne aerosol for the
739740 ! liquid clouds. This is the same behavior as CAM5.
741+ !
742+ ! ptend_loc is initialized inside dropmixnuc
740743 if (use_preexisting_ice) then
741744 call dropmixnuc( aero_props_obj, aero_state1_obj, &
742745 state1, ptend_loc, deltatin, pbuf, wsub, wsub_min_asf, &
@@ -757,6 +760,11 @@ subroutine microp_aero_run ( &
757760 ! for bulk aerosol: activation, contact freezing, CCN diagnostics
758761 ! do not run for aquaplanet compsets which also gets in this path.
759762 if (associated (aero_state1_obj)) then
763+ ! get liquid cloud fraction. scaling is done within the ndrop_bam scheme.
764+ call pbuf_get_field(pbuf, ast_idx, ast, start= (/ 1 ,1 ,itim_old/ ), kount= (/ pcols,pver,1 / ))
765+
766+ ! ndrop_bam has no tendencies; this is initialized in order
767+ ! for ptend_loc accummulation to happen the same as dropmixnuc above.
760768 call physics_ptend_init(ptend_loc, state1% psetcols, ' none' )
761769
762770 allocate (ccn_bam(pcols, pver, psat))
@@ -774,12 +782,19 @@ subroutine microp_aero_run ( &
774782 ncol = ncol, &
775783 pver = pver, &
776784 top_lev = top_lev, &
785+ gravit = gravit, &
786+ rair = rair, &
787+ tmelt = tmelt, &
788+ cpair = cpair, &
789+ rh2o = rh2o, &
790+ rhoh2o = rhoh2o, &
791+ latvap = latvap, &
777792 rho = rho(:ncol,:), &
778793 tair = state1% t(:ncol,:), &
779794 wsub = wsub(:ncol,:), &
780795 qcld = state1% q(:ncol,:,cldliq_idx), &
781796 qsmall_in = qsmall, &
782- lcldm = lcldm (:ncol,:), &
797+ ast = ast (:ncol,:), &
783798 numliq = state1% q(:ncol,:,numliq_idx), &
784799 deltatin = deltatin, &
785800 npccn = npccn(:ncol,:), &
@@ -802,18 +817,17 @@ subroutine microp_aero_run ( &
802817 ! cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
803818 ! Contact freezing (-40<T<-3 C) (Young, 1974) with hooks into simulated dust
804819 ! estimate rndst and nacon for 4 dust bins here to pass to MG microphysics
805-
806- do k = top_lev, pver
807- do i = 1 , ncol
808-
809- if (state1% t(i,k) < 269.15_r8 ) then
810-
811- if (clim_modal_aero) then
812-
813- ! For modal aerosols:
814- ! use size '3' for dust coarse mode...
815- ! scale by dust fraction in coarse mode
816-
820+ !
821+ ! For bulk aerosol contact freezing is handled inside ndrop_bam_run
822+ ! (nacon is output from ndrop_bam_run)
823+ ! Below for modal aerosol only:
824+ if (clim_modal_aero) then
825+ ! For modal aerosols:
826+ ! use size '3' for dust coarse mode...
827+ ! scale by dust fraction in coarse mode
828+ do k = top_lev, pver
829+ do i = 1 , ncol
830+ if (state1% t(i,k) < 269.15_r8 ) then
817831 dmc = coarse_dust(i,k)
818832 ssmc = coarse_nacl(i,k)
819833
@@ -832,26 +846,20 @@ subroutine microp_aero_run ( &
832846 nacon(i,k,3 ) = 0._r8
833847 end if
834848
835- ! also redefine parameters based on size...
836-
849+ ! also redefine parameters based on size...
837850 rndst(i,k,3 ) = 0.5_r8 * dgnumwet(i,k,mode_coarse_dst_idx)
838851 if (rndst(i,k,3 ) <= 0._r8 ) then
839852 rndst(i,k,3 ) = rn_dst3
840853 end if
841-
842854 end if
843-
844- ! For bulk aerosol contact freezing is handled inside ndrop_bam_run
845- ! nacon is output from ndrop_bam_run
846-
847- end if
855+ end do
848856 end do
849- end do
857+ end if
850858
851859 ! cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
852860 ! BAM diagnostic output (CCN concentration and aerosol number)
853-
854- if (( .not. clim_modal_aero) .and. ( .not. clim_carma_aero) .and. allocated (ccn_bam) .and. allocated (naer2_bam)) then
861+ if (( .not. clim_modal_aero) .and. ( .not. clim_carma_aero) .and. & ! not modal / carma
862+ allocated (ccn_bam) .and. allocated (naer2_bam)) then ! and bulk aerosols are active (not aquap)
855863 do l = 1 , psat
856864 call outfld(ccn_name(l), ccn_bam(1 ,1 ,l), pcols, lchnk)
857865 end do
0 commit comments