!----- AGPL -------------------------------------------------------------------- ! ! Copyright (C) Stichting Deltares, 2015. ! ! This file is part of Delft3D (D-Flow Flexible Mesh component). ! ! Delft3D is free software: you can redistribute it and/or modify ! it under the terms of the GNU Affero General Public License as ! published by the Free Software Foundation version 3. ! ! Delft3D is distributed in the hope that it will be useful, ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! GNU Affero General Public License for more details. ! ! You should have received a copy of the GNU Affero General Public License ! along with Delft3D. If not, see . ! ! contact: delft3d.support@deltares.nl ! Stichting Deltares ! P.O. Box 177 ! 2600 MH Delft, The Netherlands ! ! All indications and logos of, and references to, "Delft3D", ! "D-Flow Flexible Mesh" and "Deltares" are registered trademarks of Stichting ! Deltares, and remain the property of Stichting Deltares. All rights reserved. ! !------------------------------------------------------------------------------- ! $Id: unstruc_files.f90 42642 2015-10-21 11:34:20Z dam_ar $ ! $HeadURL: https://repos.deltares.nl/repos/ds/trunk/additional/unstruc/src/unstruc_files.f90 $ module unstruc_files !! Centralizes unstruc file management (formerly in REST.F90) use unstruc_messages use unstruc_version_module implicit none integer, parameter :: ERR_FILENOTEXIST = 1 integer, parameter :: ERR_FILEALREADYOPEN = 2 integer, parameter :: ERR_FILEACCESSDENIED= 3 integer, parameter :: maxlength = 256 !< Max length of a file name (not checked upon). integer :: maxnum = 0 !< Current length of filenames list. character(maxlength), dimension(:), allocatable :: filenames integer :: mdia = 0 !< File pointer to .dia file integer :: mini = 0 !< File pointer to .ini file integer :: mhlp = 0 !< File pointer to help file character(len=60) :: pathdi ! TODO: AvD: TEMP. moved from hwsw.inc contains subroutine init_unstruc_files() end subroutine init_unstruc_files !> Registers in the filenames list that a file is opened. !! Use this instead of directly writing in the list (automatic realloc). !! The actual open is not performed here. subroutine reg_file_open(mfil, filename) use m_alloc integer, intent(in) :: mfil !< File unit number (e.g., from numuni) character(len=*), intent(in) :: filename if (mfil > maxnum) then MAXNUM = MFIL + 50 call realloc(filenames, maxnum, fill=' ') end if filenames(mfil) = filename end subroutine !> 'Unregisters' a file name from the list upon closing. !! The actual close is not performed here. subroutine reg_file_close(mfil) integer, intent(in) :: mfil filenames(mfil) = ' ' end subroutine !> Closes all remaining files in the file list. subroutine close_all_files() integer :: mfil do mfil = maxnum,1,-1 if ( mfil.ne.mdia) then ! SPvdP: need to close dia-file last close(mfil) ! No need to check file status, just attempt to close. if (filenames(mfil) /= ' ') then call mess(LEVEL_INFO, 'Closed file : ', filenames(mfil)) end if end if end do if ( allocated(filenames) ) deallocate(filenames) maxnum = 0 end subroutine close_all_files !> Proposes a filename for a certain file type. !! If a similar file was previously loaded, that same filename is returned. !! Otherwise, the basename of the model definition is used with an appropriate suffix. !! Otherwise, a wildcard is returned. TODO [AvD] !! !! When an output directory is configured, the filename is also prefixed with that, unless switched off by prefixWithDirectory=.false.. function defaultFilename(filecat, timestamp, prefixWithDirectory, allowWildcard) use unstruc_model use m_flowtimes implicit none character(len=*), intent(in) :: filecat !< File category for which the filename is requested, e.g. 'obs', 'map', 'hyd'. logical, optional, intent(in) :: prefixWithDirectory !< Optional, default true. Prefix file name with the configured output directory. Set this to .false. to get purely the filename. logical, optional, intent(in) :: allowWildcard !< Optional, default false. Allow the result to fall back to *., in case no model id or other basename could be found. double precision, optional, intent(in) :: timestamp !< Optional, default disabled. Form a datetime string out of the timestamp (in seconds) and include it in the filename. character(len=255) :: activeFile character(len=255) :: basename character(len=16) :: suffix character(len=255) :: defaultFilename character(len=16) :: dateandtime integer :: L logical :: prefix_dir if (present(prefixWithDirectory)) then prefix_dir = prefixWithDirectory else prefix_dir = .true. end if activeFile = ' ' basename = ' ' suffix = ' ' defaultFilename = ' ' select case (trim(filecat)) case ('obs') activeFile = md_obsfile suffix = '_obs.xyn' case ('bal') activeFile = '' suffix = '.bal' case ('map') activeFile = md_mapfile suffix = '_map.nc' case ('fou') activeFile = '' suffix = '_fou.nc' case ('avgwavquant') !! JRE activeFile = md_avgwavquantfile suffix = '_wav.nc' case ('tec') activeFile = '' suffix = '.dat' case ('map.plt') activeFile = md_mapfile suffix = '_map.plt' case ('net.plt') activeFile = md_mapfile suffix = '_net.plt' case ('net') activeFile = md_netfile suffix = '_net.nc' case ('waqgeom') activeFile = '' suffix = '_waqgeom.nc' case ('ldb') activeFile = md_ldbfile suffix = '.ldb' case ('rstold') activeFile = '' suffix = '.rst' case ('rst') activeFile = md_restartfile suffix = '_rst.nc' case ('his') activeFile = md_hisfile suffix = '_his.nc' case ('inc_s1') activeFile = '' suffix = '_inc_s1.nc' case ('bot') activeFile = '' suffix = '.xyb' case ('_lev.xyz') activeFile = '' suffix = '_lev.xyz' ! dus.. case ('com') activeFile = md_comfile suffix = '_com.nc' ! Delwaq files: filecat is identical to file extension case ('hyd','vol','are','flo','poi','len','srf','tau','vdf','tem','sal','atr','bnd') if (prefix_dir) then basename = 'DFM_DELWAQ_'//trim(md_ident)//trim(rundat2) end if basename = trim(basename)//trim(md_waqfilebase) suffix = '.'//trim(filecat) end select if (present(timestamp)) then dateandtime = '_' call maketime(dateandtime(2:), timestamp) else dateandtime = ' ' end if ! Now choose the most sensible filename: if (len_trim(activeFile) > 0) then ! File of this type already active, use that one. defaultFileName = activeFile elseif (len_trim(basename) > 0) then ! Create new filename, based on a certain prefix/basename defaultFileName = trim(basename)//trim(dateandtime)//suffix elseif (len_trim(md_ident) > 0) then ! No active, no basename, use md_ident as basename defaultFilename = trim(md_ident)//trim(dateandtime)//suffix elseif (len_trim(md_ident) == 0) then ! Not even a md_ident, use basename as basename defaultFilename = trim(unstruc_basename)//trim(dateandtime)//suffix else if(present(allowWildcard)) then ! Final resort: just a wildcard with proper file extention. if (allowWildcard) then defaultFilename = '*'//suffix end if end if ! Output files are generally stored in a subfolder, so prefix them here with that. select case (trim(filecat)) case ('his', 'map', 'rstold', 'rst', 'bal', 'inc_s1', 'tec', 'map.plt', 'net.plt', 'avgwavquant', 'com') !! JRE if (prefix_dir) then defaultFilename = trim(getoutputdir())//trim(defaultFilename) end if end select end function defaultFilename !> Initializes file pointer to diagnostics file. !! !! The filename is determined by the program name and possibly a sequence !! number. File-open attempts will not continue indefinitely (program may stop). subroutine inidia(basename) use unstruc_model character(len=*) :: basename integer, external :: numuni integer :: ierr integer :: jscr integer :: k integer :: L integer :: m ! integer :: numuni CHARACTER(*) FILENAME*256, BASE*256 character(*) RW*20 if (mdia > 0) return mdia = numuni() L = len_trim(md_ident) if (L == 0) then base = trim(basename) L = len_trim(basename) else base = trim(md_ident) end if filename = trim(base)//'.dia' K = 0 ierr = 0 10 OPEN(mdia, FILE=trim(filename), action='readwrite', IOSTAT=ierr) inquire(mdia, readwrite=rw) IF (ierr .GT. 0 .or. trim(rw)/='YES') THEN K = K + 1 filename = basename(1:l)//'_000.dia' WRITE(filename(L+2:L+4),'(I3.3)') K GOTO 10 ENDIF if (k > 0) then write (*,*) 'Warning: could not open default diagnostics file.' write (*,*) 'Now using '''//trim(filename)//''' instead.' end if call initMessaging(mdia) end subroutine inidia !> Constructs the full path to a file in the system directory. subroutine sysfilepath(filename, fullpath) character(len=*), intent(in) :: filename character(len=*), intent(out) :: fullpath fullpath = trim(pathdi)//trim(filename) end subroutine sysfilepath SUBROUTINE SYSFIL(LUNID,FILNAM) integer :: lunid CHARACTER :: FILNAM*76 integer, external :: numuni character :: FULNAM*180 logical :: ja call sysfilepath(filnam, fulnam) INQUIRE(FILE= FULNAM,EXIST=JA) IF (JA) THEN LUNID = NUMUNI() OPEN(LUNID,FILE= FULNAM) call reg_file_open(lunid, fulnam) ENDIF RETURN END SUBROUTINE SYSFIL !> Constructs the full path to a file in the system directory. function getfilename(ftype, success) character(len=255) :: getfilename character(len=*), intent(in) :: ftype logical, optional, intent(out) :: success ! fullpath = trim(pathdi)//trim(filename) getfilename='todo' success = .true. end function getfilename !> Gets the basename of a file. By default this is the filename without its extension. !! Optionally, a file category may be specified, such that e.g., '_net.nc' !! is stripped off (instead of .nc only) subroutine basename(filename, filebase, filecat) implicit none character(len=*), intent(in) :: filename character(len=*), intent(out) :: filebase character(len=*), optional, intent(in) :: filecat character(1), external :: get_dirsep integer :: L1,L2 ! Strip off file extension L2 = len_trim(filename) if (present(filecat)) then select case (trim(filecat)) case ('net') L2 = L2 - 7 ! '_net.nc' case default L2 = index(filename, '.', .true.)-1 end select else L2 = index(filename, '.', .true.)-1 end if ! Also strip off any preceding dir names. L1 = index(filename, get_DIRSEP(), .true.)+1 filebase = ' ' filebase = filename(L1:L2) end subroutine basename !> get output directory function getoutputdir() use m_flowtimes use unstruc_model implicit none character(len=255) :: getoutputdir character(len=1), external :: get_dirsep call datum2(rundat2) if ( len_trim(md_outputdir)==0 ) then ! default if ( len_trim(md_ident_sequential) > 0 ) then getoutputdir = 'DFM_OUTPUT_'//trim(md_ident_sequential)//trim(rundat2) else getoutputdir = 'DFM_OUTPUT_'//trim(rundat2) end if else getoutputdir = trim(md_outputdir)//get_dirsep() end if return end function getoutputdir end module unstruc_files !> !> Find out if system is PC (directory seperator character \ (92) !> or UNIX (directory seperator character / (47)) function get_dirsep() implicit none character(len=1) :: get_dirsep integer :: nval, lslash CHARACTER FILNAM*76 character errtxt*8,arch*10,hlpstr*999,slash*1 CALL GET_ENVIRONMENT_VARIABLE('PATH',hlpstr) slash = CHAR (47) lslash = INDEX (hlpstr,slash) if (lslash .eq. 0) then slash = CHAR (92) endif get_dirsep = slash end function get_dirsep