diff --git a/bld/configure b/bld/configure index ed35b593e9..6193e62b02 100755 --- a/bld/configure +++ b/bld/configure @@ -989,13 +989,6 @@ if ($rad_pkg eq 'camrt') { " with aerosol package $chem_pkg\n"; } } -elsif ($rad_pkg =~ m/rrtmg/) { - - # RRTMGP not currently working with CARMA - if ($rad_pkg eq 'rrtmgp' and $carma_pkg ne 'none') { - die "configure ERROR: The CARMA microphysics package does not currently work with RRTMGP\n"; - } -} $cfg_ref->set('rad', $rad_pkg); diff --git a/cime_config/testdefs/testlist_cam.xml b/cime_config/testdefs/testlist_cam.xml index 42c6033122..83cd921c1f 100644 --- a/cime_config/testdefs/testlist_cam.xml +++ b/cime_config/testdefs/testlist_cam.xml @@ -324,6 +324,16 @@ + + + + + + + + + + @@ -1808,6 +1818,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/chemistry/aerosol/aero_convproc.F90 b/src/chemistry/aerosol/aero_convproc.F90 index 017914d225..6fbbcd2dfb 100644 --- a/src/chemistry/aerosol/aero_convproc.F90 +++ b/src/chemistry/aerosol/aero_convproc.F90 @@ -1711,8 +1711,8 @@ subroutine activate_convproc( aero_props, & character(len=32) :: spec_type real(r8) :: tmpa, tmpb, tmpc ! working variable - real(r8) :: naerosol_a(1) ! number conc (1/m3) - real(r8) :: vaerosol_a(1) ! volume conc (m3/m3) + real(r8) :: naerosol_a(1,1) ! number conc (1/m3) + real(r8) :: vaerosol_a(1,1) ! volume conc (m3/m3) !----------------------------------------------------------------------- @@ -1779,12 +1779,12 @@ subroutine activate_convproc( aero_props, & tmpa = tmpa + max( conent(2,mm), 0.0_r8 ) naerosol(m) = tmpa * rhoair - naerosol_a(1) = naerosol(m) - vaerosol_a(1) = vaerosol(m) + naerosol_a(1,1) = naerosol(m) + vaerosol_a(1,1) = vaerosol(m) call aero_props%apply_number_limits( naerosol_a, vaerosol_a, 1, 1, m ) - naerosol(m) = naerosol_a(1) + naerosol(m) = naerosol_a(1,1) end do ! call Razzak-Ghan activation routine with single updraft @@ -1918,8 +1918,8 @@ subroutine activate_convproc_method2( aero_props, & character(len=32) :: spec_type real(r8) :: tmpa, tmpb, tmpc ! working variable - real(r8) :: naerosol_a(1) ! number conc (1/m3) - real(r8) :: vaerosol_a(1) ! volume conc (m3/m3) + real(r8) :: naerosol_a(1,1) ! number conc (1/m3) + real(r8) :: vaerosol_a(1,1) ! volume conc (m3/m3) !----------------------------------------------------------------------- @@ -1999,12 +1999,12 @@ subroutine activate_convproc_method2( aero_props, & tmpa = tmpa + max( conu(2,mm), 0.0_r8 ) naerosol(m) = tmpa * rhoair - naerosol_a(1) = naerosol(m) - vaerosol_a(1) = vaerosol(m) + naerosol_a(1,1) = naerosol(m) + vaerosol_a(1,1) = vaerosol(m) call aero_props%apply_number_limits( naerosol_a, vaerosol_a, 1, 1, m ) - naerosol(m) = naerosol_a(1) + naerosol(m) = naerosol_a(1,1) end do diff --git a/src/chemistry/aerosol/aerosol_properties_mod.F90 b/src/chemistry/aerosol/aerosol_properties_mod.F90 index b2bc986fba..9a27c85913 100644 --- a/src/chemistry/aerosol/aerosol_properties_mod.F90 +++ b/src/chemistry/aerosol/aerosol_properties_mod.F90 @@ -307,13 +307,13 @@ end function aero_icenuc_updates_mmr !------------------------------------------------------------------------------ ! apply max / min to number concentration !------------------------------------------------------------------------------ - subroutine aero_apply_num_limits( self, naerosol, vaerosol, istart, istop, m ) + subroutine aero_apply_num_limits( self, naerosol, vaerosol, ncol, nlev, m ) import :: aerosol_properties, r8 class(aerosol_properties), intent(in) :: self - real(r8), intent(inout) :: naerosol(:) ! number conc (1/m3) - real(r8), intent(in) :: vaerosol(:) ! volume conc (m3/m3) - integer, intent(in) :: istart ! start column index (1 <= istart <= istop <= pcols) - integer, intent(in) :: istop ! stop column index + real(r8), intent(inout) :: naerosol(:,:) ! number conc (1/m3) + real(r8), intent(in) :: vaerosol(:,:) ! volume conc (m3/m3) + integer, intent(in) :: ncol ! number of columns + integer, intent(in) :: nlev ! number of vert levels integer, intent(in) :: m ! mode or bin index end subroutine aero_apply_num_limits diff --git a/src/chemistry/aerosol/aerosol_state_mod.F90 b/src/chemistry/aerosol/aerosol_state_mod.F90 index d56bade22d..e33eb6d278 100644 --- a/src/chemistry/aerosol/aerosol_state_mod.F90 +++ b/src/chemistry/aerosol/aerosol_state_mod.F90 @@ -301,7 +301,7 @@ end function aero_wet_diam !------------------------------------------------------------------------------ ! returns aerosol number, volume concentrations, and bulk hygroscopicity !------------------------------------------------------------------------------ - subroutine loadaer( self, aero_props, istart, istop, k, m, cs, phase, & + subroutine loadaer( self, aero_props, ncol, nlev, m, cs, phase, & naerosol, vaerosol, hygro, errnum, errstr, pom_hygro) use aerosol_properties_mod, only: aerosol_properties @@ -310,17 +310,15 @@ subroutine loadaer( self, aero_props, istart, istop, k, m, cs, phase, & class(aerosol_state), intent(in) :: self class(aerosol_properties), intent(in) :: aero_props - integer, intent(in) :: istart ! start column index (1 <= istart <= istop <= pcols) - integer, intent(in) :: istop ! stop column index - integer, intent(in) :: k ! level index + integer, intent(in) :: ncol, nlev integer, intent(in) :: m ! mode or bin index real(r8), intent(in) :: cs(:,:) ! air density (kg/m3) integer, intent(in) :: phase ! phase of aerosol: 1 for interstitial, 2 for cloud-borne, 3 for sum ! output arguments - real(r8), intent(out) :: naerosol(:) ! number conc (1/m3) - real(r8), intent(out) :: vaerosol(:) ! volume conc (m3/m3) - real(r8), intent(out) :: hygro(:) ! bulk hygroscopicity of mode + real(r8), intent(out) :: naerosol(:,:) ! number conc (1/m3) + real(r8), intent(out) :: vaerosol(:,:) ! volume conc (m3/m3) + real(r8), intent(out) :: hygro(:,:) ! bulk hygroscopicity of mode integer , intent(out) :: errnum character(len=*), intent(out) :: errstr @@ -333,15 +331,13 @@ subroutine loadaer( self, aero_props, istart, istop, k, m, cs, phase, & real(r8) :: specdens, spechygro character(len=aero_name_len) :: spectype - real(r8) :: vol(istart:istop) ! aerosol volume mixing ratio - integer :: i, l + real(r8) :: vol(ncol,nlev) ! aerosol volume mixing ratio + integer :: i, k, l !------------------------------------------------------------------------------- errnum = 0 - do i = istart, istop - vaerosol(i) = 0._r8 - hygro(i) = 0._r8 - end do + vaerosol(:,:) = 0._r8 + hygro(:,:) = 0._r8 do l = 1, aero_props%nspecies(m) @@ -355,59 +351,42 @@ subroutine loadaer( self, aero_props, istart, istop, k, m, cs, phase, & endif if (phase == 3) then - do i = istart, istop - vol(i) = max(raer(i,k) + qqcw(i,k), 0._r8)/specdens - end do + vol(:ncol,:) = max(raer(:ncol,:) + qqcw(:ncol,:), 0._r8)/specdens else if (phase == 2) then - do i = istart, istop - vol(i) = max(qqcw(i,k), 0._r8)/specdens - end do + vol(:ncol,:) = max(qqcw(:ncol,:), 0._r8)/specdens else if (phase == 1) then - do i = istart, istop - vol(i) = max(raer(i,k), 0._r8)/specdens - end do + vol(:ncol,:) = max(raer(:ncol,:), 0._r8)/specdens else errnum = -1 write(errstr,*)'phase = ',phase,' in aerosol_state::loadaer not recognized' return end if - do i = istart, istop - vaerosol(i) = vaerosol(i) + vol(i) - hygro(i) = hygro(i) + vol(i)*spechygro - end do - + vaerosol(:ncol,:) = vaerosol(:ncol,:) + vol(:ncol,:) + hygro(:ncol,:) = hygro(:ncol,:) + vol(:ncol,:)*spechygro end do - do i = istart, istop - if (vaerosol(i) > 1.0e-30_r8) then - hygro(i) = hygro(i)/(vaerosol(i)) - vaerosol(i) = vaerosol(i)*cs(i,k) - else - hygro(i) = 0.0_r8 - vaerosol(i) = 0.0_r8 - end if - end do + where(vaerosol(:ncol,:) > 1.0e-30_r8) + hygro(:ncol,:) = hygro(:ncol,:)/(vaerosol(:ncol,:)) + vaerosol(:ncol,:) = vaerosol(:ncol,:)*cs(:ncol,:) + elsewhere + hygro(:ncol,:) = 0._r8 + vaerosol(:ncol,:) = 0._r8 + end where ! aerosol number mixing ratios (#/kg) call self%get_ambient_num(m, raer) call self%get_cldbrne_num(m, qqcw) if (phase == 3) then - do i = istart, istop - naerosol(i) = (raer(i,k) + qqcw(i,k))*cs(i,k) ! #/kg -> #/m3 - end do + naerosol(:ncol,:) = (raer(:ncol,:) + qqcw(:ncol,:))*cs(:ncol,:) ! #/kg -> #/m3 else if (phase == 2) then - do i = istart, istop - naerosol(i) = qqcw(i,k)*cs(i,k) - end do + naerosol(:ncol,:) = qqcw(:ncol,:)*cs(:ncol,:) else - do i = istart, istop - naerosol(i) = raer(i,k)*cs(i,k) - end do + naerosol(:ncol,:) = raer(:ncol,:)*cs(:ncol,:) end if ! adjust number - call aero_props%apply_number_limits( naerosol, vaerosol, istart, istop, m ) + call aero_props%apply_number_limits( naerosol, vaerosol, ncol, nlev, m ) end subroutine loadaer diff --git a/src/chemistry/aerosol/bulk_aerosol_properties_mod.F90 b/src/chemistry/aerosol/bulk_aerosol_properties_mod.F90 index 3033851289..0fbff764cb 100644 --- a/src/chemistry/aerosol/bulk_aerosol_properties_mod.F90 +++ b/src/chemistry/aerosol/bulk_aerosol_properties_mod.F90 @@ -522,12 +522,12 @@ end function icenuc_updates_mmr !------------------------------------------------------------------------------ ! apply max / min to number concentration !------------------------------------------------------------------------------ - subroutine apply_number_limits( self, naerosol, vaerosol, istart, istop, m ) + subroutine apply_number_limits( self, naerosol, vaerosol, ncol, nlev, m ) class(bulk_aerosol_properties), intent(in) :: self - real(r8), intent(inout) :: naerosol(:) ! number conc (1/m3) - real(r8), intent(in) :: vaerosol(:) ! volume conc (m3/m3) - integer, intent(in) :: istart ! start column index (1 <= istart <= istop <= pcols) - integer, intent(in) :: istop ! stop column index + real(r8), intent(inout) :: naerosol(:,:) ! number conc (1/m3) + real(r8), intent(in) :: vaerosol(:,:) ! volume conc (m3/m3) + integer, intent(in) :: ncol ! number of columns + integer, intent(in) :: nlev ! number of vert levels integer, intent(in) :: m ! mode or bin index call endrun('ERROR: bulk_aerosol_properties_mod%apply_number_limits not yet implemented') diff --git a/src/chemistry/aerosol/carma_aerosol_properties_mod.F90 b/src/chemistry/aerosol/carma_aerosol_properties_mod.F90 index e00c807257..39df98e97e 100644 --- a/src/chemistry/aerosol/carma_aerosol_properties_mod.F90 +++ b/src/chemistry/aerosol/carma_aerosol_properties_mod.F90 @@ -644,12 +644,12 @@ end function icenuc_updates_mmr !------------------------------------------------------------------------------ ! apply max / min to number concentration !------------------------------------------------------------------------------ - subroutine apply_number_limits( self, naerosol, vaerosol, istart, istop, m ) + subroutine apply_number_limits( self, naerosol, vaerosol, ncol, nlev, m ) class(carma_aerosol_properties), intent(in) :: self - real(r8), intent(inout) :: naerosol(:) ! number conc (1/m3) - real(r8), intent(in) :: vaerosol(:) ! volume conc (m3/m3) - integer, intent(in) :: istart ! start column index (1 <= istart <= istop <= pcols) - integer, intent(in) :: istop ! stop column index + real(r8), intent(inout) :: naerosol(:,:) ! number conc (1/m3) + real(r8), intent(in) :: vaerosol(:,:) ! volume conc (m3/m3) + integer, intent(in) :: ncol ! number of columns + integer, intent(in) :: nlev ! number of vert levels integer, intent(in) :: m ! mode or bin index end subroutine apply_number_limits diff --git a/src/chemistry/aerosol/modal_aerosol_properties_mod.F90 b/src/chemistry/aerosol/modal_aerosol_properties_mod.F90 index e255be91da..3d100d717c 100644 --- a/src/chemistry/aerosol/modal_aerosol_properties_mod.F90 +++ b/src/chemistry/aerosol/modal_aerosol_properties_mod.F90 @@ -743,22 +743,24 @@ end function icenuc_updates_mmr !------------------------------------------------------------------------------ ! apply max / min to number concentration !------------------------------------------------------------------------------ - subroutine apply_number_limits( self, naerosol, vaerosol, istart, istop, m ) + subroutine apply_number_limits( self, naerosol, vaerosol, ncol, nlev, m ) class(modal_aerosol_properties), intent(in) :: self - real(r8), intent(inout) :: naerosol(:) ! number conc (1/m3) - real(r8), intent(in) :: vaerosol(:) ! volume conc (m3/m3) - integer, intent(in) :: istart ! start column index (1 <= istart <= istop <= pcols) - integer, intent(in) :: istop ! stop column index + real(r8), intent(inout) :: naerosol(:,:) ! number conc (1/m3) + real(r8), intent(in) :: vaerosol(:,:) ! volume conc (m3/m3) + integer, intent(in) :: ncol ! number of columns + integer, intent(in) :: nlev ! number of vert levels integer, intent(in) :: m ! mode or bin index - integer :: i + integer :: i,k ! adjust number so that dgnumlo < dgnum < dgnumhi ! -- the diameter falls within the lower and upper limits which are ! represented by voltonumhi and voltonumblo values, respectively - do i = istart, istop - naerosol(i) = max(naerosol(i), vaerosol(i)*self%voltonumbhi_(m)) - naerosol(i) = min(naerosol(i), vaerosol(i)*self%voltonumblo_(m)) + do k = 1,nlev + do i = 1,ncol + naerosol(i,k) = max(naerosol(i,k), vaerosol(i,k)*self%voltonumbhi_(m)) + naerosol(i,k) = min(naerosol(i,k), vaerosol(i,k)*self%voltonumblo_(m)) + end do end do end subroutine apply_number_limits diff --git a/src/physics/cam/ndrop.F90 b/src/physics/cam/ndrop.F90 index 3a2bed88c3..3d46923c17 100644 --- a/src/physics/cam/ndrop.F90 +++ b/src/physics/cam/ndrop.F90 @@ -68,6 +68,8 @@ module ndrop logical :: lq(pcnst) = .false. ! set flags true for constituents with non-zero tendencies ! in the ptend object +integer :: nbin ! number of bins + !=============================================================================== contains !=============================================================================== @@ -93,6 +95,8 @@ subroutine ndrop_init(aero_props) aten = 2._r8*mwh2o*surften/(r_universal*tmelt*rhoh2o) + nbin = aero_props%nbins() + allocate( & aer_cnst_idx(aero_props%nbins(),0:maxval(aero_props%nmasses())), & fieldname(aero_props%ncnst_tot()), & @@ -203,7 +207,6 @@ subroutine dropmixnuc( aero_props, aero_state, & integer :: lchnk ! chunk identifier integer :: ncol ! number of columns - integer :: nbin ! number of modes/bins integer :: nele_tot ! total number of aerosol elements real(r8), pointer :: ncldwtr(:,:) ! droplet number concentration (#/kg) @@ -281,7 +284,7 @@ subroutine dropmixnuc( aero_props, aero_state, & real(r8), allocatable :: raercol_cw(:,:,:) ! same as raercol but for cloud-borne phase - real(r8) :: na(pcols), va(pcols), hy(pcols) + real(r8) :: na(pcols,pver,nbin), va(pcols,pver,nbin), hy(pcols,pver,nbin) real(r8), allocatable :: naermod(:) ! (1/m3) real(r8), allocatable :: hygro(:) ! hygroscopicity of aerosol mode real(r8), allocatable :: vaerosol(:) ! interstit+activated aerosol volume conc (cm3/cm3) @@ -316,7 +319,6 @@ subroutine dropmixnuc( aero_props, aero_state, & lchnk = state%lchnk ncol = state%ncol - nbin = aero_props%nbins() nele_tot = aero_props%ncnst_tot() ncldwtr => state%q(:,:,numliq_idx) @@ -382,6 +384,20 @@ subroutine dropmixnuc( aero_props, aero_state, & ! initialize aerosol tendencies call physics_ptend_init(ptend, state%psetcols, 'ndrop', lq=lq) + ! air density (kg/m3) + cs(:ncol,:) = pmid(:ncol,:)/(rair*temp(:ncol,:)) + + phase = 1 ! interstitial + do m = 1, nbin + call aero_state%loadaer( aero_props, & + ncol, pver, & + m, cs, phase, na(:,:,m), va(:,:,m), & + hy(:,:,m), errnum, errstr) + if (errnum/=0) then + call endrun('dropmixnuc : '//trim(errstr)) + end if + end do + ! overall_main_i_loop do i = 1, ncol @@ -397,7 +413,6 @@ subroutine dropmixnuc( aero_props, aero_state, & qcld(k) = ncldwtr(i,k) qncld(k) = 0._r8 srcn(k) = 0._r8 - cs(i,k) = pmid(i,k)/(rair*temp(i,k)) ! air density (kg/m3) dz(i,k) = 1._r8/(cs(i,k)*gravit*rpdel(i,k)) ! layer thickness in m do m = 1, nbin @@ -520,18 +535,10 @@ subroutine dropmixnuc( aero_props, aero_state, & ! load aerosol properties, assuming external mixtures - phase = 1 ! interstitial do m = 1, nbin - call aero_state%loadaer( aero_props, & - i, i, k, & - m, cs, phase, na, va, & - hy, errnum, errstr) - if (errnum/=0) then - call endrun('dropmixnuc : '//trim(errstr)) - end if - naermod(m) = na(i) - vaerosol(m) = va(i) - hygro(m) = hy(i) + naermod(m) = na(i,k,m) + vaerosol(m) = va(i,k,m) + hygro(m) = hy(i,k,m) end do call activate_aerosol( & @@ -608,21 +615,13 @@ subroutine dropmixnuc( aero_props, aero_state, & alogarg = max(1.e-20_r8, 1._r8/lcldn(i,k) - 1._r8) wmin = wbar + wmix*0.25_r8*sq2pi*log(alogarg) - phase = 1 ! interstitial do m = 1, nbin ! rce-comment - use kp1 here as old-cloud activation involves ! aerosol from layer below - call aero_state%loadaer( aero_props, & - i, i, kp1, & - m, cs, phase, na, va, & - hy, errnum, errstr) - if (errnum/=0) then - call endrun('dropmixnuc : '//trim(errstr)) - end if - naermod(m) = na(i) - vaerosol(m) = va(i) - hygro(m) = hy(i) + naermod(m) = na(i,kp1,m) + vaerosol(m) = va(i,kp1,m) + hygro(m) = hy(i,kp1,m) end do call activate_aerosol( & @@ -1461,17 +1460,16 @@ subroutine ccncalc(aero_state, aero_props, state, cs, ccn) ! local integer :: ncol ! number of columns - integer :: nbin ! number of bins real(r8), pointer :: tair(:,:) ! air temperature (K) - real(r8) naerosol(pcols) ! interstit+activated aerosol number conc (/m3) - real(r8) vaerosol(pcols) ! interstit+activated aerosol volume conc (m3/m3) + real(r8) naerosol(pcols,pver,nbin) ! interstit+activated aerosol number conc (/m3) + real(r8) vaerosol(pcols,pver,nbin) ! interstit+activated aerosol volume conc (m3/m3) real(r8) amcube(pcols) real(r8), allocatable :: argfactor(:) real(r8) surften_coef real(r8) a(pcols) ! surface tension parameter - real(r8) hygro(pcols) ! aerosol hygroscopicity + real(r8) hygro(pcols,pver,nbin) ! aerosol hygroscopicity real(r8) sm(pcols) ! critical supersaturation at mode radius real(r8) arg(pcols) integer l,m,i,k, astat @@ -1487,7 +1485,6 @@ subroutine ccncalc(aero_state, aero_props, state, cs, ccn) !------------------------------------------------------------------------------- - nbin = aero_props%nbins() ncol = state%ncol tair => state%t @@ -1502,6 +1499,18 @@ subroutine ccncalc(aero_state, aero_props, state, cs, ccn) argfactor(m)=twothird/(sq2*aero_props%alogsig(m)) end do + phase=3 ! interstitial+cloudborne + + do m = 1, nbin + call aero_state%loadaer( aero_props, & + ncol, pver, & + m, cs, phase, naerosol(:,:,m), vaerosol(:,:,m), & + hygro(:,:,m), errnum, errstr) + if (errnum/=0) then + call endrun('ccncalc : '//trim(errstr)) + end if + end do + ccn = 0._r8 do k=top_lev,pver @@ -1512,26 +1521,16 @@ subroutine ccncalc(aero_state, aero_props, state, cs, ccn) do m=1,nbin - phase=3 ! interstitial+cloudborne - - call aero_state%loadaer( aero_props, & - 1, ncol, k, & - m, cs, phase, naerosol, vaerosol, & - hygro, errnum, errstr) - if (errnum/=0) then - call endrun('ccncalc : '//trim(errstr)) - end if - - where(naerosol(:ncol)>1.e-3_r8 .and. hygro(:ncol)>1.e-10_r8) - amcube(:ncol)=aero_props%amcube(m, vaerosol(:ncol), naerosol(:ncol) ) - sm(:ncol)=smcoef(:ncol)/sqrt(hygro(:ncol)*amcube(:ncol)) ! critical supersaturation + where(naerosol(:ncol,k,m)>1.e-3_r8 .and. hygro(:ncol,k,m)>1.e-10_r8) + amcube(:ncol)=aero_props%amcube(m, vaerosol(:ncol,k,m), naerosol(:ncol,k,m) ) + sm(:ncol)=smcoef(:ncol)/sqrt(hygro(:ncol,k,m)*amcube(:ncol)) ! critical supersaturation elsewhere sm(:ncol)=1._r8 ! value shouldn't matter much since naerosol is small endwhere do l=1,psat do i=1,ncol arg(i)=argfactor(m)*log(sm(i)/super(l)) - ccn(i,k,l)=ccn(i,k,l)+naerosol(i)*0.5_r8*(1._r8-erf(arg(i))) + ccn(i,k,l)=ccn(i,k,l)+naerosol(i,k,m)*0.5_r8*(1._r8-erf(arg(i))) enddo enddo enddo diff --git a/src/physics/cam/physpkg.F90 b/src/physics/cam/physpkg.F90 index ad0837ea9b..0c7bf8ad5d 100644 --- a/src/physics/cam/physpkg.F90 +++ b/src/physics/cam/physpkg.F90 @@ -298,10 +298,6 @@ subroutine phys_register ! register various data model gasses with pbuf call ghg_data_register() - ! carma microphysics - ! - call carma_register() - ! Register iondrag variables with pbuf call iondrag_register() @@ -323,6 +319,10 @@ subroutine phys_register call cloud_diagnostics_register call radheat_register + ! carma microphysics + ! + call carma_register() + ! COSP call cospsimulator_intr_register diff --git a/src/physics/cam7/physpkg.F90 b/src/physics/cam7/physpkg.F90 index a3f0c49fe6..853beaede6 100644 --- a/src/physics/cam7/physpkg.F90 +++ b/src/physics/cam7/physpkg.F90 @@ -288,10 +288,6 @@ subroutine phys_register ! register various data model gasses with pbuf call ghg_data_register() - ! carma microphysics - ! - call carma_register() - ! Register iondrag variables with pbuf call iondrag_register() @@ -313,6 +309,10 @@ subroutine phys_register call cloud_diagnostics_register call radheat_register + ! carma microphysics + ! + call carma_register() + ! COSP call cospsimulator_intr_register diff --git a/src/physics/carma/cam/carma_intr.F90 b/src/physics/carma/cam/carma_intr.F90 index 20aea54ce9..8a5e402767 100644 --- a/src/physics/carma/cam/carma_intr.F90 +++ b/src/physics/carma/cam/carma_intr.F90 @@ -465,8 +465,9 @@ subroutine carma_register ! NOTE: This only needs to be done once at the start of the run and does not need ! to be done for restarts. ! - ! NOTE: We only want to do this with RRTMG. If CAM_RT is being used, then skip this. - if ((masterproc) .and. (initial_run) .and. (radiation_scheme == "rrtmg") .and. (carma_do_optics)) then + ! NOTE: We only want to do this with RRTMG(P). If CAM_RT is being used, then skip this. + if ((masterproc) .and. (initial_run) .and. (radiation_scheme == "rrtmg".or.radiation_scheme == "rrtmgp") & + .and. (carma_do_optics)) then call CARMA_CreateOpticsFile(carma, rc) if (rc < 0) call endrun('carma_register::carma_CreateOpticsFiles failed.') end if @@ -3903,6 +3904,13 @@ subroutine carma_get_wet_radius(state, igroup, ibin, rwet, rhopwet, rc) call endrun('carma_get_wet_radius ERROR4: rc = ',rc) end if + if (irhswell == I_PETTERS) then + call carma_get_kappa(state, igroup, ibin, kappa, rc) + if (rc/=RC_OK) then + call endrun('carma_get_wet_radius carma_get_kappa ERROR: rc = ',rc) + end if + end if + do icol = 1, ncol do iz = 1, pver if (rdry(icol, iz)>0._r8) then @@ -3930,11 +3938,6 @@ subroutine carma_get_wet_radius(state, igroup, ibin, rwet, rhopwet, rc) else if (irhswell == I_PETTERS) then - call carma_get_kappa(state, igroup, ibin, kappa, rc) - if (rc/=RC_OK) then - call endrun('carma_get_wet_radius carma_get_kappa ERROR: rc = ',rc) - end if - call getwetr(carma, igroup, ibin, relhum, dryrad, rwet(icol, iz), dryden, rhopwet(icol,iz), rc, & h2o_mass=watcon, h2o_vp=wvpres, temp=state%t(icol,iz), kappa=kappa(icol,iz)) if (rc/=RC_OK) then diff --git a/src/physics/rrtmgp/radiation.F90 b/src/physics/rrtmgp/radiation.F90 index 664b279399..49b4fdc733 100644 --- a/src/physics/rrtmgp/radiation.F90 +++ b/src/physics/rrtmgp/radiation.F90 @@ -353,6 +353,22 @@ end subroutine radiation_readnl !================================================================================================ subroutine radiation_register + use rrtmgp_pre, only: rrtmgp_pre_init + use rrtmgp_inputs_setup, only: rrtmgp_inputs_setup_init + use rrtmgp_lw_gas_optics, only: rrtmgp_lw_gas_optics_init + use rrtmgp_sw_gas_optics, only: rrtmgp_sw_gas_optics_init + use radheat, only: p_top_for_equil_rad + ! local variables + character(len=512) :: errmsg + + ! names of gases that are available in the model + ! -- needed for the kdist initialization routines + type(ty_gas_concs_ccpp) :: available_gases + integer :: errflg + integer :: dtime + real(r8) :: dtime_r8 + character(len=*), parameter :: sub = 'radiation_register' + real(r8) :: qrl_unused(1,1) ! Register radiation fields in the physics buffer @@ -378,6 +394,36 @@ subroutine radiation_register ! Register fields for offline radiation driver. call rad_data_register() + ! Initialize available_gases object + call rrtmgp_pre_init(nradgas, available_gases, gaslist, gaslist_lc, errmsg, errflg) + if (errflg /= 0) then + call endrun(sub//': '//errmsg) + end if + + ! Read RRTMGP coefficients files and initialize kdist objects. + call rrtmgp_lw_gas_optics_init(coefs_lw_file, available_gases, kdist_lw, errmsg, errflg) + if (errflg /= 0) then + call endrun(sub//': lw '//errmsg) + end if + call rrtmgp_sw_gas_optics_init(coefs_sw_file, available_gases, kdist_sw, errmsg, errflg) + if (errflg /= 0) then + call endrun(sub//': sw '//errmsg) + end if + + dtime = get_step_size() + dtime_r8 = real(dtime, r8) + + ! Set up inputs to RRTMGP + call rrtmgp_inputs_setup_init(nswbands, nlwbands, pref_edge, pver, pverp, kdist_sw, kdist_lw, qrl_unused, & + is_first_step(), use_rad_dt_cosz, dtime_r8, get_nstep(), iradsw, dt_avg, irad_always, & + is_first_restart_step(), p_top_for_equil_rad, nradgas, gasnamelength, get_curr_calday(), & + ktopcam, ktoprad, nlaycam, sw_low_bounds, sw_high_bounds, idx_sw_diag, idx_nir_diag, & + idx_uv_diag, idx_sw_cloudsim, idx_lw_diag, idx_lw_cloudsim, nswgpts, nlwgpts, changeseed, & + nlay, nlayp, nextsw_cday, band2gpt_sw, irad_always_modified, errmsg, errflg) + if (errflg /= 0) then + call endrun(sub//': '//errmsg) + end if + end subroutine radiation_register !================================================================================================ @@ -411,16 +457,10 @@ end function radiation_do !================================================================================================ subroutine radiation_init(pbuf2d) - use rrtmgp_pre, only: rrtmgp_pre_init - use rrtmgp_inputs_setup, only: rrtmgp_inputs_setup_init use rrtmgp_cloud_optics_setup, only: rrtmgp_cloud_optics_setup_init use rrtmgp_sw_solar_var_setup, only: rrtmgp_sw_solar_var_setup_init use solar_irrad_data, only: do_spctrl_scaling, has_spectrum use cloud_rad_props, only: cloud_rad_props_init - use rad_constituents, only: iceopticsfile, liqopticsfile - use rrtmgp_lw_gas_optics, only: rrtmgp_lw_gas_optics_init - use rrtmgp_sw_gas_optics, only: rrtmgp_sw_gas_optics_init - use radheat, only: p_top_for_equil_rad ! Initialize the radiation and cloud optics. ! Add fields to the history buffer. @@ -431,14 +471,7 @@ subroutine radiation_init(pbuf2d) ! local variables character(len=512) :: errmsg - ! names of gases that are available in the model - ! -- needed for the kdist initialization routines - type(ty_gas_concs_ccpp) :: available_gases - - real(r8) :: qrl_unused(1,1) - integer :: i, icall - integer :: nstep ! current timestep number logical :: history_amwg ! output the variables used by the AMWG diag package logical :: history_vdiag ! output the variables used by the AMWG variability diag package logical :: history_budget ! output tendencies and state variables for CAM4 @@ -447,42 +480,9 @@ subroutine radiation_init(pbuf2d) integer :: history_budget_histfile_num ! history file number for budget fields integer :: ierr, istat, errflg - integer :: dtime - real(r8) :: dtime_r8 - character(len=*), parameter :: sub = 'radiation_init' !----------------------------------------------------------------------- - ! Initialize available_gases object - call rrtmgp_pre_init(nradgas, available_gases, gaslist, gaslist_lc, errmsg, errflg) - if (errflg /= 0) then - call endrun(sub//': '//errmsg) - end if - - ! Read RRTMGP coefficients files and initialize kdist objects. - call rrtmgp_lw_gas_optics_init(coefs_lw_file, available_gases, kdist_lw, errmsg, errflg) - if (errflg /= 0) then - call endrun(sub//': lw '//errmsg) - end if - call rrtmgp_sw_gas_optics_init(coefs_sw_file, available_gases, kdist_sw, errmsg, errflg) - if (errflg /= 0) then - call endrun(sub//': sw '//errmsg) - end if - - dtime = get_step_size() - dtime_r8 = real(dtime, r8) - - ! Set up inputs to RRTMGP - call rrtmgp_inputs_setup_init(nswbands, nlwbands, pref_edge, pver, pverp, kdist_sw, kdist_lw, qrl_unused, & - is_first_step(), use_rad_dt_cosz, dtime_r8, get_nstep(), iradsw, dt_avg, irad_always, & - is_first_restart_step(), p_top_for_equil_rad, nradgas, gasnamelength, get_curr_calday(), & - ktopcam, ktoprad, nlaycam, sw_low_bounds, sw_high_bounds, idx_sw_diag, idx_nir_diag, & - idx_uv_diag, idx_sw_cloudsim, idx_lw_diag, idx_lw_cloudsim, nswgpts, nlwgpts, changeseed, & - nlay, nlayp, nextsw_cday, band2gpt_sw, irad_always_modified, errmsg, errflg) - if (errflg /= 0) then - call endrun(sub//': '//errmsg) - end if - ! Set radconstants module-level index variables that we're setting in CCPP-ized scheme now call radconstants_init(idx_sw_diag, idx_nir_diag, idx_uv_diag, idx_lw_diag)