module aerosol_intr 5,9 !--------------------------------------------------------------------------------- ! Module to interface the aerosol parameterizations with CAM ! Phil Rasch, Jan 2003 !--------------------------------------------------------------------------------- use shr_kind_mod, only: r8 => shr_kind_r8, cl => shr_kind_cl use spmd_utils, only: masterproc use camsrfexch_types, only: srfflx_state, surface_state use ppgrid, only: pcols, pver, pverp use physconst, only: mwdry, mwh2o, gravit use phys_control, only: cam_physpkg_is use constituents, only: pcnst, cnst_name use abortutils, only: endrun use perf_mod use cam_logfile, only: iulog implicit none private save ! Public interfaces public ::& aerosol_readnl, & ! read aerosol_nl namelist group aerosol_register_cnst, & ! register consituents aerosol_implements_cnst, & ! returns true if consituent is implemented by this package aerosol_init_cnst, & ! initialize mixing ratios if not read from initial file prognostic_aerosol_initialize, & ! initialize (history) variables aerosol_drydep_intr, & ! interface to dry deposition aerosol_wet_intr, & ! interface to wet deposition aerosol_emis_intr ! interface to surface emissions ! Set this flag to .TRUE. to turn on prognostic sea salt logical, parameter :: def_progsslt = .FALSE. ! default logical :: progsslt = def_progsslt ! dust ! Set this flag to .TRUE. to turn on dust logical, parameter :: def_dust = .FALSE. ! default logical :: dust = def_dust ! It is useful to know if any of the aerosols are running ! (for instance, to initialize dry deposition module logical :: is_any_aerosol = .false. ! Namelist variables real(r8) :: dust_emis_fact = -1.e36 ! tuning parameter for dust emissions character(cl) :: soil_erod = 'soil_erod' ! full pathname for soil erodibility dataset !=============================================================================== contains !=============================================================================== subroutine aerosol_readnl(nlfile),9 use namelist_utils, only: find_group_name use units, only: getunit, freeunit use mpishorthand character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input ! Local variables integer :: unitn, ierr character(len=*), parameter :: subname = 'aerosol_readnl' namelist /aerosol_nl/ dust_emis_fact, soil_erod !----------------------------------------------------------------------------- ! Read namelist if (masterproc) then unitn = getunit() open( unitn, file=trim(nlfile), status='old' ) call find_group_name(unitn, 'aerosol_nl', status=ierr) if (ierr == 0) then read(unitn, aerosol_nl, iostat=ierr) if (ierr /= 0) then call endrun(subname // ':: ERROR reading namelist') end if end if close(unitn) call freeunit(unitn) end if #ifdef SPMD ! Broadcast namelist variables call mpibcast(dust_emis_fact, 1, mpir8, 0, mpicom) call mpibcast(soil_erod, len(soil_erod), mpichar, 0, mpicom) #endif end subroutine aerosol_readnl !=============================================================================== subroutine aerosol_register_cnst 1,13 !----------------------------------------------------------------------- ! ! Purpose: register aerosols ! ! Method: ! Author: P. J. Rasch ! !----------------------------------------------------------------------- use dust_intr, only: dust_register_cnst use dust_intr, only: ndst=>dust_number, dust_names use progseasalts_intr,only: progseasalts_register_cnst use progseasalts_intr,only: nsst, progseasalts_names use phys_buffer, only: pbuf_times, pbuf_add use camsrfexch_types, only: hub2atm_setopts #if ( defined MODAL_AERO ) use modal_aero_data, only: maxd_amode #endif #if ( defined TROPCHEM ) use mo_chem_utls, only: get_spc_ndx #endif implicit none !---------------------------Local workspace----------------------------- integer :: m ! tracer index integer idx ! pbuf idx integer :: dst_idx(ndst), slt_idx(nsst) !----------------------------------------------------------------------- #if ( defined TROPCHEM ) do m=1,ndst dst_idx(m) = get_spc_ndx( dust_names(m) ) enddo do m=1,nsst slt_idx(m) = get_spc_ndx( progseasalts_names(m) ) enddo dust = all( dst_idx > 0 ) progsslt = all( slt_idx > 0 ) #else dust = .false. progsslt = .false. #endif if ( dust ) then is_any_aerosol = .true. endif if ( progsslt ) then is_any_aerosol = .true. endif if ( dust .or. progsslt ) then ! tell camsrfexch_types to allocate fv & ram1 -- needed by prodsslts and dust call hub2atm_setopts(aero_dust_in=.true.) endif #if ( defined MODAL_AERO ) is_any_aerosol = .true. call hub2atm_setopts(aero_dust_in=.true.) !++ ceh: scope of 'DGNUM' is set to 'physpkg'. ! shouldn't the scope of DGNUM set to 'global' instead of 'physpkg' ? !call pbuf_add( 'DGNUM', 'physpkg', 1, pver, maxd_amode, idx ) call pbuf_add( 'DGNUM', 'global', 1, pver, maxd_amode, idx ) !-- ceh call pbuf_add( 'DGNUMWET', 'global', 1, pver, maxd_amode, idx ) call pbuf_add( 'WETDENS_AP', 'physpkg', 1, pver, maxd_amode, idx ) call pbuf_add( 'QAERWAT', 'physpkg', 1, pver, maxd_amode, idx ) #endif ! Request physics buffer space for fields that don't persist across timesteps. call pbuf_add('FRACIS' , 'physpkg', 1,pver, pcnst, idx) return end subroutine aerosol_register_cnst !======================================================================= function aerosol_implements_cnst(name) 1,2 !----------------------------------------------------------------------- ! ! Purpose: return true if specified constituent is implemented by this ! package ! ! Author: T. Henderson ! !----------------------------------------------------------------------- use dust_intr, only: dust_implements_cnst use progseasalts_intr, only: progseasalts_implements_cnst implicit none !-----------------------------Arguments--------------------------------- character(len=*), intent(in) :: name ! constituent name logical :: aerosol_implements_cnst ! return value !---------------------------Local workspace----------------------------- integer :: m !----------------------------------------------------------------------- aerosol_implements_cnst = .false. if ( dust ) then aerosol_implements_cnst = & (aerosol_implements_cnst.OR.dust_implements_cnst (name)) endif if ( progsslt ) then aerosol_implements_cnst = & (aerosol_implements_cnst.OR.progseasalts_implements_cnst (name)) endif end function aerosol_implements_cnst !======================================================================= subroutine aerosol_init_cnst(name, q, gcid) 1,7 !----------------------------------------------------------------------- ! ! Purpose: ! Set initial mass mixing ratios. ! !----------------------------------------------------------------------- use drydep_mod, only: inidrydep use dust_intr, only: dust_implements_cnst, dust_init_cnst use progseasalts_intr,only: progseasalts_implements_cnst, progseasalts_init_cnst implicit none !-----------------------------Arguments--------------------------------- character(len=*), intent(in) :: name ! constituent name real(r8), intent(out) :: q(:,:) ! mass mixing ratio integer, intent(in) :: gcid(:) ! global column id !----------------------------------------------------------------------- if ( dust ) then if (dust_implements_cnst(name)) then call dust_init_cnst(name, q, gcid) endif endif if ( progsslt ) then if (progseasalts_implements_cnst(name)) then call progseasalts_init_cnst(name, q, gcid) endif endif end subroutine aerosol_init_cnst !=============================================================================== subroutine prognostic_aerosol_initialize(phys_state) 1,10 !----------------------------------------------------------------------- ! ! Purpose: initialize aerosol parameterizations ! (declare history variables) ! ! Method: ! call subroutines ! ! Author: Phil Rasch ! !----------------------------------------------------------------------- use physics_types, only: physics_state use dust_intr, only: dust_initialize use progseasalts_intr, only: progseasalts_initialize use drydep_mod, only: inidrydep use physconst, only: rair implicit none type(physics_state), intent(in) :: phys_state(:) #if ( defined MODAL_AERO ) call dust_initialize(dust_emis_fact, soil_erod) call progseasalts_initialize #else if ( dust ) then call dust_initialize(dust_emis_fact, soil_erod) endif if ( progsslt ) then call progseasalts_initialize endif #endif ! Dry deposition needs to be initialized if any of the aerosols ! are running. if ( is_any_aerosol ) then call inidrydep (rair, gravit ) endif return end subroutine prognostic_aerosol_initialize !=============================================================================== subroutine aerosol_wet_intr (state, ptend, dt, pbuf, cam_out, dlf) 1,48 !----------------------------------------------------------------------- ! ! Purpose: ! Interface to wet processing of all aerosols ! ! Method: ! use a modified version of the scavenging parameterization described in ! Barth et al, 2000, JGR (sulfur cycle paper) ! Rasch et al, 2001, JGR (INDOEX paper) ! ! Author: Phil Rasch ! !----------------------------------------------------------------------- use cam_history, only: outfld use physics_types, only: physics_state, physics_ptend use phys_buffer, only: pbuf_size_max, pbuf_fld, pbuf_old_tim_idx, pbuf_get_fld_idx use phys_grid, only: get_lat_all_p, get_lon_all_p, get_rlat_all_p, get_rlon_all_p use dust_intr, only: dust_wet_intr use progseasalts_intr,only: progseasalts_wet_intr use wetdep, only: clddiag use time_manager, only: get_curr_date, get_perp_date, get_curr_calday use time_manager, only: is_perpetual, get_nstep use scyc, only: scyc_idx1 #if ( defined TROPCHEM || defined MODAL_AERO ) use mz_aerosols_intr, only: mz_aero_wet_intr #endif #if ( defined MODAL_AERO ) use modal_aero_calcsize, only: modal_aero_calcsize_sub use modal_aero_wateruptake, only: modal_aero_wateruptake_sub use modal_aero_data, only: maxd_amode #endif !----------------------------------------------------------------------- implicit none !----------------------------------------------------------------------- ! ! Arguments: ! ! real(r8), intent(in) :: dt ! time step type(physics_state), intent(in ) :: state ! Physics state variables type(physics_ptend), intent(inout) :: ptend ! indivdual parameterization tendencies type(pbuf_fld), intent(inout) :: pbuf(pbuf_size_max) type(surface_state), intent(inout) :: cam_out ! export state real(r8), intent(in) :: dlf(pcols,pver) ! shallow+deep convective detrainment [kg/kg/s] ! local vars real(r8) :: calday ! current calendar day integer :: yr, mon, day, ncsec integer :: ncdate real(r8):: rainmr(pcols,pver) ! mixing ratio of rain within cloud volume real(r8):: cldv(pcols,pver) ! cloudy volume undergoing wet chem and scavenging real(r8):: cldvcu(pcols,pver) ! Convective precipitation area at the top interface of current layer real(r8):: cldvst(pcols,pver) ! Stratiform precipitation area at the top interface of current layer integer ix integer m integer lat(pcols) ! latitude indices real(r8) clat(pcols) ! latitudes integer lon(pcols) ! longtitude indices real(r8) clon(pcols) ! longitudes integer nstep real(r8) conicw(pcols,pver) ! convective in-cloud water real(r8) cmfdqr(pcols,pver) ! convective production of rain real(r8) cldc(pcols,pver) ! convective cloud fraction, currently empty real(r8) clds(pcols,pver) ! Stratiform cloud fraction real(r8) evapc(pcols,pver) ! Evaporation rate of convective precipitation #if ( defined MODAL_AERO ) integer i, k #endif ! physics buffer integer itim, ifld real(r8), pointer, dimension(:,:) :: cldn ! cloud fraction real(r8), pointer, dimension(:,:) :: cme real(r8), pointer, dimension(:,:) :: prain real(r8), pointer, dimension(:,:) :: evapr real(r8), pointer, dimension(:,:) :: icwmrdp ! in cloud water mixing ratio, deep convection real(r8), pointer, dimension(:,:) :: rprddp ! rain production, deep convection real(r8), pointer, dimension(:,:) :: icwmrsh ! in cloud water mixing ratio, deep convection real(r8), pointer, dimension(:,:) :: rprdsh ! rain production, deep convection real(r8), pointer, dimension(:,:,:) :: fracis ! fraction of transported species that are insoluble ! Dec.29.2009. Sungsu real(r8), pointer, dimension(:,:) :: sh_frac ! Shallow convective cloud fraction real(r8), pointer, dimension(:,:) :: dp_frac ! Deep convective cloud fraction real(r8), pointer, dimension(:,:) :: evapcsh ! Evaporation rate of shallow convective precipitation >=0. real(r8), pointer, dimension(:,:) :: evapcdp ! Evaporation rate of deep convective precipitation >=0. ! Dec.29.2009. Sungsu #if ( defined MODAL_AERO ) real(r8), pointer, dimension(:,:,:) :: dgnum_pbuf, dgnumwet_pbuf, wetdens_pbuf real(r8), pointer, dimension(:,:,:) :: qqcw ! cloud-borne aerosol real(r8), pointer, dimension(:,:,:) :: qaerwat ! aerosol water real(r8), pointer, dimension(:,:) :: rate1ord_cw2pr_st ! 1st order rate for direct conversion of ! strat. cloud water to precip (1/s) ! rce 2010/05/01 #endif integer ncol,lchnk nstep = get_nstep() calday = get_curr_calday() if ( is_perpetual() ) then call get_perp_date(yr, mon, day, ncsec) else call get_curr_date(yr, mon, day, ncsec) end if ncdate = yr*10000 + mon*100 + day ncol = state%ncol lchnk = state%lchnk call get_lat_all_p(lchnk, ncol, lat) call get_lon_all_p(lchnk, ncol, lon) call get_rlat_all_p(lchnk, ncol, clat) call get_rlon_all_p(lchnk, ncol, clon) ! Associate pointers with physics buffer fields itim = pbuf_old_tim_idx() ifld = pbuf_get_fld_idx('CLD') cldn => pbuf(ifld)%fld_ptr(1,1:pcols,1:pver,lchnk,itim) ifld = pbuf_get_fld_idx('QME') cme => pbuf(ifld)%fld_ptr(1,1:pcols,1:pver,lchnk, 1) ifld = pbuf_get_fld_idx('PRAIN') prain => pbuf(ifld)%fld_ptr(1,1:pcols,1:pver,lchnk, 1) ifld = pbuf_get_fld_idx('NEVAPR') evapr => pbuf(ifld)%fld_ptr(1,1:pcols,1:pver,lchnk, 1) ifld = pbuf_get_fld_idx('FRACIS') fracis => pbuf(ifld)%fld_ptr(1,1:pcols,1:pver,lchnk,1:pcnst) ifld = pbuf_get_fld_idx('ICWMRDP') icwmrdp => pbuf(ifld)%fld_ptr(1,1:pcols,1:pver,lchnk, 1) ifld = pbuf_get_fld_idx('RPRDDP') rprddp => pbuf(ifld)%fld_ptr(1,1:pcols,1:pver,lchnk, 1) ifld = pbuf_get_fld_idx('ICWMRSH') icwmrsh => pbuf(ifld)%fld_ptr(1,1:pcols,1:pver,lchnk, 1) ifld = pbuf_get_fld_idx('RPRDSH') rprdsh => pbuf(ifld)%fld_ptr(1,1:pcols,1:pver,lchnk, 1) ! Dec.29.2009. Sungsu ifld = pbuf_get_fld_idx('SH_FRAC') sh_frac => pbuf(ifld)%fld_ptr(1,1:pcols,1:pver,lchnk,1) ifld = pbuf_get_fld_idx('DP_FRAC') dp_frac => pbuf(ifld)%fld_ptr(1,1:pcols,1:pver,lchnk,1) ifld = pbuf_get_fld_idx('NEVAPR_SHCU') evapcsh => pbuf(ifld)%fld_ptr(1,1:pcols,1:pver,lchnk, 1) ifld = pbuf_get_fld_idx('NEVAPR_DPCU') evapcdp => pbuf(ifld)%fld_ptr(1,1:pcols,1:pver,lchnk, 1) cldc(:ncol,:) = dp_frac(:ncol,:) + sh_frac(:ncol,:) ! Sungsu included this. evapc(:ncol,:) = evapcsh(:ncol,:) + evapcdp(:ncol,:) ! Sungsu included this. clds(:ncol,:) = cldn(:ncol,:) - cldc(:ncol,:) ! Stratiform cloud fraction ! sum deep and shallow convection contributions if (cam_physpkg_is('cam5')) then ! Dec.29.2009. Sungsu conicw(:ncol,:) = (icwmrdp(:ncol,:)*dp_frac(:ncol,:) + icwmrsh(:ncol,:)*sh_frac(:ncol,:))/ & max(0.01_r8, sh_frac(:ncol,:) + dp_frac(:ncol,:)) else conicw(:ncol,:) = icwmrdp(:ncol,:) + icwmrsh(:ncol,:) end if cmfdqr(:ncol,:) = rprddp(:ncol,:) + rprdsh(:ncol,:) ! fields needed for wet scavenging call clddiag( state%t, state%pmid, state%pdel, cmfdqr, evapc, cldn, cldc, clds, cme, evapr, prain, & cldv, cldvcu, cldvst, rainmr, ncol ) ptend%name = 'wetdep' #if ( defined MODAL_AERO ) m = pbuf_get_fld_idx( 'DGNUM' ) if ( associated(pbuf(m)%fld_ptr) ) then dgnum_pbuf => pbuf(m)%fld_ptr( 1, 1:pcols, 1:pver, lchnk, 1:maxd_amode ) else call endrun( 'pbuf for DGNUM not allocated in aerosol_wet_intr' ) end if m = pbuf_get_fld_idx( 'DGNUMWET' ) if ( associated(pbuf(m)%fld_ptr) ) then dgnumwet_pbuf => pbuf(m)%fld_ptr( 1, 1:pcols, 1:pver, lchnk, 1:maxd_amode ) else call endrun( 'pbuf for DGNUMWET not allocated in aerosol_wet_intr' ) end if m = pbuf_get_fld_idx( 'WETDENS_AP' ) if ( associated(pbuf(m)%fld_ptr) ) then wetdens_pbuf => pbuf(m)%fld_ptr( 1, 1:pcols, 1:pver, lchnk, 1:maxd_amode ) else call endrun( 'pbuf for WETDENS_AP not allocated in aerosol_wet_intr' ) end if m = pbuf_get_fld_idx( 'QQCW' ) if ( associated(pbuf(m)%fld_ptr) ) then qqcw => pbuf(m)%fld_ptr( 1, 1:pcols, 1:pver, lchnk, 1:pcnst ) else call endrun( 'pbuf for QQCW not allocated in aerosol_wet_intr' ) end if m = pbuf_get_fld_idx( 'QAERWAT' ) if ( associated(pbuf(m)%fld_ptr) ) then qaerwat => pbuf(m)%fld_ptr( 1, 1:pcols, 1:pver, lchnk, 1:maxd_amode ) else call endrun( 'pbuf for QAERWAT not allocated in aerosol_wet_intr' ) end if m = pbuf_get_fld_idx( 'RATE1_CW2PR_ST' ) ! rce 2010/05/01 rate1ord_cw2pr_st => pbuf(m)%fld_ptr( 1, 1:pcols, 1:pver, lchnk, 1 ) ! rce 2010/05/01 call t_startf('calcsize') call modal_aero_calcsize_sub( & lchnk, ncol, nstep, & 1, 0, & .true., dt, & state%t, state%pmid, & state%pdel, state%q, & ptend%q, ptend%lq, & qqcw, dgnum_pbuf ) call t_stopf('calcsize') call t_startf('wateruptake') call modal_aero_wateruptake_sub( & lchnk, ncol, nstep, & 1, 0, & .true., .true., & dt, state%q(:,:,1), & state%t, state%pmid, & state%pdel, cldn, state%q, & ptend%q, ptend%lq, & qaerwat, & dgnum_pbuf, dgnumwet_pbuf, & wetdens_pbuf ) call t_stopf('wateruptake') call mz_aero_wet_intr (state, ptend, nstep, dt, cme, prain, & evapr, cldv, cldvcu, cldvst, cldc, cldn, fracis, calday, cmfdqr, evapc, conicw, rainmr, & rate1ord_cw2pr_st, & ! rce 2010/05/01 dgnumwet_pbuf, qqcw, qaerwat, cam_out, dlf) ! do i = 1, ncol ! if ((lon(i)==37) .or. (lon(i)==67)) then ! if ((mod(lat(i),12)==0) .and. (lat(i)<40)) then ! do k = pver, 1, -(pver/2-1) ! write(*,'(a,4i5,1p,10(i4,2e10.2))') & ! 'DGNCUR.AA', nstep, lon(i), lat(i), k, & ! (m, dgnum_pbuf(i,k,m), dgnumwet_pbuf(i,k,m), m=1,2), & ! (m, dgnum_pbuf(i,k,m), dgnumwet_pbuf(i,k,m), m=6,7) ! write(*,'(a,4i5,10(1x,f7.3))') & ! 'WETDEN.AA', nstep, lon(i), lat(i), k, & ! (0.001*wetdens_pbuf(i,k,m), m=1,7) ! end do ! end if ! end if ! end do #else if ( dust ) then ! wet scavenging for dust call dust_wet_intr (state, ptend, nstep, dt, lat, clat, cme, prain, & evapr, cldv, cldc, cldn, fracis, calday, cmfdqr, conicw, rainmr, cam_out) endif if ( progsslt ) then ! wet scavenging for prognostic sea salts call progseasalts_wet_intr (state, ptend, nstep, dt, lat, clat, cme, prain, & evapr, cldv, cldc, cldn, fracis, calday, cmfdqr, conicw, rainmr) endif #if ( defined TROPCHEM ) ! wet scavenging for mozart aerosols ! can not be done under trop_mozart chem_timestep_tend -- ! this need to be done before deep convection so that fracis is set correctly ! for the mozart aerosols -- fracis is used in deep convection routine call mz_aero_wet_intr (state, ptend, nstep, dt, cme, prain, & evapr, cldv, cldvcu, cldvst, cldc, cldn, fracis, calday, cmfdqr, evapc, conicw, rainmr, cam_out, dlf) #endif #endif return end subroutine aerosol_wet_intr subroutine aerosol_drydep_intr (state, ptend, cam_in, cam_out, dt, & 1,23 fsds, obklen, ustar, prect, pblh, pbuf ) !----------------------------------------------------------------------- ! ! Purpose: ! Interface to dry deposition parameterizions and sedimentation of all aerosols ! ! Method: ! Use prescribed dry deposition velocities for sulfur and carbon ! Use calculated dry dep velocities from CLM for dust and prognostic seasalt ! ! Author: Phil Rasch ! !----------------------------------------------------------------------- use cam_history, only: outfld use physics_types, only: physics_state, physics_ptend use phys_grid, only: get_lat_all_p, get_rlat_all_p use dust_intr, only: dust_drydep_intr use progseasalts_intr, only: progseasalts_drydep_intr use time_manager, only: get_curr_date, get_perp_date, get_curr_calday, & is_perpetual use scyc, only: scyc_idx1 #if ( defined MODAL_AERO ) use modal_aero_data, only: maxd_amode use mz_aerosols_intr, only: mz_aero_dry_intr #endif use phys_buffer, only: pbuf_size_max, pbuf_fld, pbuf_get_fld_idx !----------------------------------------------------------------------- implicit none !----------------------------------------------------------------------- ! ! Arguments: ! real(r8), intent(in) :: dt ! time step type(physics_state), intent(in ) :: state ! Physics state variables type(srfflx_state), intent(in), target :: cam_in ! import state type(surface_state), intent(inout) :: cam_out ! export state real(r8), intent(in) :: fsds(pcols) ! longwave down at sfc real(r8), intent(in) :: obklen(pcols) ! longwave down at sfc real(r8), intent(in) :: ustar(pcols) ! sfc fric vel real(r8), intent(in) :: prect(pcols) ! prect real(r8), intent(in) :: pblh(pcols) ! pbl height type(physics_ptend), intent(inout) :: ptend ! indivdual parameterization tendencies type(pbuf_fld), intent(inout), dimension(pbuf_size_max) :: pbuf ! ! Local ! ! local names of the fields in cam_in real(r8), pointer, dimension(:) :: wvflx ! (pcols) water vapor flux real(r8), pointer, dimension(:) :: ts ! (pcols) sfc temp real(r8), pointer, dimension(:) :: snowh ! (pcols) snow depth real(r8), pointer, dimension(:) :: hflx ! (pcols) sensible heat flux real(r8), pointer, dimension(:) :: landfrac ! (pcols) land fraction real(r8), pointer, dimension(:) :: icefrac ! (pcols) ice fraction real(r8), pointer, dimension(:) :: ocnfrac ! (pcols) ocn fraction integer lat(pcols) ! latitude index for S->N storage real(r8) clat(pcols) ! latitude integer lchnk integer ncol integer ix integer m integer :: yr, mon, day, ncsec integer :: ncdate #if ( defined MODAL_AERO ) real(r8), pointer, dimension(:,:,:) :: dgnumwet_pbuf, wetdens_pbuf real(r8), pointer, dimension(:,:,:) :: qqcw ! cloud-borne aerosol real(r8), pointer, dimension(:,:,:) :: qaerwat ! aerosol water #endif lchnk = state%lchnk ncol = state%ncol wvflx => cam_in%cflx(:,1) ts => cam_in%tref(:) snowh => cam_in%snowhland(:) hflx => cam_in%shf(:) landfrac => cam_in%landfrac(:) icefrac => cam_in%icefrac(:) ocnfrac => cam_in%ocnfrac(:) if ( is_perpetual() ) then call get_perp_date(yr, mon, day, ncsec) else call get_curr_date(yr, mon, day, ncsec) end if call get_lat_all_p(lchnk, ncol, lat) call get_rlat_all_p(lchnk, ncol, clat) ! note that tendencies are not only in sfc layer (because of sedimentation) ! and that ptend is updated within each subroutine for different species ptend%name = 'drydep' #if ( defined MODAL_AERO ) m = pbuf_get_fld_idx( 'DGNUMWET' ) if ( associated(pbuf(m)%fld_ptr) ) then dgnumwet_pbuf => pbuf(m)%fld_ptr( 1, 1:pcols, 1:pver, lchnk, 1:maxd_amode ) else call endrun( 'pbuf for DGNUMWET not allocated in aerosol_drydep_intr' ) end if m = pbuf_get_fld_idx( 'WETDENS_AP' ) if ( associated(pbuf(m)%fld_ptr) ) then wetdens_pbuf => pbuf(m)%fld_ptr( 1, 1:pcols, 1:pver, lchnk, 1:maxd_amode ) else call endrun( 'pbuf for WETDENS_AP not allocated in aerosol_drydep_intr' ) end if m = pbuf_get_fld_idx( 'QQCW' ) if ( associated(pbuf(m)%fld_ptr) ) then qqcw => pbuf(m)%fld_ptr( 1, 1:pcols, 1:pver, lchnk, 1:pcnst ) else call endrun( 'pbuf for QQCW not allocated in aerosol_drydep_intr' ) end if m = pbuf_get_fld_idx( 'QAERWAT' ) if ( associated(pbuf(m)%fld_ptr) ) then qaerwat => pbuf(m)%fld_ptr( 1, 1:pcols, 1:pver, lchnk, 1:maxd_amode ) else call endrun( 'pbuf for QAERWAT not allocated in aerosol_drydep_intr' ) end if call mz_aero_dry_intr (state, ptend, wvflx, dt, lat, clat, & fsds, obklen, ts, ustar, prect, snowh, pblh, hflx, mon, & landfrac, icefrac, ocnfrac, cam_in%fv, cam_in%ram1, & dgnumwet_pbuf, wetdens_pbuf, qqcw, qaerwat, cam_out) #else if ( dust ) then call dust_drydep_intr (state, ptend, wvflx, dt, lat, clat, & fsds, obklen, ts, ustar, prect, snowh, pblh, hflx, mon, & landfrac, icefrac, ocnfrac, cam_in%fv, cam_in%ram1, cam_out) endif if ( progsslt ) then call progseasalts_drydep_intr (state, ptend, wvflx, dt, lat, clat, & fsds, obklen, ts, ustar, prect, snowh, pblh, hflx, mon, landfrac, & icefrac, ocnfrac, cam_in%fv, cam_in%ram1) endif #endif return end subroutine aerosol_drydep_intr #if ( defined MODAL_AERO ) subroutine aerosol_emis_intr (state, ptend, cflx, dt,ocnfrc,sst) 2,10 #else subroutine aerosol_emis_intr (state, ptend, cflx, dt,ocnfrc) 2,10 #endif !----------------------------------------------------------------------- ! ! Purpose: ! return surface fluxes of aerosol species and tendencies in surface layer ! due to surface emissions ! ! Method: ! ! Author: Phil Rasch ! !----------------------------------------------------------------------- use cam_history, only: outfld use physics_types, only: physics_state, physics_ptend use phys_grid, only: get_lon_all_p, get_lat_all_p, get_rlat_all_p use time_manager, only: get_curr_date, get_perp_date, get_curr_calday, & is_perpetual use dust_intr, only: dust_emis_intr use progseasalts_intr, only: progseasalts_emis_intr !----------------------------------------------------------------------- implicit none !----------------------------------------------------------------------- ! ! Arguments: ! real(r8), intent(in) :: dt ! time step type(physics_state), intent(in ) :: state ! Physics state variables real(r8), intent(in) :: ocnfrc(pcols) #if ( defined MODAL_AERO ) real(r8), intent(in) :: sst(pcols) ! Sea surface temperature #endif type(physics_ptend), intent(inout) :: ptend ! indivdual parameterization tendencies real(r8), intent(inout) :: cflx(pcols,pcnst) ! Surface constituent flux (kg/m^2/s) integer lat(pcols) ! latitude index integer lon(pcols) ! longitude index real(r8) clat(pcols) ! latitude integer lchnk integer ncol integer i integer m real(r8) astmp(pcols,pver,3) ! real(r8) :: calday ! current calendar day integer :: yr, mon, day, ncsec integer :: ncdate real(r8) :: so2sf(pcols), so4sf(pcols), dmssf(pcols) integer :: k ptend%name = 'aerosol_emis' #if ( defined MODAL_AERO ) call dust_emis_intr(state,ptend,dt,cflx) call progseasalts_emis_intr(state,ptend,dt,cflx,ocnfrc,sst) #else if ( dust ) then call dust_emis_intr(state,ptend,dt,cflx) endif if ( progsslt ) then call progseasalts_emis_intr(state,ptend,dt,cflx,ocnfrc) endif #endif return end subroutine aerosol_emis_intr end module aerosol_intr