@@ -494,7 +494,7 @@ end function wgtpct
494494
495495 !- -----------------------------------------------------------------------------
496496 ! Compute BAM number concentration (#/m3) and mass concentration (kg/m3)
497- ! for a single bin. Hardcodes the sulfate scale factor (bam_sulfate_scale ).
497+ ! for a single bin. Applies bam_sulfate_scale only to SULFATE (not volcanic ).
498498 ! b4b operation order: (mmr * rho) first, then * ntm [* 2.0 for sulfate].
499499 !- -----------------------------------------------------------------------------
500500 subroutine get_bulk_num_and_mass (self , bin_ndx , ncol , rho , naer2 , maerosol )
@@ -513,10 +513,16 @@ subroutine get_bulk_num_and_mass(self, bin_ndx, ncol, rho, naer2, maerosol)
513513 call rad_aer_get_props(self% list_idx_, bin_ndx, num_to_mass_aer= ntm, aername= aname)
514514
515515 ! b4b operation order: (mmr * rho) first, then * ntm [* 2.0 for sulfate]
516+ !
517+ ! Note: only SULFATE gets the scale factor here.
518+ ! Volcanic aerosol (which also has spectype 'sulfate') does not get scaled in the
519+ ! ndrop_bam/CCN path (which only scales idxsul, SULFATE here)
520+ ! Ice nucleation has been unified to also use this path, but it does scale volcanic
521+ ! aerosol; it will apply this scale factor separately.
516522 maerosol(:ncol,:) = mmr(:ncol,:) * rho(:ncol,:)
517523
518524 select case ( to_lower( aname(:4 ) ) )
519- case (' sulf' , ' volc ' )
525+ case (' sulf' )
520526 naer2(:ncol,:) = maerosol(:ncol,:) * ntm * bam_sulfate_scale
521527 case default
522528 naer2(:ncol,:) = maerosol(:ncol,:) * ntm
@@ -535,9 +541,8 @@ end subroutine get_bulk_num_and_mass
535541 ! giving: (mmr * rho * ntm) / 25 * 1e-6
536542 !
537543 ! These differ only in floating-point operation order (associativity).
538- ! If this causes non-b4b results during testing, uncomment the procedure
539- ! binding in the type definition and this override to match the exact
540- ! original operation order.
544+ ! It has been shown that this rearranging causes answer differences, so we
545+ ! use this subroutine to replicate the original behavior.
541546 subroutine nuclice_get_numdens_bam (self , aero_props , use_preexisting_ice , &
542547 ncol , nlev , rho , dust_num_col , sulf_num_col , soot_num_col , sulf_num_tot_col )
543548 ! REMOVECAM: host-model specific dimensions
@@ -557,7 +562,7 @@ subroutine nuclice_get_numdens_bam(self, aero_props, use_preexisting_ice, &
557562
558563 real (r8 ) :: naer2_1bin(ncol,nlev)
559564 real (r8 ) :: maerosol_1bin(ncol,nlev)
560- character (len= 32 ) :: spectype
565+ character (len= 32 ) :: spectype, aname
561566 integer :: m, i, k
562567 real (r8 ), parameter :: per_cm3 = 1.e-6_r8
563568
@@ -570,6 +575,18 @@ subroutine nuclice_get_numdens_bam(self, aero_props, use_preexisting_ice, &
570575 call aero_props% species_type(m, 1 , spectype)
571576 call self% get_bulk_num_and_mass(m, ncol, rho, naer2_1bin, maerosol_1bin)
572577
578+ ! get_bulk_num_and_mass only applied bam_sulfate_scale to SULFATE (by name).
579+ ! For the nucleate_ice path, volcanic aerosol (spectype 'sulfate', name 'volc*')
580+ ! also needs the scale, matching the original inline code which scaled ALL
581+ ! spectype=='sulfate' bins including volcanic aerosol, so we will do it here:
582+ ! (but do not do it again for SULFATE)
583+ if (spectype == ' sulfate' ) then
584+ call rad_aer_get_props(self% list_idx_, m, aername= aname)
585+ if (to_lower(aname(:4 )) == ' volc' ) then
586+ naer2_1bin(:ncol,:nlev) = naer2_1bin(:ncol,:nlev) * bam_sulfate_scale
587+ end if
588+ end if
589+
573590 do k = 1 , nlev
574591 do i = 1 , ncol
575592 select case (trim (spectype))
0 commit comments