CGpop mini-Application (2-sided MPI 1D data structure version) 0.1
IOUnitsMod.F90
Go to the documentation of this file.
00001 !==============================================================================
00002 ! Copyright (C) 2010, University Corporation for Atmospheric Research,
00003 !                     Colorado State University,
00004 !                     Los Alamos National Security, LLC,
00005 !                     United States Department of Energy
00006 !
00007 ! All rights reserved.  See ../COPYING for copyright details
00008 !==============================================================================
00009 
00010 !|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
00011 
00012 !>
00013 !! I/O unit manager for tracking, assigning and reserving I/O unit numbers.
00014 !!
00015 !! There are three reserved I/O units set as parameters in this
00016 !! module.  The default units for standard input (stdin), standard
00017 !! output (stdout) and standard error (stderr).  These are currently
00018 !! set as units 5,6,6, respectively as that is the most commonly
00019 !! used among vendors. However, the user may change these if those
00020 !! default units are conflicting with other models or if the
00021 !! vendor is using different values.
00022 !!
00023 !! The maximum number of I/O units per node is currently set by
00024 !! the parameter POP\_IOMaxUnits.
00025 !<
00026  module IOUnitsMod
00027 
00028 ! !USES:
00029 
00030    use kinds_mod, only: i4, log_kind
00031 
00032    implicit none
00033    private
00034    save
00035 
00036 ! !PUBLIC MEMBER FUNCTIONS:
00037 
00038    public :: IOUnitsGet,                &
00039              IOUnitsRelease,            &
00040              IOUnitsFlush
00041 
00042 ! !PUBLIC DATA MEMBERS:
00043 
00044    integer (i4), parameter, public :: 
00045       stdin  =  5,  ! reserved unit for standard input
00046       stdout =  6,  ! reserved unit for standard output
00047       stderr =  6,  ! reserved unit for standard error
00048       nmlin  = 10
00049 
00050    ! common formats for writing to stdout, stderr
00051 
00052    character (9), parameter, public ::   
00053       delimFormat    = "(72('-'))",  
00054       delimFormatNew = "(72('='))"
00055 
00056    character (5), parameter, public :: 
00057       blankFormat = "(' ')" 
00058 
00059    character (7), parameter, public :: 
00060       nml_filename = 'pop_in'  ! namelist input file name
00061 
00062 
00063 !-----------------------------------------------------------------------
00064 !
00065 !  private io unit manager variables
00066 !
00067 !-----------------------------------------------------------------------
00068 
00069    integer (i4), parameter :: 
00070       IOUnitsMinUnits = 11,    ! do not use unit numbers below this
00071       IOUnitsMaxUnits = 99      ! maximum number of open units
00072 
00073    logical (log_kind) :: 
00074       IOUnitsInitialized = .false.
00075 
00076    logical (log_kind), dimension(IOUnitsMaxUnits) :: 
00077       IOUnitsInUse       ! flag=.true. if unit currently open
00078 
00079 !***********************************************************************
00080 
00081 contains
00082 
00083 !***********************************************************************
00084 
00085 !>
00086 !! This routine returns the next available i/o unit and marks it as
00087 !! in use to prevent any later use.
00088 !! Note that {\em all} processors must call this routine even if only
00089 !! the master task is doing the i/o.  This is necessary insure that
00090 !! the units remain synchronized for other parallel I/O functions.
00091 !!
00092 !! @param iunit  next free i/o unit
00093 !<
00094  subroutine IOUnitsGet(iunit)
00095 
00096    integer (i4), intent(out) :: 
00097       iunit
00098 
00099 !-----------------------------------------------------------------------
00100 !
00101 !  local variables
00102 !
00103 !-----------------------------------------------------------------------
00104 
00105    integer (i4) :: n  ! dummy loop index
00106 
00107    logical (log_kind) :: alreadyInUse
00108 
00109 !-----------------------------------------------------------------------
00110 !
00111 !  check to see if units initialized and initialize if necessary
00112 !
00113 !-----------------------------------------------------------------------
00114 
00115    if (.not. IOUnitsInitialized) then
00116       IOUnitsInUse = .false.
00117       IOUnitsInUse(stdin) = .true.
00118       IOUnitsInUse(stdout) = .true.
00119       IOUnitsInUse(stderr) = .true.
00120 
00121       IOUnitsInitialized = .true.
00122    endif
00123 
00124 !-----------------------------------------------------------------------
00125 !
00126 !  find next free unit
00127 !
00128 !-----------------------------------------------------------------------
00129 
00130    srch_units: do n=IOUnitsMinUnits, IOUnitsMaxUnits
00131       if (.not. IOUnitsInUse(n)) then   ! I found one, I found one
00132 
00133          !*** make sure not in use by library or calling routines
00134          INQUIRE (unit=n,OPENED=alreadyInUse)
00135 
00136          if (.not. alreadyInUse) then
00137             iunit = n        ! return the free unit number
00138             IOUnitsInUse(iunit) = .true.  ! mark iunit as being in use
00139             exit srch_units
00140          else
00141             !*** if inquire shows this unit in use, mark it as
00142             !***    in use to prevent further queries
00143             IOUnitsInUse(n) = .true.
00144          endif
00145       endif
00146    end do srch_units
00147 
00148    if (iunit > IOUnitsMaxUnits) stop 'IOUnitsGet: No free units'
00149 
00150 !-----------------------------------------------------------------------
00151 !EOC
00152 
00153  end subroutine IOUnitsGet
00154 
00155 !***********************************************************************
00156 
00157 !>
00158 !! This routine releases an i/o unit (marks it as available).
00159 !! Note that {\em all} processors must call this routine even if only
00160 !! the master task is doing the i/o.  This is necessary insure that
00161 !! the units remain synchronized for other parallel I/O functions.
00162 !!
00163 !! @param  iunit   i/o unit to be released
00164 !<
00165  subroutine IOUnitsRelease(iunit)
00166 
00167 ! !INPUT PARAMETER:
00168 
00169    integer (i4), intent(in) :: 
00170       iunit                    ! i/o unit to be released
00171 
00172 !-----------------------------------------------------------------------
00173 !
00174 !  check for proper unit number
00175 !
00176 !-----------------------------------------------------------------------
00177 
00178    if (iunit < 1 .or. iunit > IOUnitsMaxUnits) then
00179       stop 'IOUnitsRelease: bad unit'
00180    endif
00181 
00182 !-----------------------------------------------------------------------
00183 !
00184 !  mark the unit as not in use
00185 !
00186 !-----------------------------------------------------------------------
00187 
00188    IOUnitsInUse(iunit) = .false.  !  that was easy...
00189 
00190 !-----------------------------------------------------------------------
00191 
00192  end subroutine IOUnitsRelease
00193 
00194 !***********************************************************************
00195 
00196 !>
00197 !! This routine enables a user to flush the output from an IO unit
00198 !! (typically stdout) to force output when the system is buffering
00199 !! such output.  Because this system function is system dependent,
00200 !! we only support this wrapper and users are welcome to insert the
00201 !! code relevant to their local machine.  In the case where the CCSM
00202 !! libraries are available, the shared routine for sys flush can be
00203 !! used (and is provided here under a preprocessor option).
00204 !!
00205 !! @param iunit  i/o unit to be flushed
00206 !<
00207  subroutine IOUnitsFlush(iunit)
00208 
00209 ! !INPUT PARAMETER:
00210 
00211    integer (i4), intent(in) :: 
00212       iunit 
00213 
00214 !-----------------------------------------------------------------------
00215 !
00216 !  insert your system code here
00217 !
00218 !-----------------------------------------------------------------------
00219 
00220  end subroutine IOUnitsFlush
00221 
00222 !***********************************************************************
00223 
00224  end module IOUnitsMod
00225 
00226 !|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 All Classes Namespaces Files Functions Variables