diff --git a/bld/build-namelist b/bld/build-namelist index 17781990b1..0063c23985 100755 --- a/bld/build-namelist +++ b/bld/build-namelist @@ -706,10 +706,35 @@ if (!($simple_phys or $aqua_mode)) { add_default($nl, 'stream_ndep_year_first' , 'sim_year'=>$sim_year); add_default($nl, 'stream_ndep_year_last' , 'sim_year'=>$sim_year); add_default($nl, 'stream_ndep_year_align' , 'sim_year'=>$sim_year); + add_default($nl, 'stream_ndep_taxmode' , 'sim_year'=>$sim_year); add_default($nl, 'stream_ndep_varlist'); } } +# Setup default co2 surface source stream only if not simple_phys or aqua_mode and +# the chemistry cannot produce the nitrogen depostion fluxes +if (!($simple_phys or $aqua_mode)) { + add_default($nl, 'co2_surface_source'); + if ($nl->get_value('co2_surface_source') =~ /$TRUE/io) { + if ( !(defined $nl->get_value('stream_co2_surface_source_mesh_filename') and + defined $nl->get_value('stream_co2_surface_source_data_filename') and + defined $nl->get_value('stream_co2_surface_source_data_varname') and + defined $nl->get_value('stream_co2_surface_source_year_first') and + defined $nl->get_value('stream_co2_surface_source_year_last') and + defined $nl->get_value('stream_co2_surface_source_year_align') and + defined $nl->get_value('stream_co2_surface_source_taxmode') ) ) { + die "$ProgName - ERROR: if co2_surface_source is .true. then the following must be defined: + stream_co2_surface_source_mesh_filename, + stream_co2_surface_source_data_filename, + stream_co2_surface_source_data_varname, + stream_co2_surface_source_taxmode, + stream_co2_surface_source_year_first, + stream_co2_surface_source_year_last, + stream_co2_surface_source_year_align\n"; + } + } +} + # Topography add_default($nl, 'use_topo_file'); my $use_topo_file = $nl->get_value('use_topo_file'); diff --git a/bld/namelist_files/namelist_defaults_cam.xml b/bld/namelist_files/namelist_defaults_cam.xml index 0978e20a28..d624c4d985 100644 --- a/bld/namelist_files/namelist_defaults_cam.xml +++ b/bld/namelist_files/namelist_defaults_cam.xml @@ -2010,6 +2010,9 @@ atm/cam/dst/dst_source2x2tuned-cam4-06132012.nc atm/cam/dst/dst_source1x1tuned-cam4-06202012.nc + +.false. + NDEP_NHx_month:NDEP_NOy_month drynhx:wetnhx:drynoy:wetnoy @@ -2032,8 +2035,11 @@ 2022 2010 +cycle +extend + 1 -1850 +1850 .false. diff --git a/bld/namelist_files/namelist_definition.xml b/bld/namelist_files/namelist_definition.xml index 09471b0ec4..f42ac6f4a6 100644 --- a/bld/namelist_files/namelist_definition.xml +++ b/bld/namelist_files/namelist_definition.xml @@ -8256,6 +8256,14 @@ calendar is setup to span the same year range as the forcing data. Set by build-namelist. Default: 1 + +Time extrapolation algorithm to use for nitrogen deposition. +- cycle: Simply cycle through the available model data (i.e., start over when the end is reached) +- extend: Use the final value when end of data is reached. +- limit: Halt the model run if the model time exceeds the available data. +Default: extend for transient, otherwise cycle + @@ -8264,7 +8272,7 @@ Nitrogen deposition stream data filename. -Grid mesh file corresponding to sream_ndep_data_filename. +Grid mesh file corresponding to stream_ndep_data_filename. + + + + If TRUE, set co2_diag sent to land and ocean to value read from co2_surface_source_data_filename + Default: FALSE + + + Grid mesh file corresponding to stream_co2_surface_source_data_filename. + Must be set by user. + + + Data source file for reading CO2 concentrations to be passed to the surface if co2_surface_source=.true. + Must be set by user. + + + Variable name for reading CO2 concentrations in stream_co2_surface_source_data_filename. + Must be set by user. + + + Time extrapolation algorithm to use for CO2 surface stream data. + - cycle: Simply cycle through the available model data (i.e., start over when the end is reached) + - extend: Use the final value when end of data is reached. + - limit: Halt the model run if the model time exceeds the available data. + Must be set by user. + + + First year to use in CO2 surface stream data. + Must be set by user. + + + Last year to use in CO2 surface stream data. + Must be set by user. + + + The simulation year corresponding to stream_co2_surface_source_year_first. + A common usage is to set this to the first year of the model run + (corresponding to the xml variable RUN_STARTDATE). With this setting, + the forcing in the first year of the run will be the forcing of year + yearFirst. + Another usage is to align the calendar of transient forcing with the + model calendar. For example, setting yearAlign = yearFirst will lead + to the forcing calendar being the same as the model calendar. The + forcing for a given model year would be the forcing of the same + year. This would be appropriate in transient runs where the model + calendar is setup to span the same year range as the forcing data. + Must be set by user. + + diff --git a/src/control/runtime_opts.F90 b/src/control/runtime_opts.F90 index 8fab0c6b20..6186bf2a8a 100644 --- a/src/control/runtime_opts.F90 +++ b/src/control/runtime_opts.F90 @@ -104,6 +104,7 @@ subroutine read_namelist(nlfilename, single_column, scmlat, scmlon) use surface_emissions_mod, only: surface_emissions_readnl use elevated_emissions_mod, only: elevated_emissions_readnl use atm_stream_ndep, only: stream_ndep_readnl + use atm_stream_co2, only: stream_co2_surface_source_readnl !---------------------------Arguments----------------------------------- @@ -209,6 +210,7 @@ subroutine read_namelist(nlfilename, single_column, scmlat, scmlon) call surface_emissions_readnl(nlfilename) call elevated_emissions_readnl(nlfilename) call stream_ndep_readnl(nlfilename) + call stream_co2_surface_source_readnl(nlfilename) end subroutine read_namelist diff --git a/src/cpl/nuopc/atm_import_export.F90 b/src/cpl/nuopc/atm_import_export.F90 index 48b253ba6f..fbf7de8377 100644 --- a/src/cpl/nuopc/atm_import_export.F90 +++ b/src/cpl/nuopc/atm_import_export.F90 @@ -28,6 +28,8 @@ module atm_import_export use chemistry , only : chem_has_ndep_flx use cam_control_mod , only : aqua_planet, simple_phys use cam_esmf_mod , only : cam_esmf_set_areas + use atm_stream_co2 , only : stream_co2_surface_source_init, stream_co2_surface_source_interp + use atm_stream_co2 , only : stream_co2_surface_source_is_initialized, co2_surface_source implicit none private ! except @@ -1227,6 +1229,16 @@ subroutine export_fields(gcomp, cam_out, rc) call state_getfldptr(exportState, 'Sa_co2diag', fldptr=fldptr_co2diag, exists=exists, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (exists) then + ! if co2_surface_source is a filename - use this to overwrite co2_diag + if (co2_surface_source) then + if (.not. stream_co2_surface_source_is_initialized) then + call stream_co2_surface_source_init(rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + call stream_co2_surface_source_interp(cam_out, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + g = 1 do c = begchunk,endchunk do i = 1,get_ncols_p(c) diff --git a/src/cpl/nuopc/atm_stream_co2.F90 b/src/cpl/nuopc/atm_stream_co2.F90 new file mode 100644 index 0000000000..c6f8d6e178 --- /dev/null +++ b/src/cpl/nuopc/atm_stream_co2.F90 @@ -0,0 +1,257 @@ +module atm_stream_co2 + + !----------------------------------------------------------------------- + ! Contains methods for reading in co2_surface_source deposition data file + ! Also includes functions for dynamic co2_surface_source file handling and + ! interpolation. + !----------------------------------------------------------------------- + ! + use ESMF , only : ESMF_SUCCESS + use nuopc_shr_methods , only : chkerr + use dshr_strdata_mod , only : shr_strdata_type + use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_cl, CS => shr_kind_cs + use shr_log_mod , only : errMsg => shr_log_errMsg + use spmd_utils , only : mpicom, masterproc, iam, masterprocid + use spmd_utils , only : mpi_character, mpi_integer, mpi_logical + use cam_logfile , only : iulog + use cam_abortutils , only : endrun + use cam_esmf_mod , only : model_clock, model_mesh + + implicit none + private + + public :: stream_co2_surface_source_readnl ! read runtime options + public :: stream_co2_surface_source_init ! position datasets for dynamic co2_surface_source + public :: stream_co2_surface_source_interp ! interpolates between two years of co2_surface_source file data + + type(shr_strdata_type) :: sdat_co2_surface_source ! input data stream + + ! namelist variables + character(len=CL) :: stream_co2_surface_source_mesh_filename + character(len=CL) :: stream_co2_surface_source_data_filename + character(len=CL) :: stream_co2_surface_source_data_varname ! variable name for co2_surface_source on stream file(s) + character(len=CS) :: stream_co2_surface_source_taxmode ! 'cycle' or 'extend' or 'limit' + integer :: stream_co2_surface_source_year_first ! first year in stream to use + integer :: stream_co2_surface_source_year_last ! last year in stream to use + integer :: stream_co2_surface_source_year_align ! align stream_year_first + + logical, public, protected :: co2_surface_source + logical, public, protected :: stream_co2_surface_source_is_initialized = .false. + + character(len=*), parameter :: u_FILE_u = __FILE__ + +!============================================================================== +contains +!============================================================================== + + subroutine stream_co2_surface_source_readnl(nlfile) + + ! Uses: + use shr_nl_mod, only: shr_nl_find_group_name + + ! input/output variables + character(len=*), intent(in) :: nlfile + + ! local variables + integer :: nu_nml ! unit for namelist file + integer :: nml_error ! namelist i/o error flag + integer :: ierr ! error status + integer :: nf ! field counter + character(len=*), parameter :: subName = "('stream_co2_surface_source_readnl')" + !----------------------------------------------------------------------- + + namelist /co2_surface_source_stream_nl/ & + co2_surface_source, & + stream_co2_surface_source_mesh_filename, & + stream_co2_surface_source_data_filename, & + stream_co2_surface_source_data_varname, & + stream_co2_surface_source_taxmode, & + stream_co2_surface_source_year_first, & + stream_co2_surface_source_year_last, & + stream_co2_surface_source_year_align + + ! Default values for namelist + co2_surface_source = .false. + stream_co2_surface_source_data_filename = ' ' + stream_co2_surface_source_mesh_filename = ' ' + stream_co2_surface_source_data_varname = ' ' + stream_co2_surface_source_taxmode = 'unset' + stream_co2_surface_source_year_first = -999 ! first year in stream to use + stream_co2_surface_source_year_last = -999 ! last year in stream to use + stream_co2_surface_source_year_align = -999 ! align stream_co2_surface_source_year_first with this model year + + ! Read co2_surface_source_stream namelist + if (masterproc) then + open( newunit=nu_nml, file=trim(nlfile), status='old', iostat=nml_error ) + if (nml_error /= 0) then + call endrun(subName//': ERROR opening '//trim(nlfile)//errMsg(u_FILE_u, __LINE__)) + end if + call shr_nl_find_group_name(nu_nml, 'co2_surface_source_stream_nl', status=nml_error) + if (nml_error == 0) then + read(nu_nml, nml=co2_surface_source_stream_nl, iostat=nml_error) + if (nml_error /= 0) then + call endrun(' ERROR reading co2_surface_source_stream_nl namelist'//errMsg(u_FILE_u, __LINE__)) + end if + end if + close(nu_nml) + + ! Error check + if (co2_surface_source) then + if ( trim(stream_co2_surface_source_taxmode) /= 'cycle' .and. & + trim(stream_co2_surface_source_taxmode) /= 'extend' .and. & + trim(stream_co2_surface_source_taxmode) /= 'limit') then + call endrun(subName//': ERROR stream_co2_surface_source_taxmode ' & + //trim(stream_co2_surface_source_taxmode) & + //' must be either cycle, extend or limit') + end if + end if + end if + + call mpi_bcast(co2_surface_source, 1, mpi_logical, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: co2_surface_source") + + if (co2_surface_source) then + call mpi_bcast(stream_co2_surface_source_mesh_filename, & + len(stream_co2_surface_source_mesh_filename), mpi_character, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_co2_surface_source_mesh_filename") + call mpi_bcast(stream_co2_surface_source_data_filename, & + len(stream_co2_surface_source_data_filename), mpi_character, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_co2_surface_source_data_filename") + call mpi_bcast(stream_co2_surface_source_data_varname, & + len(stream_co2_surface_source_data_varname), mpi_character, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_co2_surface_source_data_varname") + call mpi_bcast(stream_co2_surface_source_taxmode, & + len(stream_co2_surface_source_taxmode), mpi_character, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_co2_surface_source_taxmode") + call mpi_bcast(stream_co2_surface_source_year_first, & + 1, mpi_integer, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_co2_surface_source_year_first") + call mpi_bcast(stream_co2_surface_source_year_last, & + 1, mpi_integer, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_co2_surface_source_year_last") + call mpi_bcast(stream_co2_surface_source_year_align, & + 1, mpi_integer, masterprocid, mpicom, ierr) + end if + + if (masterproc) then + write(iulog,'(a)') ' ' + if (co2_surface_source) then + write(iulog,'(2a)') subname,' co2 surface source override settings::' + write(iulog,'(3a)') subname,' stream_co2_surface_source_data_filename = ',& + trim(stream_co2_surface_source_data_filename) + write(iulog,'(3a)') subname,' stream_co2_surface_source_mesh_filename = ',& + trim(stream_co2_surface_source_mesh_filename) + write(iulog,'(3a)') subname,' stream_co2_surface_source_data_varname = ',& + trim(stream_co2_surface_source_data_varname) + write(iulog,'(3a)') subname,' stream_co2_surface_source_taxmode = ',& + trim(stream_co2_surface_source_taxmode) + write(iulog,'(2a,i0)') subname,' stream_co2_surface_source_year_first = ',& + stream_co2_surface_source_year_first + write(iulog,'(2a,i0)') subname,' stream_co2_surface_source_year_last = ',& + stream_co2_surface_source_year_last + write(iulog,'(2a,i0)') subname,' stream_co2_surface_source_year_align = ',& + stream_co2_surface_source_year_align + write(iulog,'(a)') ' ' + else + write(iulog, '(2a)') subname, 'co2 surface source will not be overwritten' + end if + end if + + end subroutine stream_co2_surface_source_readnl + + !================================================================ + subroutine stream_co2_surface_source_init(rc) + use dshr_strdata_mod, only: shr_strdata_init_from_inline + + ! input/output variables + integer, intent(out) :: rc + + ! local variables + character(len=*), parameter :: subName = "('stream_co2_surface_source_init')" + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (co2_surface_source .and. .not. stream_co2_surface_source_is_initialized) then + ! Initialize the cdeps data type sdat_co2_surface_source + call shr_strdata_init_from_inline(sdat_co2_surface_source, & + my_task = iam, & + logunit = iulog, & + compname = 'ATM', & + model_clock = model_clock, & + model_mesh = model_mesh, & + stream_meshfile = trim(stream_co2_surface_source_mesh_filename), & + stream_filenames = (/trim(stream_co2_surface_source_data_filename)/), & + stream_yearFirst = stream_co2_surface_source_year_first, & + stream_yearLast = stream_co2_surface_source_year_last, & + stream_yearAlign = stream_co2_surface_source_year_align, & + stream_fldlistFile = (/stream_co2_surface_source_data_varname/), & + stream_fldListModel = (/stream_co2_surface_source_data_varname/), & + stream_lev_dimname = 'null', & + stream_mapalgo = 'bilinear', & + stream_offset = 0, & + stream_taxmode = trim(stream_co2_surface_source_taxmode), & + stream_dtlimit = 1.0e30_r8, & + stream_tintalgo = 'linear', & + stream_name = 'CO2_SURFACE_SOURCE data ', & + rc = rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + stream_co2_surface_source_is_initialized = .true. + end if + + end subroutine stream_co2_surface_source_init + + !================================================================ + subroutine stream_co2_surface_source_interp(cam_out, rc) + + use dshr_methods_mod , only : dshr_fldbun_getfldptr + use dshr_strdata_mod , only : shr_strdata_advance + use camsrfexch , only : cam_out_t + use ppgrid , only : begchunk, endchunk + use time_manager , only : get_curr_date + use phys_grid , only : get_ncols_p + + ! input/output variables + type(cam_out_t) , intent(inout) :: cam_out(begchunk:endchunk) + integer , intent(out) :: rc + + ! local variables + integer :: ig,icol,lchnk + integer :: year ! year (0, ...) for nstep+1 + integer :: mon ! month (1, ..., 12) for nstep+1 + integer :: day ! day of month (1, ..., 31) for nstep+1 + integer :: sec ! seconds into current date for nstep+1 + integer :: mcdate ! Current model date (yyyymmdd) + real(r8), pointer :: dataptr1d(:) + character(len=*), parameter :: subName = "('stream_co2_surface_source_interp')" + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Advance co2_surface_source sdat stream + call get_curr_date(year, mon, day, sec) + mcdate = year*10000 + mon*100 + day + call shr_strdata_advance(sdat_co2_surface_source, ymd=mcdate, tod=sec, logunit=iulog, & + istr='co2_surface_source_diag', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get pointer for stream data that is time and spatially interpolated to model time and grid + call dshr_fldbun_getFldPtr(sdat_co2_surface_source%pstrm(1)%fldbun_model, & + stream_co2_surface_source_data_varname, fldptr1=dataptr1d, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Set output diagnostic co2_surface_source + ! Input data is in [mol/mol] but land and ocean expect to receive [ppm]. + ! Unit conversion is to multiply by 1e6. + ig = 1 + do lchnk = begchunk,endchunk + do icol = 1,get_ncols_p(lchnk) + cam_out(lchnk)%co2diag(icol) = dataptr1d(ig) * 1.0e6_r8 + ig = ig + 1 + end do + end do + + end subroutine stream_co2_surface_source_interp + +end module atm_stream_co2 diff --git a/src/cpl/nuopc/atm_stream_ndep.F90 b/src/cpl/nuopc/atm_stream_ndep.F90 index b72a598444..03fb8a89c0 100644 --- a/src/cpl/nuopc/atm_stream_ndep.F90 +++ b/src/cpl/nuopc/atm_stream_ndep.F90 @@ -13,7 +13,7 @@ module atm_stream_ndep use dshr_strdata_mod , only : shr_strdata_type use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_cl, CS => shr_kind_cs use shr_log_mod , only : errMsg => shr_log_errMsg - use spmd_utils , only : mpicom, masterproc, iam + use spmd_utils , only : mpicom, masterproc, iam, masterprocid use spmd_utils , only : mpi_character, mpi_integer use cam_logfile , only : iulog use cam_abortutils , only : endrun @@ -41,6 +41,7 @@ module atm_stream_ndep character(len=CL) :: stream_ndep_data_filename character(len=CL) :: stream_ndep_mesh_filename character(len=CL) :: stream_ndep_varlist ! colon delimited string of ndep field names + character(len=CS) :: stream_ndep_taxmode ! time extrapolation - 'cycle','limit' or 'extend' integer :: stream_ndep_year_first ! first year in stream to use integer :: stream_ndep_year_last ! last year in stream to use integer :: stream_ndep_year_align ! align stream_year_firstndep with @@ -67,7 +68,7 @@ subroutine stream_ndep_readnl(nlfile) integer :: ierr ! error status integer :: nf ! field counter integer :: numflds ! number of fields in stream_ndep_varlist - character(*), parameter :: subName = "('stream_ndep_readnl')" + character(len=*), parameter :: subName = "('stream_ndep_readnl')" !----------------------------------------------------------------------- namelist /ndep_stream_nl/ & @@ -76,12 +77,14 @@ subroutine stream_ndep_readnl(nlfile) stream_ndep_year_first, & stream_ndep_year_last, & stream_ndep_year_align, & - stream_ndep_varlist + stream_ndep_varlist, & + stream_ndep_taxmode ! Default values for namelist stream_ndep_data_filename = ' ' stream_ndep_mesh_filename = ' ' stream_ndep_varlist = ' ' + stream_ndep_taxmode = 'unset' stream_ndep_year_first = 1 ! first year in stream to use stream_ndep_year_last = 1 ! last year in stream to use stream_ndep_year_align = 1 ! align stream_ndep_year_first with this model year @@ -101,23 +104,11 @@ subroutine stream_ndep_readnl(nlfile) end if close(nu_nml) endif - call mpi_bcast(stream_ndep_mesh_filename, len(stream_ndep_mesh_filename), mpi_character, 0, mpicom, ierr) - if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_ndep_mesh_filename") - call mpi_bcast(stream_ndep_data_filename, len(stream_ndep_data_filename), mpi_character, 0, mpicom, ierr) - if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_ndep_data_filename") - call mpi_bcast(stream_ndep_varlist, len(stream_ndep_varlist), mpi_character, 0, mpicom, ierr) - if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_ndep_varlist") - call mpi_bcast(stream_ndep_year_first, 1, mpi_integer, 0, mpicom, ierr) - if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_ndep_year_first") - call mpi_bcast(stream_ndep_year_last, 1, mpi_integer, 0, mpicom, ierr) - if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_ndep_year_last") - call mpi_bcast(stream_ndep_year_align, 1, mpi_integer, 0, mpicom, ierr) - if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_ndep_year_align") ! Determine if ndep stream is active, and if not return + call mpi_bcast(stream_ndep_data_filename, len(stream_ndep_data_filename), mpi_character, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_ndep_data_filename") ndep_stream_active = (len_trim(stream_ndep_data_filename)>0 .and. stream_ndep_data_filename/='UNSET') - - ! Check whether the stream is being used. if (.not. ndep_stream_active) then if (masterproc) then write(iulog,'(a)') ' ' @@ -127,6 +118,29 @@ subroutine stream_ndep_readnl(nlfile) RETURN endif + ! Broadcast remaining namelist variables + call mpi_bcast(stream_ndep_mesh_filename, len(stream_ndep_mesh_filename), mpi_character, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_ndep_mesh_filename") + call mpi_bcast(stream_ndep_varlist, len(stream_ndep_varlist), mpi_character, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_ndep_varlist") + call mpi_bcast(stream_ndep_taxmode, len(stream_ndep_taxmode), mpi_character, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_ndep_taxmode") + call mpi_bcast(stream_ndep_year_first, 1, mpi_integer, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_ndep_year_first") + call mpi_bcast(stream_ndep_year_last, 1, mpi_integer, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_ndep_year_last") + call mpi_bcast(stream_ndep_year_align, 1, mpi_integer, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun(trim(subname)//": FATAL: mpi_bcast: stream_ndep_year_align") + + ! error check + if ( trim(stream_ndep_taxmode) /= 'cycle' .and. & + trim(stream_ndep_taxmode) /= 'extend' .and. & + trim(stream_ndep_taxmode) /= 'limit') then + call endrun(subName//': ERROR stream_ndep_taxmode '& + //trim(stream_ndep_taxmode) & + //' must be either cycle, extend or limit') + end if + ! Create array of variable names on ndep forcing file - needed to initialize sdat numflds = shr_string_listGetNum(stream_ndep_varlist) allocate(stream_ndep_varnames(numflds), stat=ierr) @@ -157,7 +171,7 @@ subroutine stream_ndep_init(rc) integer, intent(out) :: rc ! local variables - character(*), parameter :: subName = "('stream_ndep_init')" + character(len=*), parameter :: subName = "('stream_ndep_init')" !----------------------------------------------------------------------- rc = ESMF_SUCCESS @@ -185,7 +199,7 @@ subroutine stream_ndep_init(rc) stream_lev_dimname = 'null', & stream_mapalgo = 'bilinear', & stream_offset = 0, & - stream_taxmode = 'cycle', & + stream_taxmode = trim(stream_ndep_taxmode), & stream_dtlimit = 1.0e30_r8, & stream_tintalgo = 'linear', & stream_name = 'Nitrogen deposition data ', & @@ -219,7 +233,7 @@ subroutine stream_ndep_check_units( stream_fldFileName_ndep) integer :: ierr ! error status integer :: err_handling ! temporary character(len=CS) :: ndepunits ! ndep units - character(*), parameter :: subName = "('stream_ndep_check_units')" + character(len=*), parameter :: subName = "('stream_ndep_check_units')" !----------------------------------------------------------------------- call cam_pio_openfile( fileid, trim(stream_fldFileName_ndep), PIO_NOWRITE) @@ -280,7 +294,7 @@ subroutine stream_ndep_interp(cam_out, rc) real(r8), pointer :: dataptr1d_nhx_wet(:) real(r8), pointer :: dataptr1d_noy_dry(:) real(r8), pointer :: dataptr1d_noy_wet(:) - character(*), parameter :: subName = "('stream_ndep_interp')" + character(len=*), parameter :: subName = "('stream_ndep_interp')" !----------------------------------------------------------------------- rc = ESMF_SUCCESS diff --git a/src/utils/cam_pio_utils.F90 b/src/utils/cam_pio_utils.F90 index 788957869a..1977faf9a3 100644 --- a/src/utils/cam_pio_utils.F90 +++ b/src/utils/cam_pio_utils.F90 @@ -1144,7 +1144,7 @@ subroutine cam_pio_openfile(file, fname, mode, errcode) end if if(pio_iotask_rank(pio_subsystem) == 0) then - write(iulog,*) 'Opening existing file ', trim(fname), file%fh + write(iulog,'(a,2x,a,4x,i0)') 'Opening existing file ', trim(fname), file%fh end if ierr = pio_openfile(pio_subsystem, file, pio_iotype, fname, mode)