!=============================================================================== ! SVN $Id: shr_alarm_mod.F90 239 2006-02-08 19:02:33Z kauff $ ! SVN $URL: https://svn-ccsm-models.cgd.ucar.edu/csm_share/trunk/shr/shr_alarm_mod.F90 $ !=============================================================================== !BOP =========================================================================== ! ! !MODULE: shr_ncio_mod.F90 --- Module to handle reading and writing of NetCDF data ! ! !DESCRIPTION: ! ! A module to handle the reading and writing of scalar data to NetCDF files for the ! purpose of storing scalar netCDF data in either: integer, character, or logical format. ! ! Typical usage: ! ! ! Initialize a descripVar ! call shr_ncio_descripInit( DescripVar(n), Name="T", LongName= & ! "Globally averaged Temperature of surface", & ! Units="K", RealR8Data=.true., RealR8Fill=1.e+36 ) ! ! Read in the file ! FileType="glob avg T file" ! call shr_ncio_open( NCFileName, MasterTask, FileType, ncId, exists ) ! call shr_ncio_descripRead( ncId, nVars, mpicom, MasterTask, DescripVar ) ! ! Do any other NetCDF reading on ncID.... !... ! call shr_ncio_close( ncId, MasterTask, NCFilename, type=FileType ) ! ! Return the name of the descripVar ! name = shr_ncio_descripName( DescripVar(n) ) ! ! Get the data inside the variable ! glob_t = shr_ncio_descripGetRealR8( DescripVar(n) ) ! ! Now set the scalar data of the variable ! call shr_ncio_descripSet( DescriptVar(n), Name="T", RealR8Data=glob_avg_t ) ! ! Write the scalar data to a file ! FileType="glob avg T file" ! call shr_ncio_open( NCFileName, MasterTask, FileType, ncId, exists ) ! call shr_ncio_descripWrite( ncId, nVars, mpicom, MasterTask, exists, DescripVar ) ! ! Do any other NetCDF writing on ncID.... !... ! call shr_ncio_close( ncId, MasterTask, NCFilename, FileType ) ! ! !REMARKS: ! ! !REVISION HISTORY: ! 2005-Dec-20 - E. Kluzek - creation ! ! !INTERFACE: ------------------------------------------------------------------ MODULE shr_ncio_mod 7,5 ! !USES: use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_IN, & SHR_KIND_R8, SHR_KIND_I8, & SHR_KIND_R8 use shr_sys_mod, only: shr_sys_flush use shr_const_mod, only: shr_const_spval use shr_log_mod, only: s_loglev => shr_log_Level use shr_log_mod, only: s_logunit => shr_log_Unit use netcdf implicit none private ! default private ! !PUBLIC TYPES: public :: shr_ncio_descripType ! NetCDF data description type ! !PUBLIC MEMBER FUNCTIONS public :: shr_ncio_descripSetDefault ! Set list of descrip variables to default settings public :: shr_ncio_descripInit ! Setup variable and variable Names and types public :: shr_ncio_descripPutData ! Set a variable with data public :: shr_ncio_descripName ! Get the Name from the ncio variable public :: shr_ncio_descripGetString ! Get the string value from the ncio variable public :: shr_ncio_descripGetInteger ! Get the integer value from the ncio variable public :: shr_ncio_descripGetLogical ! Get the logical value from the ncio variable public :: shr_ncio_descripGetRealR8 ! Get the real value from the ncio variable public :: shr_ncio_descripRead ! Read in file public :: shr_ncio_descripWrite ! Write out to file public :: shr_ncio_open ! Open NetCDF file for reading/writing/appending public :: shr_ncio_close ! Close a NetCDF file public :: shr_ncio_setDebug ! Set debug level of printing public :: shr_ncio_setAbort ! Set flag if should abort on error or not ! !PUBLIC DATA MEMBERS: ! no public data members !EOP ! Private member functions: private :: shr_ncio_logical2Int ! Convert logical into an integer private :: shr_ncio_int2Logical ! Convert integer back into a logical private :: shr_ncio_abort ! Local abort method !--- Private data to use for data that is not specified yet --- integer, parameter :: shr_ncio_integerFill = -99999 character(len=*), parameter :: shr_ncio_stringFill = '----NOTSET----' real(SHR_KIND_R8), parameter :: shr_ncio_realR8Fill = shr_const_spval integer, parameter :: maxDims = 1 !--- Public NetCDF description type --- type shr_ncio_descripType private ! Opaque type character(SHR_KIND_CS) :: Name = shr_ncio_stringFill ! Variable Name integer :: XType = shr_ncio_integerFill ! Variable type integer :: id = shr_ncio_integerFill ! variable id number integer :: nDims ! number of dimensions integer :: DimSizes(maxDims) ! Sizes of dimensions character(SHR_KIND_CS) :: DimNames(maxDims) ! Names of dimensions character(SHR_KIND_CS) :: Units = shr_ncio_stringFill ! Units of variable character(SHR_KIND_CL) :: StringData = shr_ncio_stringFill ! String scalar to write character(SHR_KIND_CL) :: ListDescrips = shr_ncio_stringFill! List of descriptions integer :: IntegerData = shr_ncio_integerFill! Integer scalar to write real(SHR_KIND_R8) :: RealR8Data = shr_ncio_realR8Fill ! Real scalar to write integer :: IntegerFill = shr_ncio_integerFill! Integer Fill-value real(SHR_KIND_R8) :: RealR8Fill = shr_ncio_realR8Fill ! Real Fill-value logical :: LogicalData ! Logical scalar to write integer, pointer :: ListValues(:) ! List values character(SHR_KIND_CL) :: LongName = shr_ncio_stringFill ! Long Name of variable end type shr_ncio_descripType !--- Private data to signify which type of data will be written --- integer, parameter :: shr_ncio_integerDataValue = 1 ! Data is integer integer, parameter :: shr_ncio_stringDataValue = 2 ! Data is string integer, parameter :: shr_ncio_logicalDataValue = 3 ! Data is logical integer, parameter :: shr_ncio_realR8DataValue = 4 ! Data is real r8 logical, save :: doAbort = .true. ! If abort on error or not integer, save :: debugLevel = 1 ! Debug level character(len=*), parameter :: shrCharacterDimName = "shr_character" !=============================================================================== CONTAINS !=============================================================================== !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_descripSetDefault -- Set ncio_descrip variables to defaults ! ! !DESCRIPTION: ! ! Set an array of shr_ncio_descrip variables to the default settings. This ! allows you to re-initialize them to different values if you so choose, It's ! also important on compilers that do NOT recognize structure initialization ! (as above) such as on PGI. ! ! !INTERFACE: ------------------------------------------------------------------ SUBROUTINE shr_ncio_descripSetDefault( NVars, DescripVars ) 3 ! !USES: implicit none ! !INPUT/OUTPUT PARAMETERS: integer, intent(IN) :: nVars ! Number of variables type(shr_ncio_descripType), intent(INOUT) :: DescripVars(nVars) ! Output description variables !EOP !----- local ----- character(len=*), parameter :: subName = '(shr_ncio_descripSetDefault) ' integer :: i ! index !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- do i = 1, NVars DescripVars(i)%Name = shr_ncio_stringFill ! Variable Name DescripVars(i)%XType = shr_ncio_integerFill ! Variable type DescripVars(i)%id = shr_ncio_integerFill ! variable id number DescripVars(i)%Units = shr_ncio_stringFill ! Units of variable DescripVars(i)%StringData = shr_ncio_stringFill ! String scalar to write DescripVars(i)%ListDescrips = shr_ncio_stringFill ! List of descriptions DescripVars(i)%IntegerData = shr_ncio_integerFill ! Integer scalar to write DescripVars(i)%RealR8Data = shr_ncio_realR8Fill ! Real scalar to write DescripVars(i)%IntegerFill = shr_ncio_integerFill ! Integer Fill-value DescripVars(i)%RealR8Fill = shr_ncio_realR8Fill ! Real Fill-value DescripVars(i)%LongName = shr_ncio_stringFill ! Long Name of variable end do END SUBROUTINE shr_ncio_descripSetDefault !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_descripInit -- Set ncio_descrip variable Names ! ! !DESCRIPTION: ! ! Initial setup of a ncio descrip variable. Set logical data flags either to: ! StringData, ! IntegerData, LogicalData, or RealR8Data. Can optionally set ! the LongName, Units, and fillvalue (only for RealR8 or Integer data). Note, ! if you select IntegerData for the data-type, you can only set the IntergerFill ! value, NOT the RealR8Fill value and vica-versa. If you pick IntegerData ! as the data-type you can also select ListDescrips and ListIntValues with ! the list of valid values and a description for the meaning of each of those ! values. In this case, attributes giving the values and the matching ! description of that value will be added to the output NetCDF file. ! For example, if you have integer data to describe the vegetation type, with ! a list of 12 different vegetation types, you give a colen delimited list to ! describe each type, as well as ListIntValues to give the corresponding value ! that goes with each description in the list. ! ! !INTERFACE: ------------------------------------------------------------------ SUBROUTINE shr_ncio_descripInit( DescripVar, Name, LongName, Units, & 19,19 StringData, IntegerData, LogicalData, & RealR8Data, IntegerFill, & RealR8Fill, ListDescrips, & ListIntValues, nDims, dimSizes ) ! !USES: use shr_string_mod, only: shr_string_listIsValid, shr_string_listGetNum implicit none ! !INPUT/OUTPUT PARAMETERS: type(shr_ncio_descripType), intent(INOUT) :: DescripVar! Output description variable character(len=*), intent(IN) :: Name ! Short name of data character(len=*), intent(IN), optional :: LongName ! Longname of data character(len=*), intent(IN), optional :: Units ! Physical units of data logical, intent(IN), optional, target :: StringData ! Flag if data is string-type logical, intent(IN), optional, target :: IntegerData ! Flag if data is integer-type logical, intent(IN), optional, target :: LogicalData ! Flag if data is logical-type logical, intent(IN), optional, target :: RealR8Data ! Flag if data is string-type real(SHR_KIND_R8), intent(IN), optional :: RealR8Fill ! Fill value for real-R8 data integer, intent(IN), optional, target :: IntegerFill ! Fill value for integer data ! --- For integer-list, description of each value as colen delimited list --- character(len=*), intent(IN), optional :: ListDescrips ! --- For integer-list, integer values that go with each description ---- integer, intent(IN), optional :: ListIntValues(:) integer, intent(IN), optional :: nDims ! Number of dimensions of variable integer, intent(IN), optional :: dimSizes(:) ! Sizes of each dimension !EOP !----- local ----- character(len=*), parameter :: subName = '(shr_ncio_descripInit) ' logical :: NotSet ! Type not set yet or not integer :: nList ! Number of values in list !------------------------------------------------------------------------------- ! Notes: ! ! Currently only implemented for scalar data, nDims and dimSizes are not fully ! tested. !------------------------------------------------------------------------------- ! --- Check if setting more than one data-type ------ if ( (PRESENT(StringData) .and. PRESENT(IntegerData)) .or. & (PRESENT(StringData) .and. PRESENT(LogicalData)) .or. & (PRESENT(StringData) .and. PRESENT(RealR8Data )) .or. & (PRESENT(IntegerData) .and. PRESENT(LogicalData)) .or. & (PRESENT(IntegerData) .and. PRESENT(RealR8Data )) .or. & (PRESENT(LogicalData) .and. PRESENT(RealR8Data )) )then call shr_ncio_abort( subName//': can not set more than one variable type' ) end if if ( PRESENT(nDims) .or. PRESENT(dimSizes) )then call shr_ncio_abort( subName//': currently nDims and dimSizes are NOT implemented' ) end if if ( PRESENT(nDims) .and. .not. PRESENT(dimSizes) & .or. (.not. PRESENT(nDims) .and. PRESENT(dimSizes) ) )then call shr_ncio_abort( subName//': if nDims set so must also dimSizes' ) else if ( PRESENT(nDims) .and. PRESENT(dimSizes) )then if ( nDims /= size(dimSizes) )then call shr_ncio_abort( subName//': if nDims NOT set to same dimensionality as dimSizes' ) end if if ( nDims > maxDims )then call shr_ncio_abort( subName//': nDims > size of max dimensions' ) end if DescripVar%nDims = nDims DescripVar%dimSizes(:) = dimSizes(:nDims) end if ! --- Name, check if name already defined ------ if ( DescripVar%Name == shr_ncio_stringFill )then DescripVar%Name = Name ! --- If name already defined, but you are asking for a different name -- abort else if ( trim(Name) /= trim(DescripVar%Name) )then call shr_ncio_abort( subName//': bad Name: '//trim(Name)// & ' sent to variable already defined as:'// & trim(DescripVar%Name) ) ! --- If name is the same, as previously defined name -- silently continue ------ end if ! --- Long-name and units attributes ------ if ( PRESENT(LongName) ) DescripVar%LongName = LongName if ( PRESENT(Units) ) DescripVar%Units = Units NotSet = .true. ! --- For String Data type ------ if ( PRESENT(StringData) )then NotSet = .false. DescripVar%XType = shr_ncio_stringDataValue if ( .not. PRESENT(nDims) )then DescripVar%nDims = 1 DescripVar%dimSizes(1) = len(DescripVar%StringData) end if DescripVar%dimNames(1) = shrCharacterDimName if ( .not. PRESENT(Units) ) DescripVar%Units = "string" end if ! --- For Integer Data type ------ if ( PRESENT(IntegerData) )then if ( .not. NotSet ) call shr_ncio_abort( subName//': trying to define '// & 'to more than one data-type' ) NotSet = .false. DescripVar%XType = shr_ncio_integerDataValue if ( .not. PRESENT(nDims) )then DescripVar%nDims = 0 end if if ( PRESENT(IntegerFill) )then DescripVar%IntegerFill = IntegerFill DescripVar%IntegerData = IntegerFill end if ! --- For an integer list ------ if ( PRESENT(ListDescrips) )then if ( .not. PRESENT(ListIntValues) )then call shr_ncio_abort( subName//': setting ListDescrips without '// & 'setting ListIntValues' ) end if if ( .not. shr_string_listIsValid( ListDescrips ) )then call shr_ncio_abort( subName//': ListDescrips is not a valid '// & 'list of descriptions' ) end if nList = shr_string_listGetNum( ListDescrips ) if ( size(ListIntValues) /= nList )then call shr_ncio_abort( subName//': number of list descriptions '// & 'inconsistent with number of list integer values' ) end if allocate( DescripVar%ListValues(nList) ) DescripVar%ListDescrips = ListDescrips DescripVar%ListValues(:) = ListIntValues(:) else if ( PRESENT(ListIntValues) )then call shr_ncio_abort( subName//': setting ListIntValues '// & 'without setting ListDescrips' ) end if end if else if ( PRESENT(IntegerFill) )then call shr_ncio_abort( subName//': setting integer FillValue '// & 'without setting IntegerData' ) end if if ( PRESENT(ListDescrips) .or. PRESENT(ListIntValues) )then call shr_ncio_abort( subName//': setting ListDescrips or '// & 'ListIntValues without setting IntegerData' ) end if end if ! --- Logical data ------ if ( PRESENT(LogicalData) )then if ( .not. NotSet ) call shr_ncio_abort( subName//': trying '// & 'to define to more than one data-type' ) NotSet = .false. DescripVar%XType = shr_ncio_logicalDataValue if ( .not. PRESENT(nDims) )then DescripVar%nDims = 0 end if if ( .not. PRESENT(Units) ) DescripVar%Units = & "logical flag (0=false)" end if ! --- Real-R8 data ------ if ( PRESENT(RealR8Data) )then if ( .not. NotSet ) call shr_ncio_abort( & subName//': trying to define to more than one data-type' ) NotSet = .false. DescripVar%XType = shr_ncio_realR8DataValue if ( .not. PRESENT(nDims) )then DescripVar%nDims = 0 end if if ( PRESENT(RealR8Fill) )then DescripVar%RealR8Fill = RealR8Fill DescripVar%RealR8Data = RealR8Fill end if else if ( PRESENT(RealR8Fill) )then call shr_ncio_abort( subName//': setting realr8 FillValue '// & 'without setting RealR8Data' ) end if end if if ( NotSet ) call shr_ncio_abort( subName//': called without giving '// & 'a value to set' ) END SUBROUTINE shr_ncio_descripInit !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_descripPutData -- Set a ncio_descrip variable type ! ! !DESCRIPTION: ! ! Set the data of a ncio descrip variable. Data is set to either the string, ! integer, logical or Real-R8 data value input. Can NOT specify more than one ! data-type. Check that name agrees with name on variable type, or else abort. ! ! !INTERFACE: ------------------------------------------------------------------ SUBROUTINE shr_ncio_descripPutData( DescripVar, Name, StringData, & 19,9 IntegerData, LogicalData, RealR8Data ) implicit none ! !INPUT/OUTPUT PARAMETERS: type(shr_ncio_descripType), intent(INOUT) :: DescripVar ! descrip variable to set character(len=*), intent(IN) :: Name ! Name of this variable character(len=*), optional, intent(IN), target :: StringData ! String-data value integer, target, optional, intent(IN) :: IntegerData ! Integer-data value logical, target, optional, intent(IN) :: LogicalData ! Logical-data value real(SHR_KIND_R8), optional,intent(IN), target :: RealR8Data ! Real-R8-data value !EOP !----- local ----- character(len=*), parameter :: subName = '(shr_ncio_descripPutData) ' logical :: NotSet ! Flag if data is not set yet !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- ! --- Check if too many data values are set (can only be one!) ----- if ( (PRESENT(StringData) .and. PRESENT(IntegerData)) .or. & (PRESENT(StringData) .and. PRESENT(LogicalData)) .or. & (PRESENT(StringData) .and. PRESENT(RealR8Data )) .or. & (PRESENT(IntegerData) .and. PRESENT(LogicalData)) .or. & (PRESENT(IntegerData) .and. PRESENT(RealR8Data )) .or. & (PRESENT(LogicalData) .and. PRESENT(RealR8Data )) )then call shr_ncio_abort( subName//': can not set more than one variable type' ) end if ! --- Make sure name is set and agrees with the input ----- if ( DescripVar%Name == shr_ncio_stringFill )then call shr_ncio_abort( subName//': descrip variable has not been defined '// & 'yet with shr_ncio_descripInit' ) else if ( trim(Name) /= trim(DescripVar%Name) )then call shr_ncio_abort( subName//': bad Name: '//trim(Name)// & ' sent to variable already defined as:'// & trim(DescripVar%Name) ) end if NotSet = .true. !----------------------------------------------------------------------------- ! ----------- Test for each type of data ------------ ! Make sure data sent in is consistent with expected type ! And track if data was set, so can abort if no data was set !----------------------------------------------------------------------------- ! --- If string data ------- if ( PRESENT(StringData) )then NotSet = .false. if ( DescripVar%XType /= shr_ncio_stringDataValue )then call shr_ncio_abort( subName//': Setting descrip variable to string '// & 'which is wrong variable type' ) end if if ( len_trim(StringData) > len(DescripVar%StringData) )then call shr_ncio_abort( subName//': Length of input string data longer '// & 'than storage size of DescripVar type' ) end if DescripVar%StringData(1:len(DescripVar%StringData)) = ' ' DescripVar%StringData(:len_trim(StringData)) = trim(StringData) end if ! --- If integer data ------- if ( PRESENT(IntegerData) )then NotSet = .false. if ( DescripVar%XType /= shr_ncio_integerDataValue )then call shr_ncio_abort( subName//': Setting descrip variable to integer '// & 'which is wrong variable type' ) end if DescripVar%IntegerData = IntegerData end if ! --- If logical data ------- if ( PRESENT(LogicalData) )then NotSet = .false. if ( DescripVar%XType /= shr_ncio_logicalDataValue )then call shr_ncio_abort( subName//': Setting descrip variable to logical '// & 'which is wrong variable type' ) end if DescripVar%LogicalData = LogicalData end if ! --- If real R8 data ------- if ( PRESENT(RealR8Data) )then NotSet = .false. if ( DescripVar%XType /= shr_ncio_realR8DataValue )then call shr_ncio_abort( subName//': Setting descrip variable to realr8 '// & 'which is wrong variable type' ) end if DescripVar%RealR8Data = RealR8Data end if ! --- If no data was set abort with an error ------- if ( NotSet ) call shr_ncio_abort( subName//': called without giving a '// & 'value to set' ) END SUBROUTINE shr_ncio_descripPutData !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_descripName -- Return the Name of this ncio variable ! ! !DESCRIPTION: ! ! Returns Name of the variable ! ! !INTERFACE: ------------------------------------------------------------------ FUNCTION shr_ncio_descripName( DescripVar ) 39 implicit none ! !INPUT/OUTPUT PARAMETERS: type(shr_ncio_descripType), intent(IN) :: DescripVar character(len=SHR_KIND_CS) :: shr_ncio_descripName !EOP !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- shr_ncio_descripName = trim(DescripVar%Name) END FUNCTION shr_ncio_descripName !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_descripGetString -- Return the string value of this ncio variable ! ! !DESCRIPTION: ! ! Returns the string value from this variable ! ! !INTERFACE: ------------------------------------------------------------------ FUNCTION shr_ncio_descripGetString( DescripVar ) 8,5 implicit none ! !INPUT/OUTPUT PARAMETERS: type(shr_ncio_descripType), intent(IN) :: DescripVar ! NetCDF description variable character(len=SHR_KIND_CL) :: shr_ncio_descripGetString ! Returned string value of data !EOP !----- local ----- character(len=*), parameter :: subName = '(shr_ncio_descripGetString) ' !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- ! --- If this structure hasn't been initialized yet -- abort with an error ------- if ( DescripVar%Name == shr_ncio_stringFill )then call shr_ncio_abort( subName//': input shr_ncio description variable '// & 'has not been initializated yet: ' ) end if ! --- If this isn't a string type of variable -- abort with an error ------- if ( DescripVar%XType /= shr_ncio_stringDataValue )then call shr_ncio_abort( subName//': trying to get a string from a '// & 'different variable type' ) end if shr_ncio_descripGetString(:) = ' ' shr_ncio_descripGetString(1:len_trim(DescripVar%StringData)) = & trim(DescripVar%StringData) ! --- If data not set yet abort with an error ------- if ( shr_ncio_descripGetString== shr_ncio_stringFill )then call shr_ncio_abort( subName//': Returned string has not been set yet' ) end if END FUNCTION shr_ncio_descripGetString !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_descripGetInteger -- Return the integer value of this ncio variable ! ! !DESCRIPTION: ! ! Returns the integer value from this variable ! ! !INTERFACE: ------------------------------------------------------------------ integer FUNCTION shr_ncio_descripGetInteger( DescripVar ) 2,3 implicit none ! !INPUT/OUTPUT PARAMETERS: type(shr_ncio_descripType), intent(IN) :: DescripVar ! Input NetCDF description variable !EOP !----- local ----- character(len=*), parameter :: subName = '(shr_ncio_descripGetInteger) ' !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- ! --- If this structure hasn't been initialized yet -- abort with an error ------- if ( DescripVar%Name == shr_ncio_stringFill )then call shr_ncio_abort( subName//': input shr_ncio description '// & 'variable has not been initializated yet: ' ) end if ! --- If this isn't a integer type of variable -- abort with an error ------- if ( DescripVar%XType /= shr_ncio_integerDataValue )then call shr_ncio_abort( subName//': trying to get an integer from a '// & 'different variable type' ) end if ! --- If data not set yet abort with an error ------- shr_ncio_descripGetInteger = DescripVar%IntegerData if ( shr_ncio_descripGetInteger == shr_ncio_integerFill )then call shr_ncio_abort( subName//': Returned integer has not been set yet' ) end if END FUNCTION shr_ncio_descripGetInteger !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_descripGetLogical -- Return the logical value of this ncio variable ! ! !DESCRIPTION: ! ! Returns the logical value from this variable ! ! !INTERFACE: ------------------------------------------------------------------ logical FUNCTION shr_ncio_descripGetLogical( DescripVar ) 6,2 implicit none ! !INPUT/OUTPUT PARAMETERS: type(shr_ncio_descripType), intent(IN) :: DescripVar ! Input NetCDF description variable !EOP !----- local ----- character(len=*), parameter :: subName = '(shr_ncio_descripGetLogical) ' !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- ! --- If this structure hasn't been initialized yet -- abort with an error ------ if ( DescripVar%Name == shr_ncio_stringFill )then call shr_ncio_abort( subName//': input shr_ncio description '// & 'variable has not been initializated yet: ' ) end if ! --- If this isn't a logical type of variable -- abort with an error ------ if ( DescripVar%XType /= shr_ncio_logicalDataValue )then call shr_ncio_abort( subName//': trying to get an logical from a '// & 'different variable type' ) end if shr_ncio_descripGetLogical = DescripVar%LogicalData END FUNCTION shr_ncio_descripGetLogical !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_descripGetRealR8 -- Return the realr8 value of this ncio variable ! ! !DESCRIPTION: ! ! Returns the realr8 value from this variable ! ! !INTERFACE: ------------------------------------------------------------------ real(SHR_KIND_R8) FUNCTION shr_ncio_descripGetRealR8( DescripVar ) 2,3 implicit none ! !INPUT/OUTPUT PARAMETERS: type(shr_ncio_descripType), intent(IN) :: DescripVar ! Input NetCDF description variable !EOP !----- local ----- character(len=*), parameter :: subName = '(shr_ncio_descripGetRealR8) ' !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- ! --- If this structure hasn't been initialized yet -- abort with an error ------ if ( DescripVar%Name == shr_ncio_stringFill )then call shr_ncio_abort( subName//': input shr_ncio description variable '// & 'has not been initializated yet: ' ) end if ! --- If this isn't a real r8 type of variable -- abort with an error ------ if ( DescripVar%XType /= shr_ncio_realR8DataValue )then call shr_ncio_abort( subName//': trying to get an real from a '// & 'different variable type' ) end if ! --- If data not set yet abort with an error ------ shr_ncio_descripGetRealR8 = DescripVar%RealR8Data if ( shr_ncio_descripGetRealR8 == shr_ncio_realR8Fill )then call shr_ncio_abort( subName//': Returned realr8 has not been set yet' ) end if END FUNCTION shr_ncio_descripGetRealR8 !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_descripRead -- Read in netCDF restart file ! ! !DESCRIPTION: ! ! Read in restart file information from netCDF input restart file ! ! !INTERFACE: ------------------------------------------------------------------ SUBROUTINE shr_ncio_descripRead( ncId, nVars, prefix, mpicom, MasterTask, var ) 6,21 ! !USES: use shr_string_mod, only: shr_string_lastIndex use shr_mpi_mod, only: shr_mpi_bcast implicit none ! !INPUT/OUTPUT PARAMETERS: integer, intent(IN) :: ncId ! NetCDF file unit id integer, intent(IN) :: nVars ! Number of variables character(len=*), intent(IN), optional :: prefix ! Prefix in front of variable Names integer, intent(IN), optional :: MPICom ! MPI communicator logical, intent(IN), optional :: MasterTask ! If Master PE task or not type(shr_ncio_descripType), intent(INOUT) :: var(:) ! NetCDF description structure !----- local ----- character(len=*), parameter :: subName = "(shr_ncio_descripRead) " logical :: MasterTask2 ! If Master PE task or not integer :: rCode ! Return code integer :: nDims ! Number of dimensions on file integer :: VarDimIds(maxDims) ! Array of dimension id's for this variable integer :: dimIds(maxDims) ! Dimension id number integer :: type ! Type of variable integer :: i, dim ! Index integer :: nChars ! Number of characters in string integer :: n ! Character index character(SHR_KIND_CL) :: StringData ! String value read in integer :: IntegerData ! Integer value read in real(SHR_KIND_R8) :: RealR8Data ! Real value to read in character(len=SHR_KIND_CS) :: prefixUse ! Prefix in front of variable Names !------------------------------------------------------------------------------- ! Notes: ! Currently this interface can NOT be used to read in non-scalar data. !------------------------------------------------------------------------------- if ( present(MasterTask) )then MasterTask2 = MasterTask else MasterTask2 = .true. end if if ( present(prefix) )then prefixUse = prefix else prefixUse = "" end if if ( MasterTask2 )then !------------------------------------------------------------------------- ! Loop through variables !------------------------------------------------------------------------- do i = 1, nVars if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'Read variable: ', trim(var(i)%Name) ! --- If name not set, hasn't been initialized -- abort with an error ----- if ( trim(var(i)%Name) == shr_ncio_stringFill )then write(s_logunit,'(a,i3,a,i3)') 'variable number = ', i, ' of ', nVars call shr_ncio_abort( subName//': variable name not defined -- '// & 'DescripVarSet not called' ) end if ! --- Get variable ID ----- rcode = nf90_inq_varid(ncId,trim(prefixUse)//trim(var(i)%Name),var(i)%id ) call shr_ncio_abort( subName//': variable '// trim(var(i)%Name)//' not found', rcode ) ! --- Get type of variable ----- rcode = nf90_inquire_variable(ncId, var(i)%id, nDims=nDims, & XType=type ) call shr_ncio_abort( subName// ': error on inquiry of '//var(i)%Name, rcode ) if (nDims /= var(i)%nDims )then write(s_logunit,'(a,a,a,i4,a,i4)') 'Number of dimensions for variable', & trim(var(i)%name), ' :', nDims, ' expected:', var(i)%nDims call shr_ncio_abort( subName//': '//var(i)%Name// & ' dimension size different than expected' ) end if ! --- Read in the dimension names for this variable ---------------------- do dim = 1, nDims rcode = nf90_inq_dimId(ncId, var(i)%dimNames(dim), dimIds(dim) ) call shr_ncio_abort( subName// ': error gettting dimension', rcode ) end do ! --- Check that dimension ids are correct ------------------------------- if ( nDims > 0 )then rcode = nf90_inquire_variable(ncId, var(i)%id, dimIds=VarDimIds ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on inquiry of dimIds'//var(i)%Name ) if ( any(dimIds /= VarDimIds) ) call shr_ncio_abort( subName// & ': dimIds not correct' ) end if ! --- If variable string data type ----- if (var(i)%XType == shr_ncio_stringDataValue )then if ( type /= NF90_CHAR ) call shr_ncio_abort( subName//': '// & var(i)%Name//' not proper type' ) rcode = nf90_get_att(ncId, var(i)%id, "nChars", nChars) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error getting nChars from : '//var(i)%Name ) rcode = nf90_get_var( ncId, varid=var(i)%id, values=StringData, & count=(/nChars/) ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on get of '//var(i)%Name ) var(i)%StringData(:) = ' ' var(i)%StringData(:nChars) = StringData(:nChars) ! --- If integer data type -------- else if (var(i)%XType == shr_ncio_integerDataValue )then if ( type /= NF90_INT ) call shr_ncio_abort( subName//': '// & var(i)%Name//' not proper type' ) rcode = nf90_get_var( ncId, var(i)%id, IntegerData) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on get of '//var(i)%Name ) var(i)%IntegerData = IntegerData ! --- If real r8 data type -------- else if (var(i)%XType == shr_ncio_realR8DataValue )then if ( type /= NF90_DOUBLE) call shr_ncio_abort( subName//': '// & var(i)%Name//' not proper type' ) rcode = nf90_get_var( ncId, var(i)%id, RealR8Data ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on get of '//var(i)%Name ) var(i)%RealR8Data = RealR8Data ! --- If logical data type -------- else if (var(i)%XType == shr_ncio_logicalDataValue )then if ( type /= NF90_INT ) call shr_ncio_abort( subName//': '// & var(i)%Name//' not proper type' ) rcode = nf90_get_var( ncId, var(i)%id, IntegerData) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on get of '//var(i)%Name ) var(i)%LogicalData = shr_ncio_logical2Int( IntegerData ) ! --- Otherwise data type is unknown abort with an error -------- else call shr_ncio_abort( subName//': only integer, logical, '// & 'real-r8 or character can not be read for variable ' & //var(i)%Name ) end if end do end if ! --- If MPI broadcast to other MPI tasks ----------------------------------- if ( present(mpicom) )then if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'Broadcast variables to all tasks' do i = 1, nVars if ( var(i)%XType == shr_ncio_stringDataValue )then call shr_mpi_bcast( var(i)%StringData, mpicom ) else if ( var(i)%XType == shr_ncio_integerDataValue )then call shr_mpi_bcast( var(i)%IntegerData, mpicom ) else if ( var(i)%XType == shr_ncio_realR8DataValue )then call shr_mpi_bcast( var(i)%RealR8Data, mpicom ) else if ( var(i)%XType == shr_ncio_logicalDataValue )then call shr_mpi_bcast( var(i)%LogicalData, mpicom ) else call shr_ncio_abort( subName//': invalid ncio type: ' ) end if end do end if END SUBROUTINE shr_ncio_descripRead !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_descripWrite -- Write out netCDF restart file information ! ! !DESCRIPTION: ! ! Write out restart file information to netCDF restart file ! ! !INTERFACE: ------------------------------------------------------------------ SUBROUTINE shr_ncio_descripWrite( ncId, nVars, prefix, mpicom, MasterTask, exists, & 6,22 var ) ! !USES: use shr_string_mod, only: shr_string_lastindex, shr_string_listGetName, & shr_string_listGetNum implicit none ! !INPUT/OUTPUT PARAMETERS: integer, intent(IN) :: ncId ! NetCDF file id integer, intent(IN) :: nVars ! Number of variables character(len=*), intent(IN), optional :: prefix ! Prefix in front of variable Names integer, intent(IN), optional :: MPICom ! MPI communicator logical, intent(IN), optional :: MasterTask! If Master PE task or not logical, intent(IN) :: exists ! If datafile exists already or not type(shr_ncio_descripType), intent(INOUT) :: var(:) ! NetCDF description structure !EOP !----- local ----- character(len=*), parameter :: subName = "(shr_ncio_descripWrite) " logical :: MasterTask2 ! If Master PE task or not integer :: rcode ! NetCDF return code integer :: dimIds(maxDims) ! Dimension id numbers integer :: i ! Variable index integer :: dim ! Dimension index logical :: NotSet ! If variables set yet or not logical :: DimSet ! If dimension set yet or not integer :: n ! character index integer :: type ! data type to write to file integer :: list ! List index number integer :: nList ! number of items in list character(len=SHR_KIND_CL) :: name ! List description name character(len=SHR_KIND_CS) :: prefixUse ! Prefix in front of variable Names character(len=*), parameter :: F00= & "(a,' input: nciD=',i3,' nvars=',i3, ' prefix=',a,' master=',l1,' exists=',l1)" !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- if ( present(MasterTask) )then MasterTask2 = MasterTask else MasterTask2 = .true. end if if ( present(prefix) )then prefixUse = prefix else prefixUse = "" end if !----------------------------------------------------------------------------- if ( debugLevel > 2 .and. s_loglev > 0) write(s_logunit,F00) subName, ncid, nVars, trim(prefixUse), & MasterTask2, exists if ( MasterTask2 )then ! --- If file already exists, go to re-define mode ----- if ( exists )then rcode = nf90_redef(ncId) call shr_ncio_abort( subName// ': error on redefine output NetCDF file', rcode ) end if !-------------------------------------------------------------------------- ! Define variables !-------------------------------------------------------------------------- do i = 1, nVars NotSet = .false. if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'Write variable: ', trim(var(i)%Name) ! --- If file exists, check if given variable is already defined ------- if ( exists )then rcode = nf90_inq_varid(ncId, Name=trim(prefixUse)//trim(var(i)%Name), & varid=var(i)%id ) if (rcode == nf90_enotvar )then NotSet = .true. else if (rcode /= nf90_noerr)then call shr_ncio_abort( subName//': error getting variable id' ) end if end if ! --- If new file or variable NOT defined, define it now --------------- if ( .not. exists .or. NotSet )then !-------------------------------------------------------------------- ! Define dimensions for this variable if not already defined !-------------------------------------------------------------------- do dim = 1, var(i)%nDims DimSet = .false. rcode = nf90_inq_dimId(ncId, Name=var(i)%dimNames(dim), & dimId=dimIds(dim)) if ( rcode == nf90_ebaddim )then DimSet = .true. else if (rcode /= nf90_noerr)then call shr_ncio_abort( subName//': error getting correct '// & 'dimension id for :'//trim(var(i)%dimNames(dim)) ) end if if ( DimSet )then rcode = nf90_def_dim(ncId, Name=var(i)%dimNames(dim), & len=SHR_KIND_CL, dimId=dimIds(dim) ) call shr_ncio_abort( subName//': error writing dimension', & rcode ) end if end do if ( var(i)%XType == shr_ncio_stringDataValue )then type = NF90_CHAR else if ( var(i)%XType == shr_ncio_integerDataValue .or. & var(i)%XType == shr_ncio_logicalDataValue )then type = NF90_INT else if ( var(i)%XType == shr_ncio_realR8DataValue )then type = NF90_DOUBLE else call shr_ncio_abort( subName// & ': error on variable definition: '// & trim(var(i)%Name) ) end if if ( var(i)%NDims > 0 )then rcode = nf90_def_var( ncId, trim(prefixUse)//trim(var(i)%Name), & type, dimIds=dimIds, varid=var(i)%id ) else rcode = nf90_def_var( ncId, trim(prefixUse)//trim(var(i)%Name), & type, var(i)%id ) end if if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on variable definition: '// & trim(var(i)%Name) ) end if !----------------------------------------------------------------------- ! Attributes on variables !----------------------------------------------------------------------- rcode = nf90_put_att( ncId, var(i)%id, "long_name", var(i)%LongName ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on putting LongName '// & 'attribute on variable: '// & trim(var(i)%Name) ) rcode = nf90_put_att( ncId, var(i)%id, "units", var(i)%Units ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on putting Units attribute '// & 'on variable: '//trim(var(i)%Name) ) if ( var(i)%XType == shr_ncio_stringDataValue )then rcode = nf90_put_att( ncId, var(i)%id, "nChars", & len_trim(var(i)%StringData) ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on putting nChars '// & 'attribute on variable: '// & trim(var(i)%Name) ) end if ! --- Fill value for integer data ------- if ( var(i)%IntegerFill /= shr_ncio_integerFill )then rcode = nf90_put_att( ncId, var(i)%id, "_FillValue", & var(i)%IntegerFill ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on putting _FillValue '// & 'integer attribute on variable: '// & var(i)%Name ) rcode = nf90_put_att( ncId, var(i)%id, "missing_value", & var(i)%IntegerFill ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on putting missing_value'// & 'integer attribute on variable: '// & var(i)%Name ) end if ! --- Fill value for real-r8 data ------- if ( var(i)%RealR8Fill /= shr_ncio_realR8Fill )then rcode = nf90_put_att( ncId, var(i)%id, "_FillValue", & var(i)%RealR8Fill ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on putting _FillValue '// & 'RealR8 attribute on variable: '// & var(i)%Name ) rcode = nf90_put_att( ncId, var(i)%id, "missing_value", & var(i)%RealR8Fill ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on putting missing_value'// & 'RealR8 attribute on variable: '// & var(i)%Name ) end if ! --- List description attributes ------------------------------------- if ( var(i)%ListDescrips /= shr_ncio_stringFill )then rcode = nf90_put_att( ncId, var(i)%id, "type", "Integer list" ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on putting '// & ' type string attribute on variable: '// & var(i)%Name ) nList = shr_string_listGetNum( var(i)%ListDescrips ) do list = 1, nList call shr_string_listGetName( var(i)%ListDescrips, list, & name, rcode ) rcode = nf90_put_att( ncId, var(i)%id, trim(name), & var(i)%ListValues(list) ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error on putting ' & //name//' integer attribute on variable: '// & var(i)%Name ) end do end if end do ! --- Take it out of definition mode ------ rcode = nf90_enddef( ncId ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error ending definition mode' ) !-------------------------------------------------------------------------- ! Write out variables !-------------------------------------------------------------------------- do i = 1, nVars if ( var(i)%XType == shr_ncio_stringDataValue )then rcode = nf90_put_var( ncId, var(i)%id, trim(var(i)%StringData), & count=(/len_trim(var(i)%StringData)/) ) else if ( var(i)%XType == shr_ncio_integerDataValue )then rcode = nf90_put_var( ncId, var(i)%id, var(i)%IntegerData ) else if ( var(i)%XType == shr_ncio_realR8DataValue )then rcode = nf90_put_var( ncId, var(i)%id, var(i)%RealR8Data ) else if ( var(i)%XType == shr_ncio_logicalDataValue )then rcode = nf90_put_var( ncId, var(i)%id, shr_ncio_int2Logical( & var(i)%LogicalData ) ) else call shr_ncio_abort( subName//': invalid ncio type: ' ) end if if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error writing variable: ' & //var(i)%Name ) end do end if END SUBROUTINE shr_ncio_descripWrite !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_open -- Open a NetCDF file for reading, writing or appending ! ! !DESCRIPTION: ! ! Open NetCDF file for reading, writing or appending. If reading, or appending ! abort if file does not exist or on error. If appending ! ! !INTERFACE: ------------------------------------------------------------------ subroutine shr_ncio_open( NCFileName, MasterTask, FileType, ncId, exists, & 6,3 writing, appending, clobber ) implicit none ! !INPUT/OUTPUT PARAMETERS: character(len=*), intent(IN) :: NCFileName ! Full path to input fileName to read logical, intent(IN) :: MasterTask ! If Master PE task or not character(len=*), intent(IN) :: FileType ! Description of file-type integer, intent(OUT) :: ncId ! NetCDF file unit logical, intent(OUT) :: exists ! If file exists or not logical, intent(IN), optional :: writing ! If should open for writing logical, intent(IN), optional :: appending ! If should open for appending logical, intent(IN), optional :: clobber ! if exist clobber !EOP !----- local ----- character(len=*), parameter :: subName = "(shr_ncio_open) " integer :: rCode ! Return code logical :: writing2 ! If should open for writing logical :: appending2 ! If should open for appending logical :: clobber2 ! If exist clobber !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- ! --- Only open file on MasterTask ----- if ( MasterTask ) then if ( present(writing) )then writing2 = writing else writing2 = .false. end if if ( present(appending) )then appending2 = appending else appending2 = .false. end if if ( appending2 .and. writing2 )then call shr_ncio_abort( subName//': can NOT set both appending and writing option!' ) end if if ( present(clobber)) then clobber2 = clobber else clobber2 = .false. end if if ( debugLevel > 0 .and. s_loglev > 0) write(s_logunit,*) 'Open NetCDF file FileType: '//trim(FileType)// & ' Filename: ', trim(NCFileName) inquire( file = trim(NCFileName), exist = exists ) ! If file exists and reading but not appending if ( exists .and. (.not. writing2) .and. (.not. appending2) )then if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'File exists open for reading not appending: ' rCode = nf90_open( NCFileName, nf90_nowrite, ncId ) ! If file exists and appending else if ( exists .and. appending2 )then if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'File exists open for appending: ' rCode = nf90_open( NCFileName, nf90_noclobber, ncId ) ! If file exists and writing with no clobber else if ( exists .and. writing2 .and. .not.clobber2)then if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'File exists open for writing: ' rCode = nf90_open( NCFileName, nf90_write, ncId ) ! If file exists and writing with clobber else if ( exists .and. writing2 .and. clobber2)then if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'File exists clobber for writing: ' rCode = nf90_create( NCFileName, NF90_64BIT_OFFSET, ncId ) ! If file does NOT exist and writing else if ( (.not. exists) .and. writing2 )then if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'File does NOT exist open for writing: ' rCode = nf90_create( NCFileName, NF90_64BIT_OFFSET, ncId ) ! If file does NOT exist and want to read or append -- flag an error else if ( .not. exists .and. ((.not. writing2) .or. appending2) )then call shr_ncio_abort( subName//': input file does not exist -- can '// & 'NOT open for reading!' ) end if ! Check error code from above options... call shr_ncio_abort( subName//': error opening : '//NCFileName, rcode ) if (clobber2) exists = .false. ! it doesn't exist anymore end if end subroutine shr_ncio_open !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_close -- Close a NetCDF file ! ! !DESCRIPTION: ! ! Close a NetCDF file ! ! !INTERFACE: ------------------------------------------------------------------ subroutine shr_ncio_close( ncId, MasterTask, NCFilename, type ) 6,1 implicit none ! !INPUT/OUTPUT PARAMETERS: integer, intent(IN) :: ncId ! NetCDF file unit logical, intent(IN) :: MasterTask ! If Master PE task or not character(len=*), optional :: NCFileName ! Filename to close character(len=*), optional :: type ! Type of file to close !EOP !----- local ----- character(len=*), parameter :: subName = "(shr_ncio_close) " character(len=SHR_KIND_CL) :: FileName ! Filename to close character(len=SHR_KIND_CL) :: FileType ! Description of file to close integer :: rCode ! Return code !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- ! --- Only close file on MasterTask ----- if ( MasterTask )then if ( PRESENT(NCFileName) )then FileName = NCFileName else FileName = " " end if if ( PRESENT(type) )then FileType = type else FileType = " " end if rCode = nf90_close( ncId ) if (rcode /= nf90_noerr) call shr_ncio_abort( subName// & ': error closing '//trim(FileType)//' file: '// & trim(FileName) ) end if end subroutine shr_ncio_close !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_setDebug -- set debug level ! ! !DESCRIPTION: ! ! Set debug printing level... ! ! !INTERFACE: ------------------------------------------------------------------ subroutine shr_ncio_setDebug(iflag) implicit none ! !INPUT/OUTPUT PARAMETERS: integer, intent(in) :: iflag ! Flag value to set printing level to !EOP !--- local --- character(*),parameter :: subName = "(shr_ncio_setDebug)" !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- debugLevel = iflag end subroutine shr_ncio_setDebug !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_setAbort -- set abort level ! ! !DESCRIPTION: ! ! Set abort level... ! ! !INTERFACE: ------------------------------------------------------------------ subroutine shr_ncio_setAbort(flag) implicit none ! !INPUT/OUTPUT PARAMETERS: logical, intent(in) :: flag ! Flag value to set abort level to !EOP !--- local --- character(*),parameter :: subName = "(shr_ncio_setAbort)" !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- doAbort = flag end subroutine shr_ncio_setAbort !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_logical2Int -- Return logical value based on integer input ! ! !DESCRIPTION: ! ! Convert integer to logical. Private to this module. ! ! !INTERFACE: ------------------------------------------------------------------ logical FUNCTION shr_ncio_logical2Int( int_input ) 1,1 implicit none ! !INPUT/OUTPUT PARAMETERS: integer, intent(IN) :: int_input ! Integer input value to convert to logical !EOP !----- local ----- character(len=*), parameter :: subName = '(shr_ncio_logical2Int) ' !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- if ( int_input == 0 )then shr_ncio_logical2Int = .false. else if ( int_input == 1 )then shr_ncio_logical2Int = .true. else call shr_ncio_abort( subName//': bad input to shr_ncio_logical2Int: ' ) end if END FUNCTION shr_ncio_logical2Int !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_int2Logical -- Return integer value based on logical input ! ! !DESCRIPTION: ! ! Convert logical to integer. Private to this module ! ! !INTERFACE: ------------------------------------------------------------------ integer FUNCTION shr_ncio_int2Logical( log_input ) 1 implicit none ! !INPUT/OUTPUT PARAMETERS: logical, intent(IN) :: log_input ! input logical value to convert to integer !EOP !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- if ( .not. log_input )then shr_ncio_int2Logical = 0 else shr_ncio_int2Logical = 1 end if END FUNCTION shr_ncio_int2Logical !=============================================================================== !BOP =========================================================================== ! ! !IROUTINE: shr_ncio_abort -- abort on error ! ! !DESCRIPTION: ! ! Private routine to abort on error ! ! !INTERFACE: ------------------------------------------------------------------ subroutine shr_ncio_abort( string, rcode) 78,2 ! !USES: use shr_sys_mod, only: shr_sys_abort implicit none ! !INPUT/OUTPUT PARAMETERS: character(*),optional,intent(IN) :: string ! abort message integer, optional,intent(IN) :: rcode ! NetCDF error code !EOP !--- local --- character(SHR_KIND_CL) :: lstring character(*),parameter :: subName = "(shr_ncio_abort)" character(*),parameter :: F00 = "('(shr_ncio_abort) ',a)" !------------------------------------------------------------------------------- ! Notes: !------------------------------------------------------------------------------- if (present(rcode))then if ( rcode == nf90_noerr )then return else write(s_logunit,'(a,a,i3)') subname, ' : NetCDF error code = ', rcode end if end if lstring = '' if (present(string)) lstring = string if (doAbort) then call shr_sys_abort(lstring) else write(s_logunit,F00) ' no abort:'//trim(lstring) endif end subroutine shr_ncio_abort !=============================================================================== !=============================================================================== END MODULE shr_ncio_mod