diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 8d9a4835c..dbd441085 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -219,7 +219,7 @@ end subroutine SetServices !=============================================================================== subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) - + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(ESMF_GridComp) :: gcomp type(ESMF_State) :: importState, exportState @@ -276,6 +276,11 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (my_task == main_task) then nlfilename = "datm_in"//trim(inst_suffix) open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'datm_nml', status=ierr) + if (ierr > 0) then + write(logunit,*) 'ERROR: reading input namelist, '//trim(nlfilename)//' iostat=',ierr + call shr_sys_abort(subName//': namelist read error '//trim(nlfilename)) + end if read (nu,nml=datm_nml,iostat=ierr) close(nu) if (ierr > 0) then diff --git a/datm/datm_datamode_simple_mod.F90 b/datm/datm_datamode_simple_mod.F90 index 9d670dbea..ca978c153 100644 --- a/datm/datm_datamode_simple_mod.F90 +++ b/datm/datm_datamode_simple_mod.F90 @@ -89,6 +89,7 @@ module datm_datamode_simple_mod subroutine datm_datamode_simple_advertise(exportState, fldsexport, flds_scalar_name, & nlfilename, my_task, vm, rc) + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(esmf_State) , intent(inout) :: exportState @@ -116,6 +117,7 @@ subroutine datm_datamode_simple_advertise(exportState, fldsexport, flds_scalar_n ! Read const_forcing_nml from nlfilename if (my_task == main_task) then open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'const_forcing_nml', status=ierr) read (nu,nml=const_forcing_nml,iostat=ierr) close(nu) if (ierr > 0) then diff --git a/dice/ice_comp_nuopc.F90 b/dice/ice_comp_nuopc.F90 index ba368983d..fd552bbcb 100644 --- a/dice/ice_comp_nuopc.F90 +++ b/dice/ice_comp_nuopc.F90 @@ -160,6 +160,7 @@ end subroutine SetServices !=============================================================================== subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(ESMF_GridComp) :: gcomp @@ -206,6 +207,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (my_task == main_task) then nlfilename = "dice_in"//trim(inst_suffix) open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'dice_nml', status=ierr) + read (nu,nml=dice_nml,iostat=ierr) close(nu) if (ierr > 0) then diff --git a/dlnd/lnd_comp_nuopc.F90 b/dlnd/lnd_comp_nuopc.F90 index df901dd0c..ff84bae05 100644 --- a/dlnd/lnd_comp_nuopc.F90 +++ b/dlnd/lnd_comp_nuopc.F90 @@ -157,6 +157,7 @@ end subroutine SetServices !=============================================================================== subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(ESMF_GridComp) :: gcomp @@ -198,6 +199,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (my_task == main_task) then nlfilename = "dlnd_in"//trim(inst_suffix) open (newunit=nu, file=trim(nlfilename), status="old", action="read") + call shr_nl_find_group_name(nu, 'dlnd_nml', status=ierr) + read (nu,nml=dlnd_nml,iostat=ierr) close(nu) if (ierr > 0) then diff --git a/docn/ocn_comp_nuopc.F90 b/docn/ocn_comp_nuopc.F90 index 14b2b6d3c..462989995 100644 --- a/docn/ocn_comp_nuopc.F90 +++ b/docn/ocn_comp_nuopc.F90 @@ -178,7 +178,7 @@ end subroutine SetServices !=============================================================================== subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) - + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(ESMF_GridComp) :: gcomp type(ESMF_State) :: importState, exportState @@ -224,6 +224,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Read docn_nml from nlfilename nlfilename = "docn_in"//trim(inst_suffix) open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'docn_nml', status=ierr) read (nu,nml=docn_nml,iostat=ierr) close(nu) if (ierr > 0) then diff --git a/drof/rof_comp_nuopc.F90 b/drof/rof_comp_nuopc.F90 index f2172e7c5..c3602cd97 100644 --- a/drof/rof_comp_nuopc.F90 +++ b/drof/rof_comp_nuopc.F90 @@ -153,7 +153,7 @@ end subroutine SetServices !=============================================================================== subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) - + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(ESMF_GridComp) :: gcomp type(ESMF_State) :: importState, exportState @@ -195,6 +195,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (mainproc) then nlfilename = "drof_in"//trim(inst_suffix) open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'drof_nml', status=ierr) read (nu,nml=drof_nml,iostat=ierr) close(nu) if (ierr > 0) then diff --git a/dwav/wav_comp_nuopc.F90 b/dwav/wav_comp_nuopc.F90 index 665aeb8d8..e200e00b6 100644 --- a/dwav/wav_comp_nuopc.F90 +++ b/dwav/wav_comp_nuopc.F90 @@ -151,6 +151,7 @@ end subroutine SetServices !=============================================================================== subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(ESMF_GridComp) :: gcomp @@ -192,6 +193,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (my_task == main_task) then nlfilename = "dwav_in"//trim(inst_suffix) open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'dwav_nml', status=ierr) read (nu,nml=dwav_nml,iostat=ierr) close(nu) if (ierr > 0) then diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt index 215847dae..fa5f4844e 100644 --- a/share/CMakeLists.txt +++ b/share/CMakeLists.txt @@ -5,6 +5,7 @@ set (GenF90_SRCS shr_infnan_mod.F90 shr_assert_mod.F90) add_library(cdeps_share ${GenF90_SRCS} + shr_nl_mod.F90 glc_elevclass_mod.F90 shr_timer_mod.F90 shr_cal_mod.F90 diff --git a/share/shr_nl_mod.F90 b/share/shr_nl_mod.F90 new file mode 100644 index 000000000..f06f2185c --- /dev/null +++ b/share/shr_nl_mod.F90 @@ -0,0 +1,88 @@ +module shr_nl_mod + +! Utilities for namelist reading +! Adapted Fall 2012 from CAM's namelist_utils. + +implicit none +private + +save + +public :: & + shr_nl_find_group_name ! seek through a file to find a specified namelist + +contains + +! This routine probably discards more error code information than it needs to. + +subroutine shr_nl_find_group_name(unit, group, status) + + use shr_string_mod, only: shr_string_toLower + +!--------------------------------------------------------------------------------------- +! Purpose: +! Search a file that contains namelist input for the specified namelist group name. +! Leave the file positioned so that the current record is the first record of the +! input for the specified group. +! +! Method: +! Read the file line by line. Each line is searched for an '&' which may only +! be preceded by blanks, immediately followed by the group name which is case +! insensitive. If found then backspace the file so the current record is the +! one containing the group name and return success. Otherwise return -1. +! +! Author: B. Eaton, August 2007 +!--------------------------------------------------------------------------------------- + + integer, intent(in) :: unit ! fortran unit attached to file + character(len=*), intent(in) :: group ! namelist group name + integer, intent(out) :: status ! 0 for success, -1 if group name not found + + ! Local variables + + integer :: len_grp + integer :: ios ! io status + character(len=80) :: inrec ! first 80 characters of input record + character(len=80) :: inrec2 ! left adjusted input record + character(len=len(group)) :: lc_group + + !--------------------------------------------------------------------------- + + len_grp = len_trim(group) + lc_group = shr_string_toLower(group) + + ios = 0 + do while (ios <= 0) + + read(unit, '(a)', iostat=ios, end=100) inrec + + if (ios <= 0) then ! ios < 0 indicates an end of record condition + + ! look for group name in this record + + ! remove leading blanks + inrec2 = adjustl(inrec) + + ! check for leading '&' + if (inrec2(1:1) == '&') then + + ! check for case insensitive group name + if (trim(lc_group) == shr_string_toLower(inrec2(2:len_grp+1))) then + + ! found group name. backspace to leave file position at this record + backspace(unit) + status = 0 + return + + end if + end if + end if + + end do + + 100 continue ! end of file processing + status = -1 + +end subroutine shr_nl_find_group_name + +end module shr_nl_mod