diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90
index 72c6b5972..99a91841b 100644
--- a/datm/atm_comp_nuopc.F90
+++ b/datm/atm_comp_nuopc.F90
@@ -124,6 +124,7 @@ module cdeps_datm_comp
character(CL) :: factorFn_data = 'null' ! file containing correction factors data
logical :: flds_presaero = .false. ! true => send valid prescribed aero fields to mediator
logical :: flds_presndep = .false. ! true => send valid prescribed ndep fields to mediator
+ logical :: flds_preso3 = .false. ! true => send valid prescribed ozone fields to mediator
logical :: flds_co2 = .false. ! true => send prescribed co2 to mediator
logical :: flds_wiso = .false. ! true => send water isotopes to mediator
character(CL) :: bias_correct = nullstr ! send bias correction fields to coupler
@@ -230,7 +231,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
model_meshfile, model_maskfile, &
nx_global, ny_global, restfilm, iradsw, factorFn_data, factorFn_mesh, &
flds_presaero, flds_co2, flds_wiso, bias_correct, anomaly_forcing, &
- skip_restart_read, flds_presndep
+ skip_restart_read, flds_presndep, flds_preso3
rc = ESMF_SUCCESS
@@ -270,6 +271,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
call shr_mpi_bcast(restfilm , mpicom, 'restfilm')
call shr_mpi_bcast(flds_presaero , mpicom, 'flds_presaero')
call shr_mpi_bcast(flds_presndep , mpicom, 'flds_presndep')
+ call shr_mpi_bcast(flds_preso3 , mpicom, 'flds_preso3')
call shr_mpi_bcast(flds_co2 , mpicom, 'flds_co2')
call shr_mpi_bcast(flds_wiso , mpicom, 'flds_wiso')
call shr_mpi_bcast(skip_restart_read , mpicom, 'skip_restart_read')
@@ -288,6 +290,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
write(logunit,F00)' factorFn_mesh = ',trim(factorFn_mesh)
write(logunit,F02)' flds_presaero = ',flds_presaero
write(logunit,F02)' flds_presndep = ',flds_presndep
+ write(logunit,F02)' flds_preso3 = ',flds_preso3
write(logunit,F02)' flds_co2 = ',flds_co2
write(logunit,F02)' flds_wiso = ',flds_wiso
write(logunit,F02)' skip_restart_read = ',skip_restart_read
@@ -319,7 +322,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
case ('CLMNCEP')
call datm_datamode_clmncep_advertise(exportState, fldsExport, flds_scalar_name, &
- flds_co2, flds_wiso, flds_presaero, flds_presndep, rc)
+ flds_co2, flds_wiso, flds_presaero, flds_presndep, flds_preso3, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
case ('CPLHIST')
call datm_datamode_cplhist_advertise(exportState, fldsExport, flds_scalar_name, &
diff --git a/datm/cime_config/buildnml b/datm/cime_config/buildnml
index 2ff95fdbe..575949b10 100755
--- a/datm/cime_config/buildnml
+++ b/datm/cime_config/buildnml
@@ -76,7 +76,7 @@ def _get_neon_data_availability(case, neonsite):
oldestdate = datetime.strptime(neonatm[-10:],"%Y-%m.nc")
neonatm = f'cdeps/{version}/{neonsite}/'+neonatm
datavaliddate.append(neonatm)
- if newestdate:
+ if newestdate:
logger.info("Found tower data version {} for {} through {}".format(version, oldestdate, newestdate))
datavaliddate.sort()
return datavaliddate
@@ -105,6 +105,7 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path
datm_topo = case.get_value("DATM_TOPO")
datm_presaero = case.get_value("DATM_PRESAERO")
datm_presndep = case.get_value("DATM_PRESNDEP")
+ datm_preso3 = case.get_value("DATM_PRESO3")
datm_co2_tseries = case.get_value("DATM_CO2_TSERIES")
atm_grid = case.get_value("ATM_GRID")
model_grid = case.get_value("GRID")
@@ -116,6 +117,8 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path
"A DATM_MODE for CLM is incompatible with DATM_PRESAERO=none.")
expect(datm_presndep != "none",
"A DATM_MODE for CLM is incompatible with DATM_PRESNDEP=none.")
+ expect(datm_preso3 != "none",
+ "A DATM_MODE for CLM is incompatible with DATM_PRESO3=none.")
expect(datm_topo != "none",
"A DATM_MODE for CLM is incompatible with DATM_TOPO=none.")
@@ -124,6 +127,7 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path
logger.debug("DATM grid is {}".format(atm_grid))
logger.debug("DATM presaero mode is {}".format(datm_presaero))
logger.debug("DATM presndep mode is {}".format(datm_presndep))
+ logger.debug("DATM preso3 mode is {}".format(datm_preso3))
logger.debug("DATM topo mode is {}".format(datm_topo))
# Initialize namelist defaults
@@ -143,6 +147,7 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path
config['datm_co2_tseries'] = datm_co2_tseries
config['datm_presaero'] = datm_presaero
config['datm_presndep'] = datm_presndep
+ config['datm_preso3'] = datm_preso3
if case.get_value('PTS_LON'):
scol_lon = float(case.get_value('PTS_LON'))
@@ -173,10 +178,13 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path
streamlist.append("presaero.{}".format(datm_presaero))
if datm_presndep != "none":
streamlist.append("presndep.{}".format(datm_presndep))
+ if datm_preso3 != "none":
+ streamlist.append("preso3.{}".format(datm_preso3))
if datm_topo != "none":
streamlist.append("topo.{}".format(datm_topo))
if datm_co2_tseries != "none":
streamlist.append("co2tseries.{}".format(datm_co2_tseries))
+
bias_correct = nmlgen.get_value("bias_correct")
if bias_correct is not None:
streamlist.append(bias_correct)
@@ -189,10 +197,33 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path
schema_file = os.path.join(_CDEPS_CONFIG,"stream_definition_v2.0.xsd")
stream_file = os.path.join(_CDEPS_CONFIG,os.pardir, "datm","cime_config","stream_definition_datm.xml")
streams = StreamCDEPS(stream_file, schema_file)
- streams.create_stream_xml(streamlist, case, outfile, data_list_path,
+ streams.create_stream_xml(streamlist, case, outfile, data_list_path,
os.path.join(caseroot,'user_nl_datm_streams'+inst_string),
available_neon_data=available_neon_data)
+
+####################################################################################
+def _create_drv_flds_in(case, confdir):
+####################################################################################
+ datm_preso3 = case.get_value("DATM_PRESO3")
+
+ # for now we are hard-coding this file name and values because we only need it for ozone
+ if datm_preso3 != "none":
+
+ # Generate drv_flds_in file
+ outfile = os.path.join(confdir, "drv_flds_in")
+ ozone_nl_name = "&ozone_coupling_nl"
+ ozone_freq_par = "atm_ozone_frequency"
+ ozone_freq_val = "'multiday_average'"
+ nl_fin = "/"
+
+ with open(outfile, "w") as drv_fl:
+ drv_fl.write("{}\n".format(ozone_nl_name))
+ drv_fl.write(" {} = {}\n".format(ozone_freq_par, ozone_freq_val))
+ drv_fl.write("{}\n".format(nl_fin))
+
+
+
###############################################################################
def buildnml(case, caseroot, compname):
###############################################################################
@@ -267,6 +298,8 @@ def buildnml(case, caseroot, compname):
# create namelist and stream file(s) data component
_create_namelists(case, confdir, inst_string, namelist_infile, nmlgen, data_list_path)
+ _create_drv_flds_in(case, confdir)
+
# copy namelist files and stream text files, to rundir
copy_inputs_to_rundir(caseroot, compname, confdir, rundir, inst_string)
diff --git a/datm/cime_config/config_component.xml b/datm/cime_config/config_component.xml
index eed8a082d..9ff459f51 100644
--- a/datm/cime_config/config_component.xml
+++ b/datm/cime_config/config_component.xml
@@ -92,7 +92,7 @@
char
- none,clim_1850,clim_2000,clim_2010,hist,SSP1-2.6,SSP2-4.5,SSP3-7.0,SSP5-3.4,SSP5-8.5
+ none,clim_1850,clim_2000,clim_2010,hist,SSP1-2.6,SSP2-4.5,SSP3-7.0,SSP5-3.4,SSP5-8.5,cplhist
clim_2000
clim_1850
@@ -112,6 +112,28 @@
DATM prescribed nitrogen deposition forcing
+
+ char
+ none,clim_1850,clim_2000,clim_2010,hist,SSP2-4.5,SSP3-7.0,SSP5-8.5
+ clim_2000
+
+ clim_1850
+ clim_2000
+ clim_2010
+ SSP2-4.5
+ SSP3-7.0
+ SSP5-8.5
+ hist
+ hist
+
+ none
+ none
+
+ run_component_datm
+ env_run.xml
+ DATM prescribed ozone forcing
+
+
char
none,observed,cplhist
diff --git a/datm/cime_config/namelist_definition_datm.xml b/datm/cime_config/namelist_definition_datm.xml
index 3ea0bef64..c677bffe0 100644
--- a/datm/cime_config/namelist_definition_datm.xml
+++ b/datm/cime_config/namelist_definition_datm.xml
@@ -279,6 +279,19 @@
+
+ logical
+ datm
+ datm_nml
+
+ If true, prescribed o3 is sent from datm (must be true for running with CLM).
+
+
+ .true.
+ .false.
+
+
+
logical
datm
diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml
index d4228d246..c29decdca 100644
--- a/datm/cime_config/stream_definition_datm.xml
+++ b/datm/cime_config/stream_definition_datm.xml
@@ -187,6 +187,17 @@
presndep.SSP5-8.5
presndep.cplhist
+ ========================
+ optional stream ozone (stream specified by xml variable DATM_PRESO3)
+ ========================
+ preso3.clim_1850
+ preso3.clim_2000
+ preso3.hist
+ preso3.SSP2-4.5
+ preso3.SSP3-7.0
+ preso3.SSP5-8.5
+
+
========================
optional stream topo (turned on and stream specified by xml variable DATM_TOPO)
========================
@@ -3999,6 +4010,273 @@
single
+
+
+ $DIN_LOC_ROOT/share/meshes/fv0.9x1.25_141008_polemod_ESMFmesh.nc
+
+
+ $DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/aero/aerodep_clm_SSP585_b.e21.BSSP585cmip6.f09_g17.CMIP6-SSP5-8.5.001_2014-2101_monthly_0.9x1.25_c190419.nc
+
+
+ BCDEPWET Faxa_bcphiwet
+ BCPHODRY Faxa_bcphodry
+ BCPHIDRY Faxa_bcphidry
+ OCDEPWET Faxa_ocphiwet
+ OCPHIDRY Faxa_ocphidry
+ OCPHODRY Faxa_ocphodry
+ DSTX01WD Faxa_dstwet1
+ DSTX01DD Faxa_dstdry1
+ DSTX02WD Faxa_dstwet2
+ DSTX02DD Faxa_dstdry2
+ DSTX03WD Faxa_dstwet3
+ DSTX03DD Faxa_dstdry3
+ DSTX04WD Faxa_dstwet4
+ DSTX04DD Faxa_dstdry4
+
+ null
+
+ bilinear
+
+ null
+ 2015
+ 2015
+ 2101
+ 0
+
+ linear
+
+
+ cycle
+
+
+ 1.5
+
+ single
+
+
+
+
+
+
+
+
+ $DIN_LOC_ROOT/share/meshes/fv0.9x1.25_141008_polemod_ESMFmesh.nc
+
+
+ $DIN_LOC_ROOT/cdeps/datm/ozone/O3_surface.f09_g17.CMIP6-historical-WACCM.001.monthly.185001-201412.nc
+
+
+ O3 Sa_o3
+
+ null
+
+ bilinear
+
+ null
+ 1
+ 1850
+ 1850
+ 0
+
+ linear
+
+
+ cycle
+
+
+ 1.5
+
+ single
+
+
+
+
+ $DIN_LOC_ROOT/share/meshes/fv0.9x1.25_141008_polemod_ESMFmesh.nc
+
+
+ $DIN_LOC_ROOT/cdeps/datm/ozone/O3_surface.f09_g17.CMIP6-historical-WACCM.001.monthly.185001-201412.nc
+
+
+ O3 Sa_o3
+
+ null
+
+ bilinear
+
+ null
+ 1
+ 2000
+ 2000
+ 0
+
+ linear
+
+
+ cycle
+
+
+ 1.5
+
+ single
+
+
+
+
+ $DIN_LOC_ROOT/share/meshes/fv0.9x1.25_141008_polemod_ESMFmesh.nc
+
+
+ $DIN_LOC_ROOT/cdeps/datm/ozone/O3_surface.f09_g17.CMIP6-historical-WACCM.001.monthly.185001-201412.nc
+
+
+ O3 Sa_o3
+
+ null
+
+ bilinear
+
+ null
+ 1
+ 2010
+ 2010
+ 0
+
+ linear
+
+
+ cycle
+
+
+ 1.5
+
+ single
+
+
+
+
+ $DIN_LOC_ROOT/share/meshes/fv0.9x1.25_141008_polemod_ESMFmesh.nc
+
+
+ $DIN_LOC_ROOT/cdeps/datm/ozone/O3_surface.f09_g17.CMIP6-historical-WACCM.001.monthly.185001-201412.nc
+
+
+ O3 Sa_o3
+
+ null
+
+ bilinear
+
+ null
+ 1850
+ 1850
+ 2014
+ 0
+
+ linear
+
+
+ cycle
+
+
+ 1.5
+
+ single
+
+
+
+
+ $DIN_LOC_ROOT/share/meshes/fv0.9x1.25_141008_polemod_ESMFmesh.nc
+
+
+ $DIN_LOC_ROOT/cdeps/datm/ozone/O3_surface.f09_g17.CMIP6-SSP2-4.5-WACCM.001.monthly.201501-210012.nc
+
+
+ O3 Sa_o3
+
+ null
+
+ bilinear
+
+ null
+ 2015
+ 2015
+ 2100
+ 0
+
+ linear
+
+
+ cycle
+
+
+ 1.5
+
+ single
+
+
+
+
+ $DIN_LOC_ROOT/share/meshes/fv0.9x1.25_141008_polemod_ESMFmesh.nc
+
+
+ $DIN_LOC_ROOT/cdeps/datm/ozone/O3_surface.f09_g17.CMIP6-SSP3-7.0-WACCM.001.monthly.201501-210012.nc
+
+
+ O3 Sa_o3
+
+ null
+
+ bilinear
+
+ null
+ 2015
+ 2015
+ 2100
+ 0
+
+ linear
+
+
+ cycle
+
+
+ 1.5
+
+ single
+
+
+
+
+ $DIN_LOC_ROOT/share/meshes/fv0.9x1.25_141008_polemod_ESMFmesh.nc
+
+
+ $DIN_LOC_ROOT/cdeps/datm/ozone/O3_surface.f09_g17.CMIP6-SSP5-8.5-WACCM.001.monthly.201501-210012.nc
+
+
+ O3 Sa_o3
+
+ null
+
+ bilinear
+
+ null
+ 2015
+ 2015
+ 2100
+ 0
+
+ linear
+
+
+ cycle
+
+
+ 1.5
+
+ single
+
+
+
+
@@ -4168,7 +4446,7 @@
$DIN_LOC_ROOT/share/meshes/fv0.9x1.25_141008_polemod_ESMFmesh.nc
- $DIN_LOC_ROOT/lnd/clm2/ndepdata/lnd/clm2/fndepdata/fndep_clm_f09_g17.CMIP6-SSP2-4.5-WACCM_1849-2101_monthly_c191007.nc
+ $DIN_LOC_ROOT/lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP2-4.5-WACCM_1849-2101_monthly_c191007.nc
NDEP_NHx_month Faxa_ndep_nhx
diff --git a/datm/datm_datamode_clmncep_mod.F90 b/datm/datm_datamode_clmncep_mod.F90
index 0c4619c01..6c376d902 100644
--- a/datm/datm_datamode_clmncep_mod.F90
+++ b/datm/datm_datamode_clmncep_mod.F90
@@ -36,6 +36,7 @@ module datm_datamode_clmncep_mod
real(r8), pointer :: Sa_dens(:) => null()
real(r8), pointer :: Sa_pbot(:) => null()
real(r8), pointer :: Sa_pslv(:) => null()
+ real(r8), pointer :: Sa_o3(:) => null()
real(r8), pointer :: Faxa_lwdn(:) => null()
real(r8), pointer :: Faxa_rainc(:) => null()
real(r8), pointer :: Faxa_rainl(:) => null()
@@ -113,7 +114,7 @@ module datm_datamode_clmncep_mod
!===============================================================================
subroutine datm_datamode_clmncep_advertise(exportState, fldsexport, flds_scalar_name, &
- flds_co2, flds_wiso, flds_presaero, flds_presndep, rc)
+ flds_co2, flds_wiso, flds_presaero, flds_presndep, flds_preso3, rc)
! input/output variables
type(esmf_State) , intent(inout) :: exportState
@@ -122,6 +123,7 @@ subroutine datm_datamode_clmncep_advertise(exportState, fldsexport, flds_scalar_
logical , intent(in) :: flds_wiso
logical , intent(in) :: flds_presaero
logical , intent(in) :: flds_presndep
+ logical , intent(in) :: flds_preso3
character(len=*) , intent(in) :: flds_scalar_name
integer , intent(out) :: rc
@@ -157,6 +159,9 @@ subroutine datm_datamode_clmncep_advertise(exportState, fldsexport, flds_scalar_
call dshr_fldList_add(fldsExport, 'Sa_co2prog')
call dshr_fldList_add(fldsExport, 'Sa_co2diag')
end if
+ if (flds_preso3) then
+ call dshr_fldList_add(fldsExport, 'Sa_o3')
+ end if
if (flds_presaero) then
call dshr_fldList_add(fldsExport, 'Faxa_bcph' , ungridded_lbound=1, ungridded_ubound=3)
call dshr_fldList_add(fldsExport, 'Faxa_ocph' , ungridded_lbound=1, ungridded_ubound=3)
@@ -309,6 +314,13 @@ subroutine datm_datamode_clmncep_init_pointers(importState, exportState, sdat, r
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
+ call ESMF_StateGet(exportstate, 'Sa_o3', itemFlag, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ if (itemflag /= ESMF_STATEITEM_NOTFOUND) then
+ call dshr_state_getfldptr(exportState, 'Sa_o3', fldptr1=Sa_o3, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ end if
+
! error check
if (.not. associated(strm_wind) .or. .not. associated(strm_tbot)) then
call shr_sys_abort(trim(subname)//' ERROR: wind and tbot must be in streams for CLMNCEP')
diff --git a/streams/dshr_stream_mod.F90 b/streams/dshr_stream_mod.F90
index 3075845ee..301718133 100644
--- a/streams/dshr_stream_mod.F90
+++ b/streams/dshr_stream_mod.F90
@@ -1718,9 +1718,11 @@ subroutine shr_stream_restIO(pioid, streams, mode)
rcode = pio_def_dim(pioid, 'strlen', CL, dimid_str)
do k=1,size(streams)
+ ! maxnfiles is the maximum number of files across all streams
if (streams(k)%nfiles > maxnfiles) then
maxnfiles = streams(k)%nfiles
endif
+ ! maxnt is the maximum number of time samples across all possible stream files
do n=1,streams(k)%nFiles
if( streams(k)%file(n)%nt > maxnt) then
maxnt = streams(k)%file(n)%nt