@@ -18,12 +18,11 @@ module bulk_aerosol_state_mod
1818
1919 private
2020
21- ! BAM sulfate scaling factor — set once at init by microp_aero_init,
22- ! read-only thereafter. Thread-safe for concurrent chunk processing .
23- real (r8 ), save :: bulk_scale_mod_ = 1 .0_r8
21+ ! BAM sulfate scaling factor:
22+ ! former microp_aero_bulk_scale namelist parameter (always 2.0) .
23+ real (r8 ), parameter :: bam_sulfate_scale = 2 .0_r8
2424
2525 public :: bulk_aerosol_state
26- public :: bulk_aerosol_state_set_bulk_scale
2726
2827 type, extends(aerosol_state) :: bulk_aerosol_state
2928 private
@@ -35,8 +34,6 @@ module bulk_aerosol_state_mod
3534
3635 ! Per-object workspace for derived number mixing ratio.
3736 ! Allocated in constructor, deallocated in destructor.
38- ! Pointer members can have their target data modified even
39- ! when self is intent(in) — only pointer association is protected.
4037 real (r8 ), pointer :: num_work_(:,:) = > null () ! (horizontal_dimension, vertical_layer_dimension)
4138 real (r8 ), pointer :: zero_fld_(:,:) = > null () ! (horizontal_dimension, vertical_layer_dimension)
4239
@@ -63,6 +60,7 @@ module bulk_aerosol_state_mod
6360 procedure :: wet_diameter
6461 procedure :: convcld_actfrac
6562 procedure :: wgtpct
63+ procedure :: get_bulk_num_and_mass
6664 ! for bit-for-bit
6765 procedure :: nuclice_get_numdens = > nuclice_get_numdens_bam
6866
@@ -195,7 +193,7 @@ subroutine get_cldbrne_mmr(self, species_ndx, bin_ndx, mmr)
195193 integer , intent (in ) :: bin_ndx ! bin index
196194 real (r8 ), pointer :: mmr(:,:) ! mass mixing ratios (ncol,nlev)
197195
198- ! BAM has no cloud-borne aerosol pool — return zero array.
196+ ! BAM has no cloud-borne aerosol equivalent, return zero array.
199197 mmr = > self% zero_fld_
200198
201199 end subroutine get_cldbrne_mmr
@@ -212,17 +210,17 @@ subroutine get_ambient_num(self, bin_ndx, num)
212210 real (r8 ) :: ntm
213211 character (len= 32 ) :: aname
214212
215- ! Derive number mixing ratio from mass: num = mmr * num_to_mass_aer (* bulk_scale for sulfate).
213+ ! Derive number mixing ratio from mass: num = mmr * num_to_mass_aer (* bam_sulfate_scale for sulfate).
216214 ! This matches the inline computation formerly in microp_aero.F90 and nucleate_ice_cam.F90.
217215 ! Computed into per-object workspace (num_work_); callers must use or copy before the next call.
218216
219217 call rad_cnst_get_aer_mmr(self% list_idx_, bin_ndx, self% state, self% pbuf, mmr)
220218 call rad_aer_get_props(self% list_idx_, bin_ndx, num_to_mass_aer= ntm, aername= aname)
221219
222- ! Apply bulk_scale to sulfate/volcanic aerosol
220+ ! Apply bam_sulfate_scale to sulfate/volcanic aerosol
223221 select case ( to_lower( aname(:4 ) ) )
224222 case (' sulf' , ' volc' ) ! both treated as 'sulfate' in aero_props%get type.
225- self% num_work_(:,:) = mmr(:,:) * ntm * bulk_scale_mod_
223+ self% num_work_(:,:) = mmr(:,:) * ntm * bam_sulfate_scale
226224 case default
227225 self% num_work_(:,:) = mmr(:,:) * ntm
228226 end select
@@ -239,7 +237,7 @@ subroutine get_cldbrne_num(self, bin_ndx, num)
239237 integer , intent (in ) :: bin_ndx ! bin index
240238 real (r8 ), pointer :: num(:,:)
241239
242- ! BAM has no cloud-borne aerosol pool — return zero array.
240+ ! BAM has no cloud-borne equivalent, return zero array.
243241 num = > self% zero_fld_
244242
245243 end subroutine get_cldbrne_num
@@ -495,17 +493,40 @@ function wgtpct(self, ncol, nlev) result(wtp)
495493 end function wgtpct
496494
497495 !- -----------------------------------------------------------------------------
498- ! Set the BAM sulfate scaling factor (bulk_scale namelist parameter).
499- ! Called once from microp_aero_init; read-only thereafter.
496+ ! Compute BAM number concentration (#/m3) and mass concentration (kg/m3)
497+ ! for a single bin. Hardcodes the sulfate scale factor (bam_sulfate_scale).
498+ ! b4b operation order: (mmr * rho) first, then * ntm [* 2.0 for sulfate].
500499 !- -----------------------------------------------------------------------------
501- subroutine bulk_aerosol_state_set_bulk_scale (scale )
502- real (r8 ), intent (in ) :: scale
503- bulk_scale_mod_ = scale
504- end subroutine bulk_aerosol_state_set_bulk_scale
500+ subroutine get_bulk_num_and_mass (self , bin_ndx , ncol , rho , naer2 , maerosol )
501+ class(bulk_aerosol_state), intent (in ) :: self
502+ integer , intent (in ) :: bin_ndx
503+ integer , intent (in ) :: ncol
504+ real (r8 ), intent (in ) :: rho(:,:) ! air density (kg/m3), (ncol,pver)
505+ real (r8 ), intent (out ) :: naer2(:,:) ! number concentration (#/m3)
506+ real (r8 ), intent (out ) :: maerosol(:,:) ! mass concentration (kg/m3)
507+
508+ real (r8 ), pointer :: mmr(:,:)
509+ real (r8 ) :: ntm
510+ character (len= 32 ) :: aname
511+
512+ call rad_cnst_get_aer_mmr(self% list_idx_, bin_ndx, self% state, self% pbuf, mmr)
513+ call rad_aer_get_props(self% list_idx_, bin_ndx, num_to_mass_aer= ntm, aername= aname)
514+
515+ ! b4b operation order: (mmr * rho) first, then * ntm [* 2.0 for sulfate]
516+ maerosol(:ncol,:) = mmr(:ncol,:) * rho(:ncol,:)
517+
518+ select case ( to_lower( aname(:4 ) ) )
519+ case (' sulf' , ' volc' )
520+ naer2(:ncol,:) = maerosol(:ncol,:) * ntm * bam_sulfate_scale
521+ case default
522+ naer2(:ncol,:) = maerosol(:ncol,:) * ntm
523+ end select
524+
525+ end subroutine get_bulk_num_and_mass
505526
506527 ! NOTE on bit-for-bit: The base-class nuclice_get_numdens computes:
507528 ! size_wght * type_wght * num_col(#/kg) * rho * per_cm3
508- ! where for BAM: num_col = mmr * ntm [* bulk_scale ], size_wght = 1/25, type_wght = 1.0
529+ ! where for BAM: num_col = mmr * ntm [* bam_sulfate_scale ], size_wght = 1/25, type_wght = 1.0
509530 ! giving: (1/25) * 1.0 * (mmr * ntm) * rho * 1e-6
510531 !
511532 ! The original inline BAM code (nucleate_ice_cam.F90, removed) computed:
@@ -519,6 +540,9 @@ end subroutine bulk_aerosol_state_set_bulk_scale
519540 ! original operation order.
520541 subroutine nuclice_get_numdens_bam (self , aero_props , use_preexisting_ice , &
521542 ncol , nlev , rho , dust_num_col , sulf_num_col , soot_num_col , sulf_num_tot_col )
543+ ! REMOVECAM: host-model specific dimensions
544+ use ppgrid, only: pcols, pver
545+ ! REMOVECAM_END
522546
523547 class(bulk_aerosol_state), intent (in ) :: self
524548 class(aerosol_properties), intent (in ) :: aero_props
@@ -531,8 +555,8 @@ subroutine nuclice_get_numdens_bam(self, aero_props, use_preexisting_ice, &
531555 real (r8 ), intent (out ) :: soot_num_col(:,:)
532556 real (r8 ), intent (out ) :: sulf_num_tot_col(:,:)
533557
534- real (r8 ), pointer :: aer_mmr(:,: )
535- real (r8 ) :: ntm, maerosol, naer2
558+ real (r8 ) :: naer2_1bin(ncol,nlev )
559+ real (r8 ) :: maerosol_1bin(ncol,nlev)
536560 character (len= 32 ) :: spectype
537561 integer :: m, i, k
538562 real (r8 ), parameter :: per_cm3 = 1.e-6_r8
@@ -544,26 +568,18 @@ subroutine nuclice_get_numdens_bam(self, aero_props, use_preexisting_ice, &
544568
545569 do m = 1 , aero_props% nbins()
546570 call aero_props% species_type(m, 1 , spectype)
547- call self% get_ambient_mmr(species_ndx= 1 , bin_ndx= m, mmr= aer_mmr)
548- call rad_aer_get_props(self% list_idx_, m, num_to_mass_aer= ntm)
571+ call self% get_bulk_num_and_mass(m, ncol, rho, naer2_1bin, maerosol_1bin)
549572
550- ! Exact original operation order: mmr * rho * ntm, then / 25 * per_cm3
551573 do k = 1 , nlev
552574 do i = 1 , ncol
553- maerosol = aer_mmr(i,k) * rho(i,k)
554- if (spectype == ' sulfate' ) then
555- naer2 = maerosol * ntm * bulk_scale_mod_
556- else
557- naer2 = maerosol * ntm
558- end if
559575 select case (trim (spectype))
560576 case (' dust' )
561- dust_num_col(i,k) = dust_num_col(i,k) + naer2 / 25._r8 * per_cm3
577+ dust_num_col(i,k) = dust_num_col(i,k) + naer2_1bin(i,k) / 25._r8 * per_cm3
562578 case (' sulfate' )
563- sulf_num_col(i,k) = sulf_num_col(i,k) + naer2 / 25._r8 * per_cm3
564- sulf_num_tot_col(i,k) = sulf_num_tot_col(i,k) + naer2 / 25._r8 * per_cm3
579+ sulf_num_col(i,k) = sulf_num_col(i,k) + naer2_1bin(i,k) / 25._r8 * per_cm3
580+ sulf_num_tot_col(i,k) = sulf_num_tot_col(i,k) + naer2_1bin(i,k) / 25._r8 * per_cm3
565581 case (' black-c' )
566- soot_num_col(i,k) = soot_num_col(i,k) + naer2 / 25._r8 * per_cm3
582+ soot_num_col(i,k) = soot_num_col(i,k) + naer2_1bin(i,k) / 25._r8 * per_cm3
567583 end select
568584 end do
569585 end do
0 commit comments