|
CGpop mini-Application (2-sided MPI 1D data structure version) 0.1
|
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 !|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1.7.4