! module input_module implicit none #include "mksrc.h" ! ! User input: ! character(len=lenpath) :: | histfile_read, | msspath_read, | histfile_write, | msspath_write real :: | dlon_in,dlat_in, ! input horizontal resolutions | dlon_out,dlat_out, ! output horizontal resolutions | vertical_in, vertical_out ! input,output vertical resolutions integer :: mtimes(3,mxhist) ! histories to read/write (day,hr,min) ! ! Namelist for user input read: namelist/mksrc_input/ histfile_read, msspath_read, histfile_write, | msspath_write, mtimes, dlon_in, dlat_in, dlon_out, dlat_out, | vertical_in, vertical_out ! ! Flags for horizontal and/or vertical interpolation: integer :: interp_horizontal=0, interp_vertical=0 contains !----------------------------------------------------------------------- subroutine input ! use readhist_module,only: mkdiskflnm ! is in readhist.oldhist ! ! Namelist inputs: ! ! histfile_read: Local input disk file to read. If this file does not exist, ! msspath_read will be read from mss to this disk file). If histfile_read ! is not provided, msspath_read must be provided (in this case, msspath_read ! will be read from mss to the cwd). ! ! msspath_read: Mss path of file to read. If histfile_read is not ! found, msrcp will be called to read this file from mss to disk file ! histfile_read. If msspath_read is not provided, file will not be ! read from mss (in this case, histfile_read must exist). ! ! histfile_write: Local disk file to write output (if it pre-exists, it ! will be overwritten). If histfile_write is not provided, msspath_write ! must be provided (histfile_write in cwd will be constructed from ! msspath_write). Be sure to provide a path with enough disk space (or ! run the program from a directory with plenty of disk space). ! ! msspath_write: Mss path to which output file is to be disposed. ! (will dispose histfile_write to this path). If msspath_write is not ! provided, the disk file will not be disposed to the mss. ! ! dlon_in,dlat_in: Horizontal resolution (delta degrees lat and lon) of ! input file. ! ! dlon_out,dlat_out: Horizontal resolution (delta degrees lat and lon) of ! output file. ! ! vertical_in: Vertical resolution (ln(p/p0)) of input file, e.g., 0.5. ! ! vertical_out: Vertical resolution (ln(p/p0)) of output file, e.g., 0.25. ! If vertical_in == vertical_out, then no inpterpolation will be performed ! in the vertical dimension. ! ! mtimes: model time(s) (day,hour,min) of input and output histories. ! integer :: i,luin=7 ! ! Init: histfile_read = ' ' ; histfile_write = ' ' msspath_read = ' ' ; msspath_write = ' ' dlon_in = spval ; dlat_in = spval dlon_out = spval ; dlat_out = spval vertical_in = spval vertical_out = spval mtimes(:,:) = ispval ! ! Remove comments from user input file: call rmcomments(5,luin,';',1) ! ! Namelist read: write(6,"(/,'Doing namelist read...')") read(luin,nml=mksrc_input) ! ! Validate user namelist input: if (dlon_in==spval.or.dlat_in==spval) then write(6,"('>>> INPUT: need dlon_in and dlat_in.')") stop 'input' endif if (dlon_out==spval.or.dlat_out==spval) then write(6,"('>>> INPUT: need dlon_out and dlat_out.')") stop 'input' endif if (vertical_in==spval.or.vertical_out==spval) then write(6,"(/,'>>> INPUT: need vertical_in and ', | 'vertical_out')") write(6,"('Input and output vertical resolutions (degrees)')") write(6,"('(at least one of these is invalid or was not ', | 'read)')") stop 'input' endif ! ! Must have either histfile_read or msspath_read: if histfile_read is ! blank, use default disk file name constructed from msspath_read. ! If msspath_read is blank, do not access mss (see sub getfile) ! if (len_trim(histfile_read)==0.and.len_trim(msspath_read)==0)then write(6,"(/,'>>> INPUT: need histfile_read and/or ', | 'msspath_read',/,'(both of these are blank')") stop 'input' endif ! ! Must have either histfile_write or msspath_write: if histfile_write ! is blank, construct a name now from msspath_write. If msspath_write ! is blank, file will not be disposed to mss (see sub putms) ! if (len_trim(histfile_write)==0.and.len_trim(msspath_write)==0) | then write(6,"(/,'>>> INPUT: need histfile_write and/or ', | 'msspath_write (both of these are blank')") stop 'input' endif if (len_trim(histfile_write)==0) then call mkdiskflnm(msspath_write,histfile_write) write(6,"('Input: made diskfile write name from msspath_write', | ': histfile_write=',a)") trim(histfile_write) endif ! if (all(mtimes==ispval)) then write(6,"(/,'>>> INPUT: need mtimes(3,*) model time(s) ', | '(day,hour,minute)')") stop 'input' endif do i=1,mxhist if (any(mtimes(:,i)/=ispval)) then if (any(mtimes(:,i)==ispval)) then write(6,"(/,'>>> INPUT: Please provide mtimes(3,i) in', | ' triplets (day,hour,minutes)')") stop 'input' endif endif enddo if (dlon_out > dlon_in) then write(6,"(/,'>>> INPUT: dlon_out must be < ', | ' dlon_in')") write(6,"('dlon_in=',f8.2,' dlon_out=', | f8.2)") dlon_in,dlon_out stop 'input' endif if (dlat_out > dlat_in) then write(6,"(/,'>>> INPUT: dlat_out must be < ', | ' dlat_in')") write(6,"('dlat_in=',f8.2,' dlat_out=', | f8.2)") dlat_in,dlat_out stop 'input' endif if (vertical_out > vertical_in) then write(6,"(/,'>>> INPUT: vertical_out must be < ', | ' vertical_in')") write(6,"('vertical_in=',f8.2,' vertical_out=', | f8.2)") vertical_in,vertical_out write(6,"('If you do not want to interpolate in the ', | 'vertical, comment out vertical_in and vertical_out.')") stop 'input' endif ! write(6,"('Namelist read complete.',/)") write(6,"('histfile_read = ',a)") trim(histfile_read) write(6,"('msspath_read = ',a)") trim(msspath_read) write(6,"('histfile_write = ',a)") trim(histfile_write) write(6,"('msspath_write = ',a)") trim(msspath_write) write(6,"('dlon_in,dlat_in = ',2f6.2)") dlon_in,dlat_in write(6,"('dlon_out,dlat_out= ',2f6.2)") dlon_out,dlat_out write(6,"('vertical_in = ',f6.2)") vertical_in write(6,"('vertical_out = ',f6.2)") vertical_out ! if (dlon_in /= dlon_out .or. dlat_in /= dlat_out) | interp_horizontal=1 if (vertical_in /= vertical_out ) interp_vertical=1 if (interp_horizontal==0.and.interp_vertical==0) then write(6,"(/,'>>> INPUT: input and output grids are the same:', | /,' dlon_in=',f8.2,' dlon_out=',f8.2, | /,' dlat_in=',f8.2,' dlat_out=',f8.2, | /,' vertical_in=',f8.2,' vertical_out=',f8.2)") | dlon_in,dlon_out,dlat_in,dlat_out,vertical_in,vertical_out write(6,"('No interpolation is necessary -- stopping')") stop 'no interp' endif if (interp_horizontal==1) then if (dlon_in /= dlon_out) then write(6,"('Will change longitude grid from ',f6.2, | ' to ',f6.2)") dlon_in,dlon_out endif if (dlat_in /= dlat_out) then write(6,"('Will change latitude grid from ',f6.2, | ' to ',f6.2)") dlat_in,dlat_out endif endif if (interp_vertical==1) then write(6,"('Will interpolate in vertical from ',f8.2, | ' to ',f8.2)") vertical_in,vertical_out else write(6,"('NOT interpolating in vertical: vertical ', | 'resolution will remain at ',f8.2)") vertical_out endif end subroutine input !------------------------------------------------------------------- subroutine rmcomments(luin,luout,comcharin,echo) implicit none ! ! Read input lines from unit lu. If current line contains the comment ! character comcharin, strip the line from position of comchar to end, ! and write any remaining line to a new unit. If no comment in current ! line, write entire line to new unit. ! Return new unit, rewound (e.g., ready to be read by namelist). ! If echo > 0, echo output lines to stdout. ! If comcharin is ' ', then default comment char is ';' ! ! Args: integer,intent(in) :: luin,luout,echo character(len=1),intent(in) :: comcharin ! Local: character(len=1) :: comchar logical isopen integer :: i,lens,ios,compos,nline,nlcfields character*80 line character(len=64) :: newcfields(30) ! if (luin <= 0) then write(6,"('>>> rmcomments: bad input luin=',i5)") luin stop 'rmcomments' endif if (luout <= 0) then write(6,"('>>> rmcomments: bad input luout=',i5)") luout stop 'rmcomments' endif if (len_trim(comcharin) > 0) then comchar = comcharin else comchar = ';' write(6,"('rmcomments: using default semicolon as ', + 'comment character.')") endif inquire(unit=luin,opened=isopen) if (.not.isopen) then open(unit=luin,iostat=ios) if (ios /= 0) then write(6,"('>>> WARNING rmcomments: error opening input', + ' file with unit luin=',i2,' ios=',i5)") luin,ios stop 'rmcomments' endif endif nline = 0 read_loop: do line = ' ' read(luin,"(a)",iostat=ios) line if (ios > 0) then write(6,"('>>> rmcomments: error reading from input', + ' unit luin=',i3,' at line ',i5)") luin,nline return endif if (ios < 0) exit read_loop ! eof nline = nline+1 ! ! Remove line if it has only "E" in column 1 (this was an ! old "Echo" directive from f77/cray namelist): ! if (line(1:1)=='E'.and.trim(line)=='E') cycle read_loop ! ! Use only non-commented part of line: ! compos = index(line,comchar) if (compos == 1) cycle read_loop if (compos > 0) line = line(1:compos-1) if (len_trim(adjustl(line))==0) cycle read_loop ! ! Write to new unit: write(luout,"(a)") trim(line) if (echo > 0) write(6,"(a)") line(1:len_trim(line)) enddo read_loop rewind luout return end subroutine rmcomments end module input_module !----------------------------------------------------------------------- subroutine mkdiskflnm(msspath,diskname) implicit none ! ! Given a mss path (msspath), construct and return a local ! file name (diskname) which is the same as msspath except ! that slashes ('/') in the msspath are replaced by dots ('.') ! in the diskname. (The initial slash in msspath is ignored) ! ! For example, if on input msspath = '/FOSTER/dir1/file', then ! diskname would be returned as 'FOSTER.dir1.file' ! ! Args: character(len=*),intent(in) :: msspath character(len=*),intent(out) :: diskname ! ! Local: integer :: lmsspath,i,ii ! lmsspath = len_trim(msspath) if (lmsspath==0) then write(6,"('WARNING mkdiskflnm: zero length msspath.', + ' Returning diskname: ''disk.file''')") diskname = 'disk.file' return endif diskname = ' ' do i=1,len(diskname) ! ! Do not replace leading slash of msspath. ! If there are no occurrences of '/' in the msspath (i.e., its ! not really an mss path, but just a file name), return the ! msspath unchanged. ! ii = i+1 if (index(msspath,'/')==0) ii = i if (ii > lmsspath) exit if (msspath(ii:ii)=='/') then diskname(i:i)='.' else diskname(i:i) = msspath(ii:ii) endif enddo if (len_trim(diskname)==0) then write(6,"('WARNING mkdiskflnm: zero length diskname output.')") write(6,"(' msspath=',a)") trim(msspath) write(6,"('Returning diskname: ''disk.file''')") diskname = 'disk.file' endif ! write(6,"('mkdiskflnm returning:',/,' msspath=',a, ! + /,' diskname=',a)") trim(msspath),trim(diskname) end subroutine mkdiskflnm