module chemistry !--------------------------------------------------------------------------------- ! "Interactive" gas phase module !--------------------------------------------------------------------------------- use shr_kind_mod, only : r8 => shr_kind_r8, shr_kind_cl use ppgrid, only : pcols, pver, pverp, begchunk, endchunk use physconst, only : gravit use constituents, only : pcnst, cnst_add, cnst_name, sflxnam, cnst_fixed_ubc use chem_mods, only : gas_pcnst, nfs use cam_history, only : fieldname_len use physics_types, only : physics_state, physics_ptend use m_types, only : time_ramp use dust_intr, only : dust_names use progseasalts_intr,only : progseasalts_names use spmd_utils, only : masterproc use cam_logfile, only : iulog use mo_gas_phase_chemdr, only : map2chm use shr_megan_mod, only : shr_megan_mechcomps, shr_megan_mechcomps_n use tracer_data, only : MAXTRCRS implicit none private save !--------------------------------------------------------------------------------- ! Public interfaces !--------------------------------------------------------------------------------- public :: chem_is ! identify which chemistry is being used public :: chem_register ! register consituents public :: chem_readnl ! read chem namelist public :: chem_is_active ! returns true public :: chem_implements_cnst ! returns true if consituent is implemented by this package public :: chem_init_cnst ! initialize mixing ratios if not read from initial file public :: chem_init ! initialize (history) variables public :: chem_timestep_init ! per timestep initializations public :: chem_timestep_tend ! interface to tendency computation public :: chem_final public :: chem_write_restart public :: chem_read_restart public :: chem_init_restart public :: chem_reset_fluxes integer, public :: imozart = -1 ! index of 1st constituent ! Namelist variables ! control integer :: chem_freq = 1 ! time steps ! ghg character(len=shr_kind_cl) :: bndtvg = ' ' ! pathname for greenhouse gas loss rate character(len=shr_kind_cl) :: h2orates = ' ' ! pathname for greenhouse gas (lyman-alpha H2O loss) ! lightning real(r8) :: lght_no_prd_factor = 1._r8 ! photolysis logical :: xactive_prates = .false. character(len=shr_kind_cl) :: rsf_file = 'rsf_file' character(len=shr_kind_cl) :: exo_coldens_file = '' character(len=shr_kind_cl) :: tuv_xsect_file = 'tuv_xsect_file' character(len=shr_kind_cl) :: o2_xsect_file = 'o2_xsect_file' character(len=shr_kind_cl) :: xs_coef_file = 'xs_coef_file' character(len=shr_kind_cl) :: xs_short_file = 'xs_short_file' character(len=shr_kind_cl) :: xs_long_file = 'xs_long_file' character(len=shr_kind_cl) :: electron_file = 'electron_file' character(len=shr_kind_cl) :: euvac_file = 'euvac_file' character(len=shr_kind_cl) :: euvacdat_file = 'euvacdat_file' ! solar / geomag data character(len=shr_kind_cl) :: solar_parms_file = ' ' ! solar variability parameters character(len=shr_kind_cl) :: photon_file = 'photon_file' ! dry dep character(len=shr_kind_cl) :: depvel_file = 'depvel_file' character(len=shr_kind_cl) :: depvel_lnd_file = 'depvel_lnd_file' character(len=shr_kind_cl) :: clim_soilw_file = 'clim_soilw_file' character(len=shr_kind_cl) :: season_wes_file = 'season_wes_file' ! emis character(len=shr_kind_cl) :: airpl_emis_file = '' ! airplane emissions character(len=shr_kind_cl) :: srf_emis_specifier(pcnst) = '' character(len=shr_kind_cl) :: ext_frc_specifier(pcnst) = '' character(len=24) :: srf_emis_type = 'CYCLICAL' ! 'CYCLICAL' | 'SERIAL' | 'INTERP_MISSING_MONTHS' integer :: srf_emis_cycle_yr = 0 integer :: srf_emis_fixed_ymd = 0 integer :: srf_emis_fixed_tod = 0 character(len=24) :: ext_frc_type = 'CYCLICAL' ! 'CYCLICAL' | 'SERIAL' | 'INTERP_MISSING_MONTHS' integer :: ext_frc_cycle_yr = 0 integer :: ext_frc_fixed_ymd = 0 integer :: ext_frc_fixed_tod = 0 ! fixed stratosphere character(len=shr_kind_cl) :: fstrat_file = 'fstrat_file' character(len=16) :: fstrat_list(pcnst) = '' ! stratospheric aerosols character(len=shr_kind_cl) :: sad_file = 'sad_file' ! trop sulf character(len=shr_kind_cl) :: sulf_file = 'sulf_file' type(time_ramp) :: sad_timing != time_ramp( "CYCLICAL", 19970101, 0 ) ! for linoz character(len=shr_kind_cl) :: chlorine_loading_file = '' character(len=8) :: chlorine_loading_type = 'SERIAL' ! "FIXED" or "SERIAL" integer :: chlorine_loading_fixed_ymd = 0 ! YYYYMMDD for "FIXED" type integer :: chlorine_loading_fixed_tod = 0 ! seconds of day for "FIXED" type !--------------------------------------------------------------------------------- ! dummy values for specific heats at constant pressure !--------------------------------------------------------------------------------- real(r8), parameter :: cptmp = 666._r8 character(len=fieldname_len) :: srcnam(gas_pcnst) ! names of source/sink tendencies integer :: ixcldliq, ixcldice ! indicies of liquid and ice cloud water integer :: ndx_cld integer :: ndx_cmfdqr integer :: ndx_nevapr integer :: ndx_prain integer :: ndx_cldtop integer :: h2o_ndx integer :: ixndrop ! cloud droplet number index integer :: ndx_pblh logical :: ghg_chem = .false. ! .true. => use ghg chem package logical :: chem_step = .true. logical :: is_active = .false. character(len=32) :: chem_name = 'UNSET' logical :: chem_rad_passive = .false. ! for MEGAN emissions integer, allocatable :: megan_indices_map(:) real(r8),allocatable :: megan_wght_factors(:) ! dust constituent indices integer :: dust_indices(8) !================================================================================================ contains !================================================================================================ logical function chem_is (name) use phys_control, only : cam_chempkg_is character(len=*), intent(in) :: name chem_is = cam_chempkg_is(name) end function chem_is !================================================================================================ subroutine chem_register !----------------------------------------------------------------------- ! ! Purpose: register advected constituents and physics buffer fields ! !----------------------------------------------------------------------- use ioFileMod, only : getfil use mo_sim_dat, only : set_sim_dat use chem_mods, only : gas_pcnst, adv_mass, inv_lst, nfs, fix_mass use mo_tracname, only : solsym use mo_chem_utls, only : get_spc_ndx use progseasalts_intr, only : progseasalts_set_idx use dust_intr, only : dust_set_idx use short_lived_species, only : slvd_index, short_lived_map=>map, register_short_lived_species use cfc11star, only : register_cfc11star #if ( defined MODAL_AERO) use modal_aero_initialize_data, only : modal_aero_register #endif use phys_control, only : waccmx_is ! WACCM-X switch query function use mo_photo, only : photo_register use mo_aurora, only : aurora_register use mo_setsoa, only : soa_register implicit none !----------------------------------------------------------------------- ! Local variables !----------------------------------------------------------------------- integer :: idx ! Index for adding fields to pbuf physics buffer integer :: m, n ! tracer index real(r8) :: qmin ! min value logical :: ic_from_cam2 ! wrk variable for initial cond input logical :: has_fixed_ubc ! wrk variable for upper bndy cond logical :: has_fixed_ubflx ! wrk variable for upper bndy flux character(len=shr_kind_cl) :: locfn ! chemistry data filespec integer :: ch4_ndx, n2o_ndx, o3_ndx integer :: co2_ndx, cfc11_ndx, cfc12_ndx, o2_1s_ndx, o2_1d_ndx, o2_ndx integer :: n_ndx, no_ndx, co_ndx, h_ndx, h2_ndx, o_ndx, e_ndx, np_ndx integer :: op_ndx, o1d_ndx, n2d_ndx, nop_ndx, n2p_ndx, o2p_ndx integer :: cly_ndx,cl_ndx,clo_ndx,hocl_ndx,cl2_ndx,cl2o2_ndx,oclo_ndx,hcl_ndx,clono2_ndx integer :: bry_ndx,br_ndx,bro_ndx,hbr_ndx,brono2_ndx,brcl_ndx,hobr_ndx character(len=128) :: lng_name ! variable long name logical :: cam_outfld character(len=128) :: mixtype character(len=128) :: molectype integer :: islvd !----------------------------------------------------------------------- ! Set the simulation chemistry variables !----------------------------------------------------------------------- call set_sim_dat o3_ndx = get_spc_ndx('O3') ch4_ndx = get_spc_ndx('CH4') n2o_ndx = get_spc_ndx('N2O') co2_ndx = get_spc_ndx('CO2') cfc11_ndx = get_spc_ndx('CFC11') cfc12_ndx = get_spc_ndx('CFC12') o2_1s_ndx = get_spc_ndx('O2_1S') o2_1d_ndx = get_spc_ndx('O2_1D') o2_ndx = get_spc_ndx('O2') n_ndx = get_spc_ndx('N') no_ndx = get_spc_ndx('NO') co_ndx = get_spc_ndx('CO') h_ndx = get_spc_ndx('H') h2_ndx = get_spc_ndx('H2') o_ndx = get_spc_ndx('O') e_ndx = get_spc_ndx('e') np_ndx = get_spc_ndx('Np') op_ndx = get_spc_ndx('Op') o1d_ndx = get_spc_ndx('O1D_') n2d_ndx = get_spc_ndx('N2D') n2p_ndx = get_spc_ndx('N2p') nop_ndx = get_spc_ndx('NOp') h2o_ndx = get_spc_ndx('H2O') o2p_ndx = get_spc_ndx('O2p') cly_ndx = get_spc_ndx('CLY') cl_ndx = get_spc_ndx('CL') clo_ndx = get_spc_ndx('CLO') hocl_ndx = get_spc_ndx('HOCL') cl2_ndx = get_spc_ndx('CL2') cl2o2_ndx = get_spc_ndx('CL2O2') oclo_ndx = get_spc_ndx('OCLO') hcl_ndx = get_spc_ndx('HCL') clono2_ndx= get_spc_ndx('CLONO2') bry_ndx = get_spc_ndx('BRY') br_ndx = get_spc_ndx('BR') bro_ndx = get_spc_ndx('BRO') hbr_ndx = get_spc_ndx('HBR') brono2_ndx= get_spc_ndx('BRONO2') brcl_ndx = get_spc_ndx('BRCL') hobr_ndx = get_spc_ndx('HOBR') !----------------------------------------------------------------------- ! Set names of diffused variable tendencies and declare them as history variables !----------------------------------------------------------------------- !----------------------------------------------------------------------- ! BAB: 2004-09-01 kludge to define a fixed ubc for water vapor ! required because water vapor is not declared by chemistry but ! has a fixed ubc only if chemistry is running. !----------------------------------------------------------------------- if (chem_is('waccm_mozart') .or. chem_is('waccm_mozart_mam3')) then !----------------------------------------------------------------------------------------- !For WACCM-X, change variable cnst_fixed_ubc(1) from .true. to .false. which eliminates !the constant fixed upper boundary condition for all species !----------------------------------------------------------------------------------------- if ( waccmx_is('ionosphere') .or. waccmx_is('neutral') ) then cnst_fixed_ubc(1) = .false. else cnst_fixed_ubc(1) = .true. endif endif !----------------------------------------------------------------------- ! Set names of diffused variable tendencies and declare them as history variables !----------------------------------------------------------------------- !---------------------------------------------------------------------------------- ! For WACCM-X, change variable has_fixed_ubc from .true. to .false. which is a flag ! used later to check for a fixed upper boundary condition for species. !---------------------------------------------------------------------------------- do m = 1,gas_pcnst ic_from_cam2 = .true. has_fixed_ubc = .false. has_fixed_ubflx = .false. lng_name = trim( solsym(m) ) molectype = 'minor' qmin = 1.e-36_r8 if ( m == o3_ndx ) then qmin = 1.e-12_r8 else if ( m == ch4_ndx ) then qmin = 1.e-12_r8 if ( waccmx_is('ionosphere') .or. waccmx_is('neutral') ) then has_fixed_ubc = .false. ! diffusive equilibrium at UB else has_fixed_ubc = .true. endif else if ( m == n2o_ndx .or. m == co2_ndx ) then qmin = 1.e-15_r8 if( m == co2_ndx ) then if ( waccmx_is('ionosphere') .or. waccmx_is('neutral') ) then has_fixed_ubc = .false. ! diffusive equilibrium at UB else has_fixed_ubc = .true. endif end if else if( m == cfc11_ndx .or. m == cfc12_ndx ) then qmin = 1.e-20_r8 else if( m == o2_1s_ndx .or. m == o2_1d_ndx ) then ic_from_cam2 = .false. if( m == o2_1d_ndx ) then lng_name = 'O2(1-delta)' else lng_name = 'O2(1-sigma)' end if else if( m==o2_ndx .or. m==n_ndx .or. m==no_ndx .or. m==co_ndx .or. m==h_ndx .or. m==h2_ndx .or. m==o_ndx ) then if ( waccmx_is('ionosphere') .or. waccmx_is('neutral') ) then has_fixed_ubc = .false. ! diffusive equilibrium at UB if ( m == h_ndx ) has_fixed_ubflx = .true. ! fixed flux value for H at UB if ( m == o2_ndx .or. m == o_ndx ) molectype = 'major' else has_fixed_ubc = .true. endif else if( m == e_ndx ) then lng_name = 'electron concentration' else if( m == np_ndx ) then lng_name = 'N+' else if( m == op_ndx ) then lng_name = 'O+' else if( m == o1d_ndx ) then lng_name = 'O(1D)' else if( m == n2d_ndx ) then lng_name = 'N(2D)' else if( m == o2p_ndx ) then lng_name = 'O2+' else if( m == n2p_ndx ) then lng_name = 'N2+' else if( m == nop_ndx ) then lng_name = 'NO+' else if( m == h2o_ndx ) then map2chm(1) = m cycle endif if ( any(solsym(m) == dust_names) ) then cam_outfld=.true. else if ( any(solsym(m) == progseasalts_names) ) then cam_outfld=.true. else cam_outfld=.false. is_active = .true. endif if ( chem_is('waccm_mozart').or.chem_is('waccm_mozart_mam3').or. & chem_is('waccm_ghg').or.chem_is('super_fast_llnl') ) then mixtype='wet' else mixtype='dry' endif islvd = slvd_index(solsym(m)) if ( islvd > 0 ) then short_lived_map(islvd) = m else call cnst_add( solsym(m), adv_mass(m), cptmp, qmin, n, readiv=ic_from_cam2, cam_outfld=cam_outfld, & mixtype=mixtype, molectype=molectype, fixed_ubc=has_fixed_ubc, fixed_ubflx=has_fixed_ubflx, longname=trim(lng_name) ) if ( solsym(m) == dust_names(1)) call dust_set_idx(n) if ( solsym(m) == progseasalts_names(1)) call progseasalts_set_idx(n) if( imozart == -1 ) then imozart = n end if map2chm(n) = m endif end do call register_short_lived_species() call soa_register() if ( chem_is('waccm_mozart') .or. chem_is('waccm_mozart_mam3') ) then call register_cfc11star() endif #if ( defined MODAL_AERO) call modal_aero_register() #endif if ( waccmx_is('ionosphere') ) then call photo_register() call aurora_register() endif end subroutine chem_register !================================================================================================ subroutine chem_readnl(nlfile) ! Read chem namelist group. use abortutils, only: endrun use namelist_utils, only: find_group_name use units, only: getunit, freeunit use mpishorthand use mz_aerosols_intr, only: mz_aero_defaultopts, mz_aero_setopts use linoz_data, only: linoz_data_defaultopts, linoz_data_setopts use tracer_cnst, only: tracer_cnst_defaultopts, tracer_cnst_setopts use tracer_srcs, only: tracer_srcs_defaultopts, tracer_srcs_setopts use aerosol_intr, only: aerosol_readnl use gas_wetdep_opts, only: gas_wetdep_readnl #ifdef WACCM_MOZART use spedata, only: spedata_defaultopts, spedata_setopts #endif use mo_sad, only: sad_defaultopts, sad_setopts use upper_bc, only: ubc_defaultopts, ubc_setopts use mo_drydep, only: drydep_srf_file ! args character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input ! local vars integer :: unitn, ierr character(len=8) :: sad_type = 'CYCLICAL' ! 'CYCLICAL' | 'SERIAL' | 'FIXED' integer :: sad_cycle_yr = 0 integer :: sad_fixed_ymd = 0 integer :: sad_fixed_tod = 0 logical :: use_cam_sulfchem character(len=16), dimension(pcnst) :: aer_wetdep_list = ' ' ! linoz data character(len=shr_kind_cl) :: linoz_data_file ! prescribed data file character(len=shr_kind_cl) :: linoz_data_filelist ! list of prescribed data files (series of files) character(len=shr_kind_cl) :: linoz_data_path ! absolute path of prescribed data files character(len=24) :: linoz_data_type ! 'INTERP_MISSING_MONTHS' | 'CYCLICAL' | 'SERIAL' (default) logical :: linoz_data_rmfile ! remove data file from local disk (default .false.) integer :: linoz_data_cycle_yr integer :: linoz_data_fixed_ymd integer :: linoz_data_fixed_tod ! trop_mozart prescribed constituent concentratons character(len=shr_kind_cl) :: tracer_cnst_file ! prescribed data file character(len=shr_kind_cl) :: tracer_cnst_filelist ! list of prescribed data files (series of files) character(len=shr_kind_cl) :: tracer_cnst_datapath ! absolute path of prescribed data files character(len=24) :: tracer_cnst_type ! 'INTERP_MISSING_MONTHS' | 'CYCLICAL' | 'SERIAL' (default) character(len=shr_kind_cl) :: tracer_cnst_specifier(MAXTRCRS) ! string array where each logical :: tracer_cnst_rmfile ! remove data file from local disk (default .false.) integer :: tracer_cnst_cycle_yr integer :: tracer_cnst_fixed_ymd integer :: tracer_cnst_fixed_tod ! trop_mozart prescribed constituent sourrces/sinks character(len=shr_kind_cl) :: tracer_srcs_file ! prescribed data file character(len=shr_kind_cl) :: tracer_srcs_filelist ! list of prescribed data files (series of files) character(len=shr_kind_cl) :: tracer_srcs_datapath ! absolute path of prescribed data files character(len=24) :: tracer_srcs_type ! 'INTERP_MISSING_MONTHS' | 'CYCLICAL' | 'SERIAL' (default) character(len=shr_kind_cl) :: tracer_srcs_specifier(MAXTRCRS) ! string array where each logical :: tracer_srcs_rmfile ! remove data file from local disk (default .false.) integer :: tracer_srcs_cycle_yr integer :: tracer_srcs_fixed_ymd integer :: tracer_srcs_fixed_tod #if ( defined WACCM_MOZART || defined WACCM_GHG ) ! Upper boundary conditions character(len=shr_kind_cl) :: tgcm_ubc_file integer :: tgcm_ubc_cycle_yr integer :: tgcm_ubc_fixed_ymd integer :: tgcm_ubc_fixed_tod character(len=32) :: tgcm_ubc_data_type character(len=shr_kind_cl) :: snoe_ubc_file ! Upper boundary conditions real(r8) :: t_pert_ubc ! temperature perturbation at ubc real(r8) :: no_xfac_ubc ! no multiplicative factor at ubc #endif #ifdef WACCM_MOZART ! waccm solor proton data variables logical :: spe_remove_file ! true => the offline spe file will be removed character(len=shr_kind_cl) :: spe_data_file ! name of file that contains the spe data character(len=shr_kind_cl) :: spe_filenames_list ! file that lists a series of spe files #endif logical :: strat_aero_feedback ! true => radiation feed backs from strat sulfur aerosol #if ( defined MODAL_AERO) ! trop_mozart aerosol constituents that have dry deposition character(len=16) :: aer_drydep_list(pcnst) #endif namelist /chem_inparm/ chem_freq, airpl_emis_file, & solar_parms_file, euvac_file, & euvacdat_file, photon_file, electron_file, & sad_type, sad_cycle_yr, sad_fixed_ymd, sad_fixed_tod, sad_file, & sulf_file, depvel_file, xs_coef_file, xs_short_file, & exo_coldens_file, tuv_xsect_file, o2_xsect_file, & xs_long_file, rsf_file, & lght_no_prd_factor, xactive_prates, & depvel_lnd_file, clim_soilw_file, season_wes_file, drydep_srf_file, & srf_emis_type, srf_emis_cycle_yr, srf_emis_fixed_ymd, srf_emis_fixed_tod, srf_emis_specifier, & fstrat_file, fstrat_list, & ext_frc_specifier, ext_frc_type, ext_frc_cycle_yr, ext_frc_fixed_ymd, ext_frc_fixed_tod, & aer_wetdep_list, use_cam_sulfchem namelist /chem_inparm/ chem_rad_passive ! ghg chem namelist /chem_inparm/ bndtvg, h2orates, ghg_chem ! linoz inputs namelist /chem_inparm/ & linoz_data_file, linoz_data_filelist, linoz_data_path, & linoz_data_type, & linoz_data_rmfile, linoz_data_cycle_yr, linoz_data_fixed_ymd, linoz_data_fixed_tod namelist /chem_inparm/ & chlorine_loading_file, chlorine_loading_type, chlorine_loading_fixed_ymd, chlorine_loading_fixed_tod ! prescribed chem tracers namelist /chem_inparm/ & tracer_cnst_file, tracer_cnst_filelist, tracer_cnst_datapath, & tracer_cnst_type, tracer_cnst_specifier, & tracer_srcs_file, tracer_srcs_filelist, tracer_srcs_datapath, & tracer_srcs_type, tracer_srcs_specifier, & tracer_cnst_rmfile, tracer_cnst_cycle_yr, tracer_cnst_fixed_ymd, tracer_cnst_fixed_tod, & tracer_srcs_rmfile, tracer_srcs_cycle_yr, tracer_srcs_fixed_ymd, tracer_srcs_fixed_tod #if ( defined WACCM_MOZART || defined WACCM_GHG ) ! upper boundary conditions namelist /chem_inparm/ tgcm_ubc_file, tgcm_ubc_data_type, tgcm_ubc_cycle_yr, tgcm_ubc_fixed_ymd, tgcm_ubc_fixed_tod, & snoe_ubc_file, t_pert_ubc, no_xfac_ubc #endif #ifdef WACCM_MOZART ! waccm solar proton namelist variables namelist /chem_inparm/ spe_data_file, spe_remove_file, spe_filenames_list #endif ! radiation feed back from stratospheric sulfur aerosols namelist /chem_inparm/ strat_aero_feedback #if ( defined MODAL_AERO) namelist /chem_inparm/ aer_drydep_list #endif ! get the default settings #if ( defined MODAL_AERO) call mz_aero_defaultopts( aer_wetdep_list_out = aer_wetdep_list, aer_drydep_list_out = aer_drydep_list, & use_cam_sulfchem_out = use_cam_sulfchem ) #else call mz_aero_defaultopts( aer_wetdep_list_out = aer_wetdep_list, use_cam_sulfchem_out = use_cam_sulfchem ) #endif call linoz_data_defaultopts( & linoz_data_file_out = linoz_data_file, & linoz_data_filelist_out = linoz_data_filelist, & linoz_data_path_out = linoz_data_path, & linoz_data_type_out = linoz_data_type, & linoz_data_rmfile_out = linoz_data_rmfile, & linoz_data_cycle_yr_out = linoz_data_cycle_yr, & linoz_data_fixed_ymd_out = linoz_data_fixed_ymd, & linoz_data_fixed_tod_out = linoz_data_fixed_tod ) call tracer_cnst_defaultopts( & tracer_cnst_file_out = tracer_cnst_file, & tracer_cnst_filelist_out = tracer_cnst_filelist, & tracer_cnst_datapath_out = tracer_cnst_datapath, & tracer_cnst_type_out = tracer_cnst_type, & tracer_cnst_specifier_out = tracer_cnst_specifier, & tracer_cnst_rmfile_out = tracer_cnst_rmfile, & tracer_cnst_cycle_yr_out = tracer_cnst_cycle_yr, & tracer_cnst_fixed_ymd_out = tracer_cnst_fixed_ymd, & tracer_cnst_fixed_tod_out = tracer_cnst_fixed_tod ) call tracer_srcs_defaultopts( & tracer_srcs_file_out = tracer_srcs_file, & tracer_srcs_filelist_out = tracer_srcs_filelist, & tracer_srcs_datapath_out = tracer_srcs_datapath, & tracer_srcs_type_out = tracer_srcs_type, & tracer_srcs_specifier_out = tracer_srcs_specifier, & tracer_srcs_rmfile_out = tracer_srcs_rmfile, & tracer_srcs_cycle_yr_out = tracer_srcs_cycle_yr, & tracer_srcs_fixed_ymd_out = tracer_srcs_fixed_ymd, & tracer_srcs_fixed_tod_out = tracer_srcs_fixed_tod ) #ifdef WACCM_MOZART ! spedata call spedata_defaultopts( spe_data_file_out = spe_data_file, & spe_remove_file_out = spe_remove_file, & spe_filenames_list_out = spe_filenames_list ) #endif call sad_defaultopts( strat_aero_feedback_out = strat_aero_feedback ) #if ( defined WACCM_MOZART || defined WACCM_GHG ) ! Upper boundary conditions call ubc_defaultopts( & snoe_ubc_file_out =snoe_ubc_file, & #ifdef WACCM_MOZART t_pert_ubc_out =t_pert_ubc, & no_xfac_ubc_out =no_xfac_ubc, & #endif tgcm_ubc_file_out = tgcm_ubc_file, & tgcm_ubc_data_type_out = tgcm_ubc_data_type, & tgcm_ubc_cycle_yr_out = tgcm_ubc_cycle_yr, & tgcm_ubc_fixed_ymd_out = tgcm_ubc_fixed_ymd, & tgcm_ubc_fixed_tod_out = tgcm_ubc_fixed_tod ) #endif if (masterproc) then unitn = getunit() open( unitn, file=trim(nlfile), status='old' ) call find_group_name(unitn, 'chem_inparm', status=ierr) if (ierr == 0) then read(unitn, chem_inparm, iostat=ierr) if (ierr /= 0) then call endrun('chem_readnl: ERROR reading namelist') end if end if close(unitn) call freeunit(unitn) end if #ifdef SPMD ! Broadcast namelist variables ! control call mpibcast (chem_freq, 1, mpiint, 0, mpicom) call mpibcast (use_cam_sulfchem, 1, mpilog, 0, mpicom) call mpibcast (aer_wetdep_list, len(aer_wetdep_list(1))*pcnst, mpichar, 0, mpicom) #if ( defined MODAL_AERO) call mpibcast (aer_drydep_list, len(aer_drydep_list(1))*pcnst, mpichar, 0, mpicom) #endif call mpibcast (chem_rad_passive, 1, mpilog, 0, mpicom) ! ghg call mpibcast (ghg_chem, 1, mpilog, 0, mpicom) call mpibcast (bndtvg, len(bndtvg), mpichar, 0, mpicom) call mpibcast (h2orates, len(h2orates), mpichar, 0, mpicom) ! lightning call mpibcast (lght_no_prd_factor,1, mpir8, 0, mpicom) ! photolysis call mpibcast (rsf_file, len(rsf_file), mpichar, 0, mpicom) call mpibcast (exo_coldens_file, len(exo_coldens_file), mpichar, 0, mpicom) call mpibcast (tuv_xsect_file, len(tuv_xsect_file), mpichar, 0, mpicom) call mpibcast (o2_xsect_file, len(o2_xsect_file), mpichar, 0, mpicom) call mpibcast (xs_coef_file, len(xs_coef_file), mpichar, 0, mpicom) call mpibcast (xs_short_file, len(xs_short_file), mpichar, 0, mpicom) call mpibcast (xs_long_file, len(xs_long_file), mpichar, 0, mpicom) call mpibcast (xactive_prates, 1, mpilog, 0, mpicom) call mpibcast (electron_file, len(electron_file), mpichar, 0, mpicom) call mpibcast (euvac_file, len(euvac_file), mpichar, 0, mpicom) call mpibcast (euvacdat_file, len(euvacdat_file), mpichar, 0, mpicom) ! solar / geomag data call mpibcast (solar_parms_file, len(solar_parms_file), mpichar, 0, mpicom) call mpibcast (photon_file, len(photon_file), mpichar, 0, mpicom) ! dry dep call mpibcast (depvel_lnd_file, len(depvel_lnd_file), mpichar, 0, mpicom) call mpibcast (depvel_file, len(depvel_file), mpichar, 0, mpicom) call mpibcast (clim_soilw_file, len(clim_soilw_file), mpichar, 0, mpicom) call mpibcast (season_wes_file, len(season_wes_file), mpichar, 0, mpicom) call mpibcast (drydep_srf_file, len(drydep_srf_file), mpichar, 0, mpicom) ! emis call mpibcast (airpl_emis_file, len(airpl_emis_file), mpichar, 0, mpicom) call mpibcast (srf_emis_specifier,len(srf_emis_specifier(1))*pcnst,mpichar, 0, mpicom) call mpibcast (srf_emis_type, len(srf_emis_type), mpichar, 0, mpicom) call mpibcast (srf_emis_cycle_yr, 1, mpiint, 0, mpicom) call mpibcast (srf_emis_fixed_ymd,1, mpiint, 0, mpicom) call mpibcast (srf_emis_fixed_tod,1, mpiint, 0, mpicom) call mpibcast (ext_frc_specifier, len(ext_frc_specifier(1))*pcnst, mpichar, 0, mpicom) call mpibcast (ext_frc_type, len(ext_frc_type), mpichar, 0, mpicom) call mpibcast (ext_frc_cycle_yr, 1, mpiint, 0, mpicom) call mpibcast (ext_frc_fixed_ymd, 1, mpiint, 0, mpicom) call mpibcast (ext_frc_fixed_tod, 1, mpiint, 0, mpicom) ! fixed stratosphere call mpibcast (fstrat_file, len(fstrat_file), mpichar, 0, mpicom) call mpibcast (fstrat_list, len(fstrat_list(1))*pcnst, mpichar, 0, mpicom) ! stratospheric aerosols call mpibcast (sad_file, len(sad_file), mpichar, 0, mpicom) call mpibcast (sad_type, len(sad_type), mpichar, 0, mpicom) call mpibcast (sad_cycle_yr, 1, mpiint, 0, mpicom) call mpibcast (sad_fixed_ymd, 1, mpiint, 0, mpicom) call mpibcast (sad_fixed_tod, 1, mpiint, 0, mpicom) ! trop sulf call mpibcast (sulf_file, len(sulf_file), mpichar, 0, mpicom) #if ( defined WACCM_MOZART || defined WACCM_GHG ) ! upper boundary call mpibcast (tgcm_ubc_file, len(tgcm_ubc_file), mpichar, 0, mpicom) call mpibcast (tgcm_ubc_data_type, len(tgcm_ubc_data_type),mpichar, 0, mpicom) call mpibcast (tgcm_ubc_cycle_yr, 1, mpiint, 0, mpicom) call mpibcast (tgcm_ubc_fixed_ymd, 1, mpiint, 0, mpicom) call mpibcast (tgcm_ubc_fixed_tod, 1, mpiint, 0, mpicom) call mpibcast (snoe_ubc_file, len(snoe_ubc_file), mpichar, 0, mpicom) call mpibcast (t_pert_ubc, 1, mpir8, 0, mpicom) call mpibcast (no_xfac_ubc, 1, mpir8, 0, mpicom) #endif #ifdef WACCM_MOZART ! waccm solar proton variables call mpibcast (spe_data_file ,len(spe_data_file) ,mpichar,0,mpicom) call mpibcast (spe_remove_file ,1 ,mpilog, 0, mpicom ) call mpibcast (spe_filenames_list ,len(spe_filenames_list),mpichar,0,mpicom) #endif call mpibcast (strat_aero_feedback,1 ,mpilog, 0, mpicom ) ! linoz data call mpibcast (linoz_data_file, len(linoz_data_file), mpichar, 0, mpicom) call mpibcast (linoz_data_filelist, len(linoz_data_filelist), mpichar, 0, mpicom) call mpibcast (linoz_data_path, len(linoz_data_path), mpichar, 0, mpicom) call mpibcast (linoz_data_type, len(linoz_data_type), mpichar, 0, mpicom) call mpibcast (linoz_data_rmfile, 1, mpilog, 0, mpicom) call mpibcast (linoz_data_cycle_yr, 1, mpiint, 0, mpicom) call mpibcast (linoz_data_fixed_ymd, 1, mpiint, 0, mpicom) call mpibcast (linoz_data_fixed_tod, 1, mpiint, 0, mpicom) call mpibcast (chlorine_loading_file,len(chlorine_loading_file), mpichar, 0, mpicom) call mpibcast (chlorine_loading_type,len(chlorine_loading_type), mpichar, 0, mpicom) call mpibcast (chlorine_loading_fixed_ymd, 1, mpiint, 0, mpicom) call mpibcast (chlorine_loading_fixed_tod, 1, mpiint, 0, mpicom) ! prescribed chemical tracers call mpibcast (tracer_cnst_specifier, len(tracer_cnst_specifier(1))*MAXTRCRS, mpichar, 0, mpicom) call mpibcast (tracer_cnst_file, len(tracer_cnst_file), mpichar, 0, mpicom) call mpibcast (tracer_cnst_filelist, len(tracer_cnst_filelist), mpichar, 0, mpicom) call mpibcast (tracer_cnst_datapath, len(tracer_cnst_datapath), mpichar, 0, mpicom) call mpibcast (tracer_cnst_type, len(tracer_cnst_type), mpichar, 0, mpicom) call mpibcast (tracer_cnst_rmfile, 1, mpilog, 0, mpicom) call mpibcast (tracer_cnst_cycle_yr, 1, mpiint, 0, mpicom) call mpibcast (tracer_cnst_fixed_ymd, 1, mpiint, 0, mpicom) call mpibcast (tracer_cnst_fixed_tod, 1, mpiint, 0, mpicom) call mpibcast (tracer_srcs_specifier, len(tracer_srcs_specifier(1))*MAXTRCRS, mpichar, 0, mpicom) call mpibcast (tracer_srcs_file, len(tracer_srcs_file), mpichar, 0, mpicom) call mpibcast (tracer_srcs_filelist, len(tracer_srcs_filelist), mpichar, 0, mpicom) call mpibcast (tracer_srcs_datapath, len(tracer_srcs_datapath), mpichar, 0, mpicom) call mpibcast (tracer_srcs_type, len(tracer_srcs_type), mpichar, 0, mpicom) call mpibcast (tracer_srcs_rmfile, 1, mpilog, 0, mpicom) call mpibcast (tracer_srcs_cycle_yr, 1, mpiint, 0, mpicom) call mpibcast (tracer_srcs_fixed_ymd, 1, mpiint, 0, mpicom) call mpibcast (tracer_srcs_fixed_tod, 1, mpiint, 0, mpicom) #endif sad_timing%type = sad_type sad_timing%cycle_yr = sad_cycle_yr sad_timing%fixed_ymd = sad_fixed_ymd sad_timing%fixed_tod = sad_fixed_tod ! set the options #if ( defined MODAL_AERO) call mz_aero_setopts( aer_wetdep_list_in = aer_wetdep_list, aer_drydep_list_in = aer_drydep_list, & use_cam_sulfchem_in = use_cam_sulfchem ) #else call mz_aero_setopts( aer_wetdep_list_in = aer_wetdep_list, use_cam_sulfchem_in = use_cam_sulfchem ) #endif call linoz_data_setopts( & linoz_data_file_in = linoz_data_file, & linoz_data_filelist_in = linoz_data_filelist, & linoz_data_path_in = linoz_data_path, & linoz_data_type_in = linoz_data_type, & linoz_data_rmfile_in = linoz_data_rmfile, & linoz_data_cycle_yr_in = linoz_data_cycle_yr, & linoz_data_fixed_ymd_in = linoz_data_fixed_ymd, & linoz_data_fixed_tod_in = linoz_data_fixed_tod ) call tracer_cnst_setopts( & tracer_cnst_file_in = tracer_cnst_file, & tracer_cnst_filelist_in = tracer_cnst_filelist, & tracer_cnst_datapath_in = tracer_cnst_datapath, & tracer_cnst_type_in = tracer_cnst_type, & tracer_cnst_specifier_in = tracer_cnst_specifier, & tracer_cnst_rmfile_in = tracer_cnst_rmfile, & tracer_cnst_cycle_yr_in = tracer_cnst_cycle_yr, & tracer_cnst_fixed_ymd_in = tracer_cnst_fixed_ymd, & tracer_cnst_fixed_tod_in = tracer_cnst_fixed_tod ) call tracer_srcs_setopts( & tracer_srcs_file_in = tracer_srcs_file, & tracer_srcs_filelist_in = tracer_srcs_filelist, & tracer_srcs_datapath_in = tracer_srcs_datapath, & tracer_srcs_type_in = tracer_srcs_type, & tracer_srcs_specifier_in = tracer_srcs_specifier, & tracer_srcs_rmfile_in = tracer_srcs_rmfile, & tracer_srcs_cycle_yr_in = tracer_srcs_cycle_yr, & tracer_srcs_fixed_ymd_in = tracer_srcs_fixed_ymd, & tracer_srcs_fixed_tod_in = tracer_srcs_fixed_tod ) #ifdef WACCM_MOZART call spedata_setopts( spe_data_file_in = spe_data_file, & spe_remove_file_in = spe_remove_file, & spe_filenames_list_in = spe_filenames_list ) #endif call sad_setopts( strat_aero_feedback_in = strat_aero_feedback ) #if ( defined WACCM_MOZART || defined WACCM_GHG ) ! Upper boundary conditions call ubc_setopts( & snoe_ubc_file_in =snoe_ubc_file, & #ifdef WACCM_MOZART t_pert_ubc_in =t_pert_ubc, & no_xfac_ubc_in =no_xfac_ubc, & #endif tgcm_ubc_file_in =tgcm_ubc_file, & tgcm_ubc_data_type_in = tgcm_ubc_data_type, & tgcm_ubc_cycle_yr_in = tgcm_ubc_cycle_yr, & tgcm_ubc_fixed_ymd_in = tgcm_ubc_fixed_ymd, & tgcm_ubc_fixed_tod_in = tgcm_ubc_fixed_tod ) #endif call aerosol_readnl(nlfile) ! call gas_wetdep_readnl(nlfile) endsubroutine chem_readnl !================================================================================================ function chem_is_active() !----------------------------------------------------------------------- ! Purpose: return true if this package is active !----------------------------------------------------------------------- logical :: chem_is_active !----------------------------------------------------------------------- chem_is_active = is_active end function chem_is_active !================================================================================================ function chem_implements_cnst(name) !----------------------------------------------------------------------- ! ! Purpose: return true if specified constituent is implemented by this package ! ! Author: B. Eaton ! !----------------------------------------------------------------------- use chem_mods, only : gas_pcnst, inv_lst, nfs use mo_tracname, only : solsym !----------------------------------------------------------------------- ! ... dummy arguments !----------------------------------------------------------------------- character(len=*), intent(in) :: name ! constituent name logical :: chem_implements_cnst ! return value !----------------------------------------------------------------------- ! ... local variables !----------------------------------------------------------------------- integer :: m chem_implements_cnst = .false. do m = 1,gas_pcnst if( trim(name) /= 'H2O' ) then if( trim(name) == solsym(m) ) then chem_implements_cnst = .true. exit end if end if end do do m = 1,nfs if( trim(name) /= 'H2O' ) then if( trim(name) == inv_lst(m) ) then chem_implements_cnst = .true. exit end if endif enddo end function chem_implements_cnst subroutine chem_init(phys_state, pbuf2d) !----------------------------------------------------------------------- ! ! Purpose: initialize parameterized greenhouse gas chemistry ! (declare history variables) ! ! Method: ! ! ! ! Author: NCAR CMS ! !----------------------------------------------------------------------- use physics_buffer, only : physics_buffer_desc, pbuf_get_index use constituents, only : cnst_get_ind, cnst_longname use cam_history, only : addfld, add_default, phys_decomp, fieldname_len use chem_mods, only : gas_pcnst, nfs, inv_lst use mo_chemini, only : chemini use mo_constants, only : mo_constants_inti use mz_aerosols_intr, only : mz_aero_initialize use mo_ghg_chem, only : ghg_chem_init use mo_tracname, only : solsym use llnl_O1D_to_2OH_adj, only : O1D_to_2OH_adj_init use lin_strat_chem, only : lin_strat_chem_inti #if ( defined MODAL_AERO ) use modal_aero_initialize_data, only: modal_aero_initialize #endif use chlorine_loading_data, only : chlorine_loading_init use cfc11star, only : init_cfc11star use phys_control, only : phys_getopts use chem_mods, only : adv_mass use infnan, only : nan use mo_chem_utls, only : get_spc_ndx use abortutils, only : endrun type(physics_buffer_desc), pointer :: pbuf2d(:,:) type(physics_state), intent(in):: phys_state(begchunk:endchunk) !----------------------------------------------------------------------- ! Local variables !----------------------------------------------------------------------- integer :: m ! tracer indicies character(len=fieldname_len) :: spc_name integer :: i, n, ii call phys_getopts(cam_chempkg_out=chem_name) call mo_constants_inti call mz_aero_initialize() #if ( defined MODAL_AERO ) call modal_aero_initialize(pbuf2d) #endif !----------------------------------------------------------------------- ! Get liq and ice cloud water indicies !----------------------------------------------------------------------- call cnst_get_ind( 'CLDLIQ', ixcldliq ) call cnst_get_ind( 'CLDICE', ixcldice ) call cnst_get_ind( 'NUMLIQ', ixndrop, abort=.false. ) !----------------------------------------------------------------------- ! get pbuf indicies !----------------------------------------------------------------------- ndx_cld = pbuf_get_index('CLD') ndx_cmfdqr = pbuf_get_index('RPRDTOT') ndx_nevapr = pbuf_get_index('NEVAPR') ndx_prain = pbuf_get_index('PRAIN') ndx_cldtop = pbuf_get_index('CLDTOP') ndx_pblh = pbuf_get_index('pblh') call addfld( 'HEIGHT', 'm', pverp,'A', 'geopotential height above surface at interfaces (m)', phys_decomp ) call addfld( 'CT_H2O_GHG','kg/kg/s ', pver, 'A', 'ghg-chem h2o source/sink', phys_decomp ) !----------------------------------------------------------------------- ! Set names of chemistry variable tendencies and declare them as history variables !----------------------------------------------------------------------- do m = 1,gas_pcnst spc_name = solsym(m) srcnam(m) = 'CT_' // spc_name ! chem tendancy (source/sink) call addfld( srcnam(m), 'kg/kg/s ', pver, 'A', trim(spc_name)//' source/sink', phys_decomp ) !call add_default (srcnam(m), 1, ' ') end do if ( masterproc ) write(iulog,*) 'chem_init: addfld done' !----------------------------------------------------------------------- ! Initialize chemistry modules !----------------------------------------------------------------------- call chemini & ( solar_parms_file & , euvac_file & , euvacdat_file & , photon_file & , electron_file & , airpl_emis_file & , sulf_file & , sad_file & , sad_timing & , depvel_file & , depvel_lnd_file & , clim_soilw_file & , season_wes_file & , xs_coef_file & , xs_short_file & , xs_long_file & , rsf_file & , fstrat_file & , fstrat_list & , srf_emis_specifier & , srf_emis_type & , srf_emis_cycle_yr & , srf_emis_fixed_ymd & , srf_emis_fixed_tod & , ext_frc_specifier & , ext_frc_type & , ext_frc_cycle_yr & , ext_frc_fixed_ymd & , ext_frc_fixed_tod & , xactive_prates & , exo_coldens_file & , tuv_xsect_file & , o2_xsect_file & , lght_no_prd_factor & , chem_name & , pbuf2d & ) if ( ghg_chem ) then call ghg_chem_init(phys_state, bndtvg, h2orates) endif if ( chem_name == 'super_fast_llnl' .or. chem_name == 'super_fast_llnl_mam3' ) then call O1D_to_2OH_adj_init endif call lin_strat_chem_inti(phys_state) call chlorine_loading_init( chlorine_loading_file, & type = chlorine_loading_type, & ymd = chlorine_loading_fixed_ymd, & tod = chlorine_loading_fixed_tod ) if ( chem_is('waccm_mozart') .or. chem_is('waccm_mozart_mam3') ) then call init_cfc11star(pbuf2d) endif ! Bulk aerosols call cnst_get_ind('DST01',dust_indices(1), abort=.false.) call cnst_get_ind('DST02',dust_indices(2), abort=.false.) call cnst_get_ind('DST03',dust_indices(3), abort=.false.) call cnst_get_ind('DST04',dust_indices(4), abort=.false.) ! MODAL aerosols call cnst_get_ind('dst_a1',dust_indices(5), abort=.false.) call cnst_get_ind('dst_a3',dust_indices(6), abort=.false.) call cnst_get_ind('dst_a5',dust_indices(7), abort=.false.) call cnst_get_ind('dst_a7',dust_indices(8), abort=.false.) ! MEGAN emissions initialize if (shr_megan_mechcomps_n>0) then allocate( megan_indices_map(shr_megan_mechcomps_n) ) allocate( megan_wght_factors(shr_megan_mechcomps_n) ) megan_wght_factors(:) = nan do n=1,shr_megan_mechcomps_n call cnst_get_ind (shr_megan_mechcomps(n)%name, megan_indices_map(n), abort=.false.) ii = get_spc_ndx(shr_megan_mechcomps(n)%name) if (ii>0) then megan_wght_factors(n) = adv_mass(ii)*1.e-3_r8 ! kg/moles (to convert moles/m2/sec to kg/m2/sec) else call endrun('gas_phase_chemdr_inti: MEGAN compound not in chemistry mechanism : '//trim(shr_megan_mechcomps(n)%name)) endif ! MEGAN history fields call addfld( 'MEG_'//trim(shr_megan_mechcomps(n)%name),'kg/m2/sec',1,'A',& trim(shr_megan_mechcomps(n)%name)//' MEGAN emissions flux',phys_decomp) enddo endif end subroutine chem_init !================================================================================ !================================================================================ subroutine chem_reset_fluxes( fptr, cam_in ) use camsrfexch, only : cam_in_t use constituents, only : pcnst, cnst_get_ind use mo_gas_phase_chemdr, only : map2chm use phys_grid, only : get_ncols_p use cam_cpl_indices, only : index_x2a_Fall_flxvoc use cam_history, only : outfld real(r8), pointer :: fptr(:,:) ! pointer into array data type(cam_in_t), intent(inout) :: cam_in(begchunk:endchunk) integer :: i,c,ig,imech, ncols ! indices integer :: m,n ! dust_intr module modifies cflx for dust each time step ! -- resetting dust emissions each time step here changes answers...?? ig=1 do c=begchunk,endchunk ncols = get_ncols_p(c) ! initialize chemistry constituent surface fluxes to zero do m = 2,pcnst n = map2chm(m) if (.not. ( any(dust_indices(:)==m) )) then if (n>0) cam_in(c)%cflx(:,m) = 0._r8 endif enddo if ( index_x2a_Fall_flxvoc>0 .and. shr_megan_mechcomps_n>0 ) then ! set MEGAN fluxes do i =1,ncols do imech = 1,shr_megan_mechcomps_n cam_in(c)%cflx(i,megan_indices_map(imech)) = -fptr(index_x2a_Fall_flxvoc+imech-1, ig)*megan_wght_factors(imech) enddo ig=ig+1 end do ! output MEGAN emis fluxes to history do n = 1,shr_megan_mechcomps_n call outfld('MEG_'//trim(shr_megan_mechcomps(n)%name), cam_in(c)%cflx(:ncols, megan_indices_map(n)), ncols, c) enddo endif end do end subroutine chem_reset_fluxes !================================================================================ subroutine chem_init_cnst( name, q, gcid) !----------------------------------------------------------------------- ! ! Purpose: ! Specify initial mass mixing ratios ! !----------------------------------------------------------------------- use chem_mods, only : inv_lst use physconst, only : mwdry, mwch4, mwn2o, mwf11, mwf12, mwh2o, mwo3 use chem_surfvals, only : chem_surfvals_get implicit none !----------------------------------------------------------------------- ! Dummy arguments !----------------------------------------------------------------------- character(len=*), intent(in) :: name ! constituent name real(r8), intent(inout) :: q(:,:) ! mass mixing ratio integer, intent(in) :: gcid(:) !----------------------------------------------------------------------- ! Local variables !----------------------------------------------------------------------- real(r8) :: rmwn2o != mwn2o/mwdry ! ratio of mol weight n2o to dry air real(r8) :: rmwch4 != mwch4/mwdry ! ratio of mol weight ch4 to dry air real(r8) :: rmwf11 != mwf11/mwdry ! ratio of mol weight cfc11 to dry air real(r8) :: rmwf12 != mwf12/mwdry ! ratio of mol weight cfc12 to dry air !----------------------------------------------------------------------- ! initialize local variables !----------------------------------------------------------------------- rmwn2o = mwn2o/mwdry rmwch4 = mwch4/mwdry rmwf11 = mwf11/mwdry rmwf12 = mwf12/mwdry !----------------------------------------------------------------------- ! Get initial mixing ratios !----------------------------------------------------------------------- if ( any( inv_lst .eq. name ) ) then q(:,:) = 0.0_r8 else q(:,:) = 1.e-38_r8 endif if ( ghg_chem ) then select case (name) case ('N2O') q = rmwn2o * chem_surfvals_get('N2OVMR') case ('CH4') q = rmwch4 * chem_surfvals_get('CH4VMR') case ('CFC11') q = rmwf11 * chem_surfvals_get('F11VMR') case ('CFC12') q = rmwf12 * chem_surfvals_get('F12VMR') end select endif end subroutine chem_init_cnst subroutine chem_timestep_init(phys_state,pbuf2d) use time_manager, only : get_nstep use time_manager, only : get_curr_calday use mo_srf_emissions, only : set_srf_emissions_time use mo_sulf, only : set_sulf_time use mo_extfrc, only : extfrc_timestep_init use mo_flbc, only : flbc_chk use tracer_cnst, only : tracer_cnst_adv use tracer_srcs, only : tracer_srcs_adv use mo_ghg_chem, only : ghg_chem_timestep_init use mo_solar_parms, only : solar_parms_timestep_init use mo_jshort, only : jshort_timestep_init use mo_jlong, only : jlong_timestep_init use mo_aurora, only : aurora_timestep_init use spedata, only : advance_spedata use mo_photo, only : photo_timestep_init use mo_strato_sad, only : strato_sad_timestep_init use linoz_data, only : linoz_data_adv use chlorine_loading_data, only : chlorine_loading_advance use cfc11star, only : update_cfc11star use physics_buffer, only : physics_buffer_desc implicit none type(physics_state), intent(inout) :: phys_state(begchunk:endchunk) type(physics_buffer_desc), pointer :: pbuf2d(:,:) !----------------------------------------------------------------------- ! Local variables !----------------------------------------------------------------------- real(r8) :: calday integer :: nstep nstep = get_nstep() chem_step = mod( nstep, chem_freq ) == 0 if ( .not. chem_step ) return !----------------------------------------------------------------------- ! get current calendar day of year !----------------------------------------------------------------------- calday = get_curr_calday( ) !----------------------------------------------------------------------- ! Set emissions timing factors !----------------------------------------------------------------------- call set_srf_emissions_time( pbuf2d, phys_state ) !----------------------------------------------------------------------- ! Set external forcings timing factors !----------------------------------------------------------------------- call extfrc_timestep_init( pbuf2d, phys_state ) !----------------------------------------------------------------------- ! Set sulf timing factors !----------------------------------------------------------------------- call set_sulf_time( calday ) !----------------------------------------------------------------------- ! Set fixed lower boundary timing factors !----------------------------------------------------------------------- call flbc_chk !----------------------------------------------------------------------- ! Advance stratospheric aerosol densities... !----------------------------------------------------------------------- call strato_sad_timestep_init() !----------------------------------------------------------------------- ! Set fixed offline tracers !----------------------------------------------------------------------- call tracer_cnst_adv(pbuf2d, phys_state) !----------------------------------------------------------------------- ! Set fixed offline tracer sources !----------------------------------------------------------------------- call tracer_srcs_adv(pbuf2d, phys_state) !----------------------------------------------------------------------- ! Advance the linoz data !----------------------------------------------------------------------- call linoz_data_adv(pbuf2d, phys_state) call chlorine_loading_advance() if ( ghg_chem ) then call ghg_chem_timestep_init(phys_state) endif if (chem_is('waccm_ghg') .or. chem_is('waccm_mozart') .or. chem_is('waccm_mozart_mam3')) then !----------------------------------------------------------------------- ! Set solar parameters !----------------------------------------------------------------------- call solar_parms_timestep_init endif !----------------------------------------------------------------------------- ! ... setup the time interpolation for mo_photo !----------------------------------------------------------------------------- call photo_timestep_init( calday ) !----------------------------------------------------------------------- ! Set jlong etf !----------------------------------------------------------------------- call jlong_timestep_init if (chem_is('waccm_mozart') .or. chem_is('waccm_mozart_mam3')) then !----------------------------------------------------------------------- ! Set jshort etf !----------------------------------------------------------------------- call jshort_timestep_init !----------------------------------------------------------------------- ! Set up aurora !----------------------------------------------------------------------- call aurora_timestep_init !----------------------------------------------------------------------- ! Set up solar proton data !----------------------------------------------------------------------- call advance_spedata() call update_cfc11star( pbuf2d, phys_state ) endif end subroutine chem_timestep_init subroutine chem_timestep_tend( state, ptend, cam_in, cam_out, dt, & pbuf, fh2o, fsds ) !----------------------------------------------------------------------- ! ! Purpose: ! Interface to parameterized greenhouse gas chemisty (source/sink). ! ! Method: ! ! ! ! Author: B.A. Boville ! !----------------------------------------------------------------------- use physics_buffer, only : physics_buffer_desc, pbuf_get_field, pbuf_old_tim_idx use cam_history, only : outfld use time_manager, only : get_curr_calday use chem_mods, only : gas_pcnst use mo_gas_phase_chemdr, only : gas_phase_chemdr use spmd_utils, only : iam use camsrfexch, only : cam_in_t, cam_out_t use perf_mod, only : t_startf, t_stopf use tropopause, only : tropopause_find, TROP_ALG_HYBSTOB, TROP_ALG_CLIMATE use mo_drydep, only : drydep_update use mo_neu_wetdep, only : neu_wetdep_tend, do_neu_wetdep #if (defined MODAL_AERO) use modal_aero_data, only : ntot_amode #endif use aerodep_flx, only : aerodep_flx_prescribed implicit none !----------------------------------------------------------------------- ! Dummy 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(cam_in_t), intent(inout) :: cam_in type(cam_out_t), intent(inout) :: cam_out real(r8), intent(out) :: fh2o(pcols) ! h2o flux to balance source from chemistry type(physics_buffer_desc), pointer :: pbuf(:) real(r8), intent(in) :: fsds(pcols) ! longwave down at sfc !----------------------------------------------------------------------- ! Local variables !----------------------------------------------------------------------- integer :: i, k, m, n ! indicies integer :: lchnk ! chunk identifier integer :: ncol ! number of atmospheric columns real(r8) :: calday ! current calendar day of year real(r8) :: cldw(pcols,pver) ! cloud water (kg/kg) real(r8) :: chem_dt ! time step real(r8) :: drydepflx(pcols,pcnst) ! dry deposition fluxes (kg/m2/s) integer :: tropLev(pcols) real(r8) :: ncldwtr(pcols,pver) ! droplet number concentration (#/kg) real(r8), pointer :: pblh(:) real(r8), pointer :: prain(:,:) real(r8), pointer :: cldfr(:,:) real(r8), pointer :: cmfdqr(:,:) real(r8), pointer :: nevapr(:,:) real(r8), pointer :: cldtop(:) integer :: tim_ndx if ( .not. chem_step ) return chem_dt = chem_freq*dt lchnk = state%lchnk ncol = state%ncol call drydep_update( state, cam_in ) !----------------------------------------------------------------------- ! get current calendar day of year !----------------------------------------------------------------------- calday = get_curr_calday() !----------------------------------------------------------------------- ! get tropopause level !----------------------------------------------------------------------- call tropopause_find(state, tropLev, primary=TROP_ALG_HYBSTOB, backup=TROP_ALG_CLIMATE) tim_ndx = pbuf_old_tim_idx() call pbuf_get_field(pbuf, ndx_pblh, pblh) call pbuf_get_field(pbuf, ndx_prain, prain, start=(/1,1/), kount=(/ncol,pver/)) call pbuf_get_field(pbuf, ndx_cld, cldfr, start=(/1,1,tim_ndx/), kount=(/ncol,pver,1/) ) call pbuf_get_field(pbuf, ndx_cmfdqr, cmfdqr, start=(/1,1/), kount=(/ncol,pver/)) call pbuf_get_field(pbuf, ndx_nevapr, nevapr, start=(/1,1/), kount=(/ncol,pver/)) call pbuf_get_field(pbuf, ndx_cldtop, cldtop ) !----------------------------------------------------------------------- ! call Neu wet dep scheme !----------------------------------------------------------------------- call neu_wetdep_tend(lchnk,ncol,state%q,state%pmid,state%pdel,state%zi,state%t,dt, & prain, nevapr, cldfr, cmfdqr, ptend%q) !----------------------------------------------------------------------- ! compute tendencies and surface fluxes !----------------------------------------------------------------------- call t_startf( 'chemdr' ) do k = 1,pver cldw(:ncol,k) = state%q(:ncol,k,ixcldliq) + state%q(:ncol,k,ixcldice) if (ixndrop>0) & ncldwtr(:ncol,k) = state%q(:ncol,k,ixndrop) end do call gas_phase_chemdr(lchnk, ncol, imozart, state%q, ptend%q, & cam_in%cflx, state%phis, state%zm, state%zi, calday, & state%t, state%pmid, state%pdel, state%pint, & cldw, tropLev, ncldwtr, state%u, state%v, & chem_dt, state%ps, xactive_prates, & fsds, cam_in%ts, cam_in%asdir, cam_in%ocnfrac, cam_in%icefrac, & cam_out%precc, cam_out%precl, cam_in%snowhland, ghg_chem, state%latmapback, & chem_name, drydepflx, pbuf) call t_stopf( 'chemdr' ) !----------------------------------------------------------------------- ! set flags for tracer tendencies (water and gas phase constituents) ! record tendencies on history files !----------------------------------------------------------------------- ptend%name = 'chemistry' do n = 1,pcnst m = map2chm(n) if( m > 0 ) then ptend%lq(n) = .true. call outfld( srcnam(m), ptend%q(:,:,n), pcols, lchnk ) end if ! if the user has specified prescribed aerosol dep fluxes then ! do not set cam_out dep fluxes according to the prognostic aerosols if (.not.aerodep_flx_prescribed()) then ! set deposition fluxes in the export state select case (trim(cnst_name(n))) case('CB1') do i = 1, ncol cam_out%bcphodry(i) = max(drydepflx(i,n), 0._r8) end do case('CB2') do i = 1, ncol cam_out%bcphidry(i) = max(drydepflx(i,n), 0._r8) end do case('OC1') do i = 1, ncol cam_out%ocphodry(i) = max(drydepflx(i,n), 0._r8) end do case('OC2') do i = 1, ncol cam_out%ocphidry(i) = max(drydepflx(i,n), 0._r8) end do end select endif end do if ( ghg_chem ) then ptend%lq(1) = .true. call outfld( 'CT_H2O_GHG', ptend%q(:,:,1), pcols, lchnk ) endif call outfld( 'HEIGHT', state%zi(:ncol,:), ncol, lchnk ) !----------------------------------------------------------------------- ! turn off water vapor tendency if radiatively passive !----------------------------------------------------------------------- if (chem_rad_passive) then ptend%lq(1) = .false. ptend%q(:ncol,:,1) = 0._r8 endif !----------------------------------------------------------------------- ! Compute water vapor flux required to make conservation check !----------------------------------------------------------------------- fh2o(:ncol) = 0._r8 do k = 1,pver fh2o(:ncol) = fh2o(:ncol) + ptend%q(:ncol,k,1)*state%pdel(:ncol,k)/gravit end do end subroutine chem_timestep_tend !------------------------------------------------------------------- !------------------------------------------------------------------- subroutine chem_final end subroutine chem_final !------------------------------------------------------------------- !------------------------------------------------------------------- subroutine chem_init_restart( File ) use pio, only : file_desc_t use tracer_cnst, only: init_tracer_cnst_restart use tracer_srcs, only: init_tracer_srcs_restart use linoz_data, only : init_linoz_data_restart implicit none type(file_desc_t),intent(inout) :: File ! pio File pointer ! ! data for offline tracers ! call init_tracer_cnst_restart(File) call init_tracer_srcs_restart(File) call init_linoz_data_restart(File) end subroutine chem_init_restart !------------------------------------------------------------------- !------------------------------------------------------------------- subroutine chem_write_restart( File ) use tracer_cnst, only: write_tracer_cnst_restart use tracer_srcs, only: write_tracer_srcs_restart use linoz_data, only: write_linoz_data_restart use pio, only : file_desc_t implicit none type(file_desc_t) :: File ! ! data for offline tracers ! call write_tracer_cnst_restart(File) call write_tracer_srcs_restart(File) call write_linoz_data_restart(File) end subroutine chem_write_restart !------------------------------------------------------------------- !------------------------------------------------------------------- subroutine chem_read_restart( File ) use tracer_cnst, only: read_tracer_cnst_restart use tracer_srcs, only: read_tracer_srcs_restart use linoz_data, only: read_linoz_data_restart use pio, only : file_desc_t implicit none type(file_desc_t) :: File ! ! data for offline tracers ! call read_tracer_cnst_restart(File) call read_tracer_srcs_restart(File) call read_linoz_data_restart(File) end subroutine chem_read_restart end module chemistry