XBeach
C:/repositories/XBeach/trunk/src/xbeachlibrary/readkey.F90
Go to the documentation of this file.
00001 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00002 ! Copyright (C) 2007 UNESCO-IHE, WL|Delft Hydraulics and Delft University !
00003 ! Dano Roelvink, Ap van Dongeren, Ad Reniers, Jamie Lescinski,            !
00004 ! Jaap van Thiel de Vries, Robert McCall                                  !
00005 !                                                                         !
00006 ! d.roelvink@unesco-ihe.org                                               !
00007 ! UNESCO-IHE Institute for Water Education                                !
00008 ! P.O. Box 3015                                                           !
00009 ! 2601 DA Delft                                                           !
00010 ! The Netherlands                                                         !
00011 !                                                                         !
00012 ! This library is free software; you can redistribute it and/or           !
00013 ! modify it under the terms of the GNU Lesser General Public              !
00014 ! License as published by the Free Software Foundation; either            !
00015 ! version 2.1 of the License, or (at your option) any later version.      !
00016 !                                                                         !
00017 ! This library is distributed in the hope that it will be useful,         !
00018 ! but WITHOUT ANY WARRANTY; without even the implied warranty of          !
00019 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU        !
00020 ! Lesser General Public License for more details.                         !
00021 !                                                                         !
00022 ! You should have received a copy of the GNU Lesser General Public        !
00023 ! License along with this library; if not, write to the Free Software     !
00024 ! Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307     !
00025 ! USA                                                                     !
00026 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00027 
00028 module readkey_module
00029 
00030    use typesandkinds, only: slen
00031    implicit none
00032    save
00033    private
00034    public readkey_int, readkey_name, readkey_dbl, isSetParameter, parmapply, readkey_dblvec, readkey_inio, strippedline
00035    public count_lines, readkey_intvec, lowercase, setallowednames, setoldnames, readkey, read_v
00036    ! before using any of the routines here, set readkey_inio
00037    ! .true. : value read will be broadcasted to all processes, including the
00038    !          output process.
00039    ! otherwise: the value will be broadcasted to the computational processes only
00040    !
00041    logical :: readkey_inio = .false.
00042 
00043    integer, parameter, private                   :: maxnames = 20
00044    character(slen), dimension(maxnames), private :: allowednames
00045    character(slen), dimension(maxnames), private :: oldnames
00046    character(slen), private                      :: varname
00047    integer,         dimension(maxnames), private :: intvalues
00048    integer, private                              :: numallowednames
00049    integer, private                              :: numoldnames
00050 
00051    interface read_v
00052       module procedure read_v_array
00053       module procedure read_v_9
00054    end interface read_v
00055 
00056 contains
00057    real*8 function readkey_dbl(fname,key,defval,mnval,mxval,bcast,required,silent,strict)
00058       ! if USEMPI then the master process will read the parameter,
00059       ! this value is subsequently broadcasted to the other processes
00060 
00061       use xmpi_module
00062       use logging_module, only: writelog, report_file_read_error
00063       implicit none
00064       character(len=*)  :: fname,key
00065       character(slen)     :: printkey
00066       real*8            :: defval,mnval,mxval
00067       logical, intent(in), optional :: bcast,required,silent,strict
00068 
00069       character(slen)   :: value,tempout
00070       real*8         :: value_dbl
00071       logical        :: lbcast,lrequired,lsilent,lstrict
00072       character(slen)  :: fmt
00073       integer          :: ier
00074 
00075       fmt = '(a,a,a,f0.4,a,f0.4)'
00076 
00077       if (present(bcast)) then
00078          lbcast = bcast
00079       else
00080          lbcast = .true.
00081       endif
00082 
00083       if (present(required)) then
00084          lrequired = required
00085       else
00086          lrequired = .false.
00087       endif
00088 
00089       if (present(silent)) then
00090          lsilent = silent
00091       else
00092          lsilent = .false.
00093       endif
00094 
00095       if (present(strict)) then
00096          lstrict = strict
00097       else
00098          lstrict = .false.
00099       endif
00100 
00101       !printkey=key
00102       printkey = ' '
00103       printkey(2:24)=trim(key)
00104       printkey(1:1)=' '
00105 
00106       if (xmaster) then
00107          call readkey(fname,key,value)
00108 
00109          if (value/=' ') then
00110             read(value,'(f10.0)',iostat=ier)value_dbl
00111             if (ier .ne. 0) then
00112                tempout = trim(fname)//' (value of '''//trim(printkey)//''' cannot be interpreted)'
00113                call report_file_read_error(tempout)
00114             endif
00115             if(lstrict .and. (value_dbl>mxval .or. value_dbl<mnval)) then
00116                call writelog('sle','(a,a,a,f0.4)','Value of ',trim(printkey),' is ',value_dbl)
00117                call writelog('sle','(a,a,f0.4,a,f0.4)',trim(printkey),' must be set between ',mnval,' and ',mxval)
00118                call writelog('sle','','Terminating simulation')
00119                call halt_program
00120             elseif (value_dbl>mxval) then
00121                call writelog('lw','(a24,a,f0.4,a,f0.4)',(printkey),' = ',value_dbl,' Warning: value > recommended value of ',mxval)
00122                call writelog('s','(a24,a,a,f0.4)','Warning: ',trim(printkey),' > recommended value of ',mxval)
00123             elseif (value_dbl<mnval) then
00124                call writelog('lw','(a24,a,f0.4,a,f0.4)',(printkey),' = ',value_dbl,' Warning: value < recommended value of ',mnval)
00125                call writelog('s','(a24,a,a,f0.4)','Warning: ',trim(printkey),' < recommended value of ',mnval)
00126             else
00127                call writelog('l','(a24,a,f0.4)',(printkey),' = ',value_dbl)
00128             endif
00129          else
00130             if (lrequired) then
00131                call writelog('lse','','Error: missing required value for parameter ',printkey)
00132                call halt_program
00133             else
00134                value_dbl=defval
00135                if (.not. lsilent) call writelog('l','(a24,a,f0.4,a)',(printkey),' = ', &
00136                value_dbl,' (no record found, default value used)')
00137             endif
00138          endif
00139          ! write to basic params data file
00140          !  write(pardatfileid,*)'f ',printkey,' ',value_dbl
00141       endif
00142 
00143 #ifdef USEMPI
00144       if (lbcast) then
00145          call xmpi_bcast(value_dbl,readkey_inio)
00146       endif
00147 #endif
00148 
00149       readkey_dbl=value_dbl
00150    end function readkey_dbl
00151 
00152    function readkey_int(fname,key,defval,mnval,mxval,bcast,required,silent,strict) result (value_int)
00153       use xmpi_module
00154       use logging_module
00155       implicit none
00156       character*(*)  :: fname,key
00157       character(slen)  :: printkey
00158       character(slen)  :: value
00159       integer*4      :: value_int
00160       integer*4      :: defval,mnval,mxval,ier
00161       logical, intent(in), optional :: bcast, required,silent,strict
00162       logical        :: lbcast,lrequired,lsilent,lstrict
00163       character(slen)  :: fmt,tempout
00164 
00165       fmt = '(a,a,a,i0,a,i0)'
00166 
00167       if (present(bcast)) then
00168          lbcast = bcast
00169       else
00170          lbcast = .true.
00171       endif
00172 
00173       if (present(required)) then
00174          lrequired = required
00175       else
00176          lrequired = .false.
00177       endif
00178 
00179       if (present(silent)) then
00180          lsilent = silent
00181       else
00182          lsilent = .false.
00183       endif
00184 
00185       if (present(strict)) then
00186          lstrict = strict
00187       else
00188          lstrict = .false.
00189       endif
00190 
00191       printkey = ' '
00192       printkey(2:24)=trim(key)
00193       printkey(1:1)=' '
00194       if (xmaster) then
00195          call readkey(fname,key,value)
00196 
00197          if (value/=' ') then
00198             read(value,'(i256)',iostat=ier)value_int
00199             if (ier .ne. 0) then
00200                tempout = trim(fname)//' (value of '''//trim(printkey)//''' cannot be interpreted)'
00201                call report_file_read_error(tempout)
00202             endif
00203             if(lstrict .and. (value_int>mxval .or. value_int<mnval)) then
00204                call writelog('sle','(a,a,a,i0)','Value of ',trim(printkey),' is ',value_int)
00205                call writelog('sle','(a,a,i0,a,i0)',trim(printkey),' must be set between ',mnval,' and ',mxval)
00206                call writelog('sle','','Terminating simulation')
00207                call halt_program
00208             elseif (value_int>mxval) then
00209                call writelog('lw',fmt,'Warning: variable ',(printkey),' ',value_int,' > recommended value of ',mxval)
00210                call writelog('s','(a24,a,a,i0)','Warning: ',trim(printkey),' > recommended value of ',mxval)
00211             elseif (value_int<mnval) then
00212                call writelog('lw',fmt,'Warning: variable ',(printkey),' ',value_int,' < recommended value of ',mnval)
00213                call writelog('s','(a24,a,a,i0)','Warning: ',trim(printkey),' < recommended value of ',mnval)
00214             else
00215                call writelog('l','(a24,a,i0)',(printkey),' = ',value_int)
00216             endif
00217          else
00218             if (lrequired) then
00219                call writelog('lse','','Error: missing required value for parameter ',printkey)
00220                call halt_program
00221             else
00222                value_int=defval
00223                if (.not. lsilent) call writelog('l','(a24,a,i0,a)',(printkey),' = ', &
00224                value_int,' (no record found, default value used)')
00225             endif
00226          endif
00227          ! write to basic params data file
00228          !  write(pardatfileid,*)'i ',printkey,' ',value_int
00229       endif
00230 #ifdef USEMPI
00231       if (lbcast) then
00232          call xmpi_bcast(value_int,readkey_inio)
00233       endif
00234 #endif
00235 
00236    end function readkey_int
00237 
00238    function readkey_str(fname,key,defval,nv,nov,allowed,old,bcast,required,silent) result (value_str)
00239       use xmpi_module
00240       use logging_module
00241       implicit none
00242       character*(*)  :: fname,key,defval
00243       character(slen)  :: value_str
00244       character(slen)   :: value
00245       integer*4      :: nv,nov,i,j
00246       character(slen),dimension(nv) :: allowed
00247       character(slen),dimension(nov):: old
00248       logical, intent(in), optional :: bcast,required,silent
00249       logical        :: lbcast,lrequired,passed,lsilent
00250       character(slen)  :: printkey
00251 
00252       printkey(2:slen)=key
00253       printkey(1:1)=' '
00254 
00255       if (present(bcast)) then
00256          lbcast = bcast
00257       else
00258          lbcast = .true.
00259       endif
00260 
00261       if (present(required)) then
00262          lrequired = required
00263       else
00264          lrequired = .false.
00265       endif
00266 
00267       if (present(silent)) then
00268          lsilent = silent
00269       else
00270          lsilent = .false.
00271       endif
00272 
00273       passed = .false.
00274       if (xmaster) then
00275          call readkey(fname,key,value)
00276          ! Change to lowercase
00277          value =  lowercase(value)
00278          if (value == ' ') then
00279             if (lrequired) then
00280                call writelog('lse','','Error: missing required value for parameter ',printkey)
00281                call halt_program
00282             else
00283                value_str=defval
00284                if (.not. lsilent) call writelog('l','(a24,a,a,a)',(printkey),' = ', &
00285                trim(value_str),' (no record found, default value used)')
00286             endif
00287          else
00288             value=adjustl(value)
00289             do i=1,nv
00290                if (trim(value)==trim(allowed(i))) then
00291                   passed = .true.
00292                   value_str = value
00293                endif
00294             enddo
00295             do j=1,nov
00296                if (trim(value)==trim(old(j))) then
00297                   passed = .true.
00298                   value_str = allowed(j)
00299                endif
00300             enddo
00301             if (passed) then
00302                call writelog('l','(a24,a,a)',printkey,' = ',trim(value_str))
00303             else
00304                call writelog('sle','(a24,a,a,a)','Invalid option for ',trim(printkey),' : ',trim(value))
00305                call writelog('sle','(a24,a,a)','Valid options for ',trim(printkey),' are:')
00306                do i=1,nv
00307                   call writelog('sle','(a24)',trim(allowed(i)))
00308                enddo
00309                do j=1,nov
00310                   call writelog('sle','(a24)',trim(old(j)))
00311                enddo
00312                call halt_program
00313             endif
00314          endif
00315          ! write to basic params data file
00316          !  write(pardatfileid,*)'c ',printkey,' ',value_str
00317       endif
00318 #ifdef USEMPI
00319       if (lbcast) then
00320          call xmpi_bcast(value_str,readkey_inio)
00321       endif
00322 #endif
00323    end function readkey_str
00324 
00325 
00326    function readkey_name(fname,key,bcast,required,silent) result (value_str)
00327       use xmpi_module
00328       use logging_module
00329       implicit none
00330       character*(*)  :: fname,key
00331       character(slen)  :: value_str
00332       character(slen)   :: value
00333       logical, intent(in), optional :: bcast,required,silent
00334       logical        :: lbcast,lrequired,lsilent
00335       character(slen)  :: printkey
00336 
00337       printkey(2:slen)=key
00338       printkey(1:1)=' '
00339 
00340       if (present(bcast)) then
00341          lbcast = bcast
00342       else
00343          lbcast = .true.
00344       endif
00345 
00346       if (present(required)) then
00347          lrequired = required
00348       else
00349          lrequired = .false.
00350       endif
00351 
00352       if (present(silent)) then
00353          lsilent = silent
00354       else
00355          lsilent = .false.
00356       endif
00357 
00358       if (xmaster) then
00359          call readkey(fname,key,value)
00360          if (value == ' ') then
00361             if (lrequired) then
00362                call writelog('lse','','Error: missing required value for parameter ',printkey)
00363                call halt_program
00364             else
00365                value_str=' '
00366                if (.not. lsilent) call writelog('l',' (a24,a)'    ,printkey,' = None specified')
00367                ! write to basic params data file
00368                !    write(pardatfileid,*)'c ',key,' ','none'
00369             endif
00370          else
00371             value_str=adjustl(value)
00372             call writelog('l','(a24,a,a)',printkey,' = ',trim(value_str))
00373             ! write to basic params data file
00374             !    write(pardatfileid,*)'c ',printkey,' ',value_str
00375          endif
00376       endif
00377 #ifdef USEMPI
00378       if (lbcast) then
00379          call xmpi_bcast(value_str,readkey_inio)
00380       endif
00381 #endif
00382    end function readkey_name
00383 
00384    function readkey_dblvec(fname,key,vlength,tlength,defval,mnval,mxval,bcast,required,silent) result (value_vec)
00385       use xmpi_module
00386       use logging_module
00387       implicit none
00388       character*(*)  :: fname,key
00389       integer, intent(in) :: vlength,tlength
00390       real*8,dimension(tlength)  :: value_vec
00391       real*8            :: defval,mnval,mxval
00392       logical, intent(in), optional :: bcast,required,silent
00393       logical        :: lbcast,lrequired,lsilent
00394 
00395       integer          :: i, ioerr
00396       character(slen)   :: value
00397       character(slen)  :: printkey
00398 
00399       printkey(2:slen)=key
00400       printkey(1:1)=' '
00401 
00402       if (present(bcast)) then
00403          lbcast = bcast
00404       else
00405          lbcast = .true.
00406       endif
00407 
00408       if (present(required)) then
00409          lrequired = required
00410       else
00411          lrequired = .false.
00412       endif
00413 
00414       if (present(silent)) then
00415          lsilent = silent
00416       else
00417          lsilent = .false.
00418       endif
00419 
00420       if (xmaster) then
00421          call readkey(fname,key,value)
00422          if (value/=' ') then
00423             read(value,*,IOSTAT=ioerr)value_vec(1:vlength)
00424             if (ioerr < 0) then
00425                call writelog('lse','','Error reading value for parameter ',printkey)
00426                call writelog('lse','','Check whether parameter is given sufficient number of input values')
00427                call halt_program
00428             endif
00429             do i=1,vlength
00430                if (value_vec(i)>mxval) then
00431                   call writelog('lw','(a24,a,f0.4,a,f0.4)',(printkey),' = ',value_vec(i), &
00432                   ' Warning: value > recommended value of ',mxval)
00433                   call writelog('s','(a24,a,a,f0.4)','Warning: ',trim(printkey),' > recommended value of ',mxval)
00434                elseif (value_vec(i)<mnval) then
00435                   call writelog('lw','(a24,a,f0.4,a,f0.4)',(printkey),' = ',value_vec(i), &
00436                   ' Warning: value < recommended value of ',mnval)
00437                   call writelog('s','(a24,a,a,f0.4)','Warning: ',trim(printkey),' < recommended value of ',mnval)
00438                else
00439                   call writelog('l','(a24,a,f0.4)',(printkey),' = ',value_vec(i))
00440                endif
00441             enddo
00442          else
00443             if (lrequired) then
00444                call writelog('lse','','Error: missing required value for parameter ',printkey)
00445                call halt_program
00446             else
00447                value_vec(1:vlength)=defval
00448                do i=1,vlength
00449                   if (.not. lsilent) call writelog('l','(a,a,f0.4,a)',(printkey),' = ', &
00450                   value_vec(i),' (no record found, default value used)')
00451                enddo
00452             endif
00453          endif
00454       endif
00455 
00456 #ifdef USEMPI
00457       if (lbcast) then
00458          do i=1,vlength
00459             call xmpi_bcast(value_vec(i),readkey_inio)
00460          enddo
00461       endif
00462 #endif
00463    end function readkey_dblvec
00464 
00465    function readkey_intvec(fname,key,vlength,tlength,defval,mnval,mxval,bcast,required,silent) result (value_vec)
00466       use xmpi_module
00467       use logging_module, only: writelog
00468       implicit none
00469       character*(*)  :: fname,key
00470       integer, intent(in) :: vlength,tlength
00471       integer,dimension(tlength)  :: value_vec
00472       integer           :: defval,mnval,mxval
00473       logical, intent(in), optional :: bcast,required,silent
00474       logical        :: lbcast,lrequired,lsilent
00475 
00476       integer          :: i, ioerr
00477       character(slen)   :: value
00478       character(slen)  :: printkey
00479 
00480       printkey(2:slen)=key
00481       printkey(1:1)=' '
00482 
00483       if (present(bcast)) then
00484          lbcast = bcast
00485       else
00486          lbcast = .true.
00487       endif
00488 
00489       if (present(required)) then
00490          lrequired = required
00491       else
00492          lrequired = .false.
00493       endif
00494 
00495       if (present(silent)) then
00496          lsilent = silent
00497       else
00498          lsilent = .false.
00499       endif
00500 
00501       if (xmaster) then
00502          call readkey(fname,key,value)
00503          if (value/=' ') then
00504             read(value,*,IOSTAT=ioerr)value_vec(1:vlength)
00505             if (ioerr < 0) then
00506                call writelog('lse','','Error reading value for parameter ',printkey)
00507                call writelog('lse','','Check whether parameter is given sufficient number of input values')
00508                call halt_program
00509             endif
00510             do i=1,vlength
00511                if (value_vec(i)>mxval) then
00512                   call writelog('lw','(a24,a,i0,a,i0)',(printkey),' = ',value_vec(i), &
00513                   ' Warning: value > recommended value of ',mxval)
00514                   call writelog('s','(a24,a,a,i0)','Warning: ',trim(printkey),' > recommended value of ',mxval)
00515                elseif (value_vec(i)<mnval) then
00516                   call writelog('lw','(a24,a,i0,a,i0)',(printkey),' = ',value_vec(i), &
00517                   ' Warning: value < recommended value of ',mnval)
00518                   call writelog('s','(a24,a,a,i0)','Warning: ',trim(printkey),' < recommended value of ',mnval)
00519                else
00520                   call writelog('l','(a24,a,i0)',(printkey),' = ',value_vec(i))
00521                endif
00522             enddo
00523          else
00524             if (lrequired) then
00525                call writelog('lse','','Error: missing required value for parameter ',printkey)
00526                call halt_program
00527             else
00528                value_vec(1:vlength)=defval
00529                do i=1,vlength
00530                   if (.not. lsilent) call writelog('l','(a,a,i0,a)',(printkey),' = ', &
00531                   value_vec(i),' (no record found, default value used)')
00532                enddo
00533             endif
00534          endif
00535       endif
00536 
00537 #ifdef USEMPI
00538       if (lbcast) then
00539          do i=1,vlength
00540             call xmpi_bcast(value_vec(i),readkey_inio)
00541          enddo
00542       endif
00543 #endif
00544    end function readkey_intvec
00545 
00546    function isSetParameter(fname,key,bcast) result (isSet)
00547       ! Function return logical true if the keyword is specified in file,
00548       ! or logical false if the keyword is not specified in the file.
00549       use xmpi_module
00550       implicit none
00551       character*(*)   :: fname,key
00552       logical, intent(in), optional :: bcast
00553       logical         :: isSet
00554       character(slen)   :: value
00555       logical         :: lbcast
00556 
00557       isSet = .false.
00558       if (present(bcast)) then
00559          lbcast = bcast
00560       else
00561          lbcast = .true.
00562       endif
00563 
00564       if (xmaster) then
00565          call readkey(fname,key,value)
00566          if (value == ' ') then
00567             isSet = .false.
00568          else
00569             isSet = .true.
00570          endif
00571       endif
00572 #ifdef USEMPI
00573       if (lbcast) then
00574          call xmpi_bcast(isSet,readkey_inio)
00575       endif
00576 #endif
00577    end function isSetParameter
00578 
00579    !
00580    !  readkey is only to be called from master, ie:
00581    !  if(xmaster) then
00582    !    call readkey(....)
00583    !  No need to cache these results.
00584    !
00585    subroutine readkey(fname,key,value)
00586       ! Reads through input file (fname) looking for key = value combinations
00587       ! Return value as string
00588       ! Subroutine also used to keep track of which lines have been succesfully read
00589       ! If called by readkey('params.txt','checkparams'), will output unsuccesful key = value
00590       ! combinations in params.txt
00591       use xmpi_module
00592       use logging_module
00593       integer                                     :: lun,i,ier,nlines,ic,ikey,itab
00594       character*1                                 :: ch
00595       character(len=*), intent(in)                :: fname,key
00596       character(len=*), intent(out)               :: value
00597       character(slen), dimension(1024),save          :: keyword,values
00598       character(slen)                                :: line,lineWithoutSpecials
00599       integer, save                               :: nkeys
00600       character(slen), save                          :: fnameold=''
00601       integer, dimension(:),allocatable,save      :: readindex
00602 
00603       ! If the file name of the input file changes, the file should be reread
00604       if (fname/=fnameold) then
00605          ! Make sure this reset only recurs when the input file name changes
00606          fnameold=fname
00607          nkeys=0
00608          ier=0
00609          ! Read the file for all lines with "="
00610          call writelog('ls','','XBeach reading from ',trim(fname))
00611          lun=99
00612          i=0
00613          open(lun,file=fname)
00614          do while (ier==0)
00615             read(lun,'(a)',iostat=ier)ch
00616             if (ier==0)i=i+1
00617          enddo
00618          close(lun)
00619          nlines=i
00620          ! reset keyword values and readindex
00621          keyword = ''
00622          values = ''
00623          if (allocated(readindex)) deallocate(readindex)
00624          ! Read through the file to fill all the keyword = value combinations
00625          open(lun,file=fname)
00626          ikey=0
00627          do i=1,nlines
00628             read(lun,'(a)')line
00629             lineWithoutSpecials = strippedline(line)
00630             line = lineWithoutSpecials
00631             ic=scan(line,'=')
00632             if (ic>0) then
00633                ikey=ikey+1
00634                keyword(ikey)=adjustl(line(1:ic-1))
00635                values(ikey)=adjustl(line(ic+1:slen))
00636             endif
00637          enddo
00638          nkeys=ikey
00639          close(lun)
00640          ! allocate index vector that stores which values have succesfully been called to be read
00641          allocate(readindex(nkeys))
00642          readindex=0
00643       endif
00644 
00645       ! Compare the input key with any keyword stored in the keyword vector and return the value.
00646       ! A succesful key - keyword match is recorded in readindex with a value "1"
00647       ! Note: in case more than one keyword matches the key, the first keyword - value combination is returned
00648       value=' '
00649       do ikey=1,nkeys
00650          ! check for keywords ignoring case difference
00651          if (lowercase(key) .eq. lowercase(keyword(ikey))) then
00652             value=values(ikey)
00653             readindex(ikey)=1
00654             exit
00655          endif
00656       enddo
00657 
00658       ! Easter egg!
00659       ! With call for key "checkparams", the subroutine searches readindex for keyword - value combinations that
00660       ! have not yet been read. It returns a warning to screen and log file for each unsuccesful keyword.
00661       if (lowercase(key) .eq. 'checkparams') then
00662          do ikey=1,nkeys
00663             if (readindex(ikey)==0) then
00664                call writelog('slw','','Unknown, unused or multiple statements of parameter ', &
00665                trim(uppercase(keyword(ikey))),' in ',trim(fname))
00666             endif
00667          enddo
00668       endif
00669 
00670    end subroutine readkey
00671 
00672 
00673    ! The following code is taken from program "CHCASE" @ http://www.davidgsimpson.com/software/chcase_f90.txt:
00674    !  Programmer:   Dr. David G. Simpson
00675    !                NASA Goddard Space Flight Center
00676    !                Greenbelt, Maryland  20771
00677    !
00678    !  Date:         January 24, 2003
00679    !
00680    !  Language:     Fortran-90
00681    !
00682    !  Version:      1.00a
00683    !                1.1 : Modified uppercase into function form by R.T. McCall 23/7/2013
00684    !
00685 
00686    pure function UPPERCASE(STR) result(upperstr)
00687 
00688       IMPLICIT NONE
00689 
00690       CHARACTER(LEN=*),intent(in) :: STR
00691       character(slen)             :: upperstr
00692       INTEGER                     :: I, DEL
00693 
00694       upperstr = STR
00695 
00696       DEL = IACHAR('a') - IACHAR('A')
00697 
00698       DO I = 1, LEN_TRIM(upperstr)
00699          IF (LGE(upperstr(I:I),'a') .AND. LLE(upperstr(I:I),'z')) THEN
00700             upperstr(I:I) = ACHAR(IACHAR(upperstr(I:I)) - DEL)
00701          END IF
00702       END DO
00703 
00704    end function UPPERCASE
00705    !
00706    !  LOWERCASE
00707    !
00708    pure function LOWERCASE(STR) result(lowerstr)
00709 
00710       IMPLICIT NONE
00711 
00712       CHARACTER(LEN=*), INTENT(IN) :: STR
00713       character(slen)              :: lowerstr
00714       INTEGER :: I, DEL
00715 
00716       lowerstr = STR
00717 
00718       DEL = IACHAR('a') - IACHAR('A')
00719 
00720       DO I = 1, LEN_TRIM(lowerstr)
00721          IF (LGE(lowerstr(I:I),'A') .AND. LLE(lowerstr(I:I),'Z')) THEN
00722             lowerstr(I:I) = ACHAR(IACHAR(lowerstr(I:I)) + DEL)
00723          END IF
00724       END DO
00725 
00726       RETURN
00727 
00728    END FUNCTION LOWERCASE
00729 
00730    ! End of code taken from CHCASE
00731 
00732 
00733 
00734    ! The following
00735    ! defines the following method to read a string parameter:
00736    !
00737    !  for example:
00738 
00739    !  integer NAME1, NAME2, NAME3
00740    !  call setallowednames('name1',NAME1,'name2',NAME2,'name3',NAME3)
00741    !   this defines the allowed names ('name1', 'name2', 'name3') and
00742    !   the to-be associated integer values (NAME1, NAME2, NAME3)
00743    !  call setoldname('0','1')
00744    !   this defines alternate allowed names for 'name1' and 'name2'
00745    !  integer intvalue
00746    !  character(slen) stringvalue
00747    !  call parmapply('gridform',2,intvalue[,stringvalue])
00748    !                            |
00749    !   this searches for 'gridform' in file 'params.txt'.
00750    !   let us assume that there is a line
00751    !   gridform = name3
00752    !   then intvalue becomes NAME2, and stringvalue becomes 'name3'
00753    !   If no line defining gridform is found, the default numer allowed name
00754    !   is used, in this case number 2: NAME2 and 'name2'
00755    !
00756    !   Notes:
00757    !     setoldnames must be called after setallowednames and is optional
00758    !     the 3rd parameter in parmapply is optional
00759    !
00760 
00761 
00762    subroutine parmapply(vname,idefname,parm,parm_str,bcast,required,silent)
00763       use typesandkinds
00764       use xmpi_module
00765       implicit none
00766       character(*), intent(in)            :: vname
00767       integer,      intent(in)            :: idefname
00768       integer,      intent(out)           :: parm
00769       character(*), intent(out), optional :: parm_str
00770       logical,      intent(in), optional  :: bcast,required,silent
00771 
00772       character(slen)                     :: d
00773       integer                             :: i
00774       logical                             :: lbcast
00775 
00776       d = readkey_str('params.txt',vname,allowednames(idefname), &
00777       numallowednames,numoldnames,allowednames,oldnames, &
00778       bcast, required, silent)
00779 
00780       if (present(bcast)) then
00781          lbcast = bcast
00782       else
00783          lbcast = .true.
00784       endif
00785 
00786       if (xmaster) then
00787          do i=1,numallowednames
00788             if (d .eq. allowednames(i)) then
00789                parm = intvalues(i)
00790                if (present(parm_str)) then
00791                   parm_str = d
00792                endif
00793                exit
00794             endif
00795          enddo
00796       endif
00797 
00798 #ifdef USEMPI
00799       if (lbcast) then
00800          call xmpi_bcast(parm,readkey_inio)
00801       endif
00802 #endif
00803 
00804    end subroutine parmapply
00805 
00806    subroutine setallowednames(a1,v1,a2,v2,a3,v3,a4,v4,a5,v5,a6,v6,a7,v7,a8,v8, &
00807    a9,v9,a10,v10,a11,v11,a12,v12,a13,v13,a14,v14,   &
00808    a15,v15,a16,v16,a17,v17,a18,v18,a19,v19,a20,v20)
00809       character(*), intent(in) :: a1
00810       character(*), intent(in), optional :: a2,a3,a4,a5,a6,a7,a8,a9,a10 
00811       ,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20
00812       integer   ,   intent(in) :: v1
00813       integer   ,   intent(in), optional :: v2,v3,v4,v5,v6,v7,v8,v9,v10 
00814       ,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20
00815       numoldnames = 0
00816       allowednames(1) = a1
00817       intvalues(1)    = v1
00818       numallowednames = 1
00819       if (present(a2)) then
00820          allowednames(2) = a2
00821          intvalues(2)    = v2
00822          numallowednames = 2
00823       endif
00824       if (present(a3)) then
00825          allowednames(3) = a3
00826          intvalues(3)    = v3
00827          numallowednames = 3
00828       endif
00829       if (present(a4)) then
00830          allowednames(4) = a4
00831          intvalues(4)    = v4
00832          numallowednames = 4
00833       endif
00834       if (present(a5)) then
00835          allowednames(5) = a5
00836          intvalues(5)    = v5
00837          numallowednames = 5
00838       endif
00839       if (present(a6)) then
00840          allowednames(6) = a6
00841          intvalues(6)    = v6
00842          numallowednames = 6
00843       endif
00844       if (present(a7)) then
00845          allowednames(7) = a7
00846          intvalues(7)    = v7
00847          numallowednames = 7
00848       endif
00849       if (present(a8)) then
00850          allowednames(8) = a8
00851          intvalues(8)    = v8
00852          numallowednames = 8
00853       endif
00854       if (present(a9)) then
00855          allowednames(9) = a9
00856          intvalues(9)    = v9
00857          numallowednames = 9
00858       endif
00859       if (present(a10)) then
00860          allowednames(10) = a10
00861          intvalues(10)    = v10
00862          numallowednames = 10
00863       endif
00864       if (present(a11)) then
00865          allowednames(11) = a11
00866          intvalues(11)    = v11
00867          numallowednames = 11
00868       endif
00869       if (present(a12)) then
00870          allowednames(12) = a12
00871          intvalues(12)    = v12
00872          numallowednames = 12
00873       endif
00874       if (present(a13)) then
00875          allowednames(13) = a13
00876          intvalues(13)    = v13
00877          numallowednames = 13
00878       endif
00879       if (present(a14)) then
00880          allowednames(14) = a14
00881          intvalues(14)    = v14
00882          numallowednames = 14
00883       endif
00884       if (present(a15)) then
00885          allowednames(15) = a15
00886          intvalues(15)    = v15
00887          numallowednames = 15
00888       endif
00889       if (present(a16)) then
00890          allowednames(16) = a16
00891          intvalues(16)    = v16
00892          numallowednames = 16
00893       endif
00894       if (present(a17)) then
00895          allowednames(17) = a17
00896          intvalues(17)    = v17
00897          numallowednames = 17
00898       endif
00899       if (present(a18)) then
00900          allowednames(18) = a18
00901          intvalues(18)    = v18
00902          numallowednames = 18
00903       endif
00904       if (present(a19)) then
00905          allowednames(19) = a19
00906          intvalues(19)    = v19
00907          numallowednames = 19
00908       endif
00909       if (present(a20)) then
00910          allowednames(20) = a20
00911          intvalues(20)    = v20
00912          numallowednames = 20
00913       endif
00914 
00915    end subroutine setallowednames
00916 
00917    subroutine setoldnames(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10 &
00918    ,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
00919       character(*), intent(in) :: a1
00920       character(*), intent(in), optional :: a2,a3,a4,a5,a6,a7,a8,a9,a10 
00921       ,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20
00922       oldnames(1) = a1
00923       numoldnames = 1
00924       if (present(a2)) then
00925          oldnames(2) = a2
00926          numoldnames = 2
00927       endif
00928       if (present(a3)) then
00929          oldnames(3) = a3
00930          numoldnames = 3
00931       endif
00932       if (present(a4)) then
00933          oldnames(4) = a4
00934          numoldnames = 4
00935       endif
00936       if (present(a5)) then
00937          oldnames(5) = a5
00938          numoldnames = 5
00939       endif
00940       if (present(a6)) then
00941          oldnames(6) = a6
00942          numoldnames = 6
00943       endif
00944       if (present(a7)) then
00945          oldnames(7) = a7
00946          numoldnames = 7
00947       endif
00948       if (present(a8)) then
00949          oldnames(8) = a8
00950          numoldnames = 8
00951       endif
00952       if (present(a9)) then
00953          oldnames(9) = a9
00954          numoldnames = 9
00955       endif
00956       if (present(a10)) then
00957          oldnames(10) = a10
00958          numoldnames = 10
00959       endif
00960       if (present(a11)) then
00961          oldnames(11) = a11
00962          numoldnames = 11
00963       endif
00964       if (present(a12)) then
00965          oldnames(12) = a12
00966          numoldnames = 12
00967       endif
00968       if (present(a13)) then
00969          oldnames(13) = a13
00970          numoldnames = 13
00971       endif
00972       if (present(a14)) then
00973          oldnames(14) = a14
00974          numoldnames = 14
00975       endif
00976       if (present(a15)) then
00977          oldnames(15) = a15
00978          numoldnames = 15
00979       endif
00980       if (present(a16)) then
00981          oldnames(16) = a16
00982          numoldnames = 16
00983       endif
00984       if (present(a17)) then
00985          oldnames(17) = a17
00986          numoldnames = 17
00987       endif
00988       if (present(a18)) then
00989          oldnames(18) = a18
00990          numoldnames = 18
00991       endif
00992       if (present(a19)) then
00993          oldnames(19) = a19
00994          numoldnames = 19
00995       endif
00996       if (present(a20)) then
00997          oldnames(20) = a20
00998          numoldnames = 20
00999       endif
01000 
01001    end subroutine setoldnames
01002 
01003    subroutine read_v_array(fid,a)
01004       use xmpi_module
01005       !
01006       ! reads array from unit fid
01007       ! to be called by everyone
01008       ! only xmaster reads
01009       ! fid is only needed on xmaster
01010       !
01011       integer, intent(in)               :: fid
01012       real*8, dimension(:), intent(out) :: a
01013       if (xmaster) then
01014          read(fid,*) a
01015       endif
01016 #ifdef USEMPI
01017       call xmpi_bcast(a,readkey_inio)
01018 #endif
01019    end subroutine read_v_array
01020 
01021    subroutine read_v_9(fid,a,a1,a2,a3,a4,a5,a6,a7,a8)
01022       use xmpi_module
01023       !
01024       ! reads doubles from unit fid
01025       ! to be called by everyone
01026       ! only xmaster reads
01027       ! fid is only needed on xmaster
01028       !
01029       integer, intent(in) :: fid
01030       real*8, intent(out) :: a
01031       real*8, optional, intent(out) :: a1,a2,a3,a4,a5,a6,a7,a8
01032       if (present(a8)) then
01033          if(xmaster) read(fid,*) a,a1,a2,a3,a4,a5,a6,a7,a8
01034 #ifdef USEMPI
01035          call xmpi_bcast(a1,readkey_inio)
01036          call xmpi_bcast(a2,readkey_inio)
01037          call xmpi_bcast(a3,readkey_inio)
01038          call xmpi_bcast(a4,readkey_inio)
01039          call xmpi_bcast(a5,readkey_inio)
01040          call xmpi_bcast(a6,readkey_inio)
01041          call xmpi_bcast(a7,readkey_inio)
01042          call xmpi_bcast(a8,readkey_inio)
01043 #endif
01044       elseif (present(a7)) then
01045          if(xmaster) read(fid,*) a,a1,a2,a3,a4,a5,a6,a7
01046 #ifdef USEMPI
01047          call xmpi_bcast(a1,readkey_inio)
01048          call xmpi_bcast(a2,readkey_inio)
01049          call xmpi_bcast(a3,readkey_inio)
01050          call xmpi_bcast(a4,readkey_inio)
01051          call xmpi_bcast(a5,readkey_inio)
01052          call xmpi_bcast(a6,readkey_inio)
01053          call xmpi_bcast(a7,readkey_inio)
01054 #endif
01055       elseif (present(a6)) then
01056          if(xmaster) read(fid,*) a,a1,a2,a3,a4,a5,a6
01057 #ifdef USEMPI
01058          call xmpi_bcast(a1,readkey_inio)
01059          call xmpi_bcast(a2,readkey_inio)
01060          call xmpi_bcast(a3,readkey_inio)
01061          call xmpi_bcast(a4,readkey_inio)
01062          call xmpi_bcast(a5,readkey_inio)
01063          call xmpi_bcast(a6,readkey_inio)
01064 #endif
01065       elseif (present(a5)) then
01066          if(xmaster) read(fid,*) a,a1,a2,a3,a4,a5
01067 #ifdef USEMPI
01068          call xmpi_bcast(a1,readkey_inio)
01069          call xmpi_bcast(a2,readkey_inio)
01070          call xmpi_bcast(a3,readkey_inio)
01071          call xmpi_bcast(a4,readkey_inio)
01072          call xmpi_bcast(a5,readkey_inio)
01073 #endif
01074       elseif (present(a4)) then
01075          if(xmaster) read(fid,*) a,a1,a2,a3,a4
01076 #ifdef USEMPI
01077          call xmpi_bcast(a1,readkey_inio)
01078          call xmpi_bcast(a2,readkey_inio)
01079          call xmpi_bcast(a3,readkey_inio)
01080          call xmpi_bcast(a4,readkey_inio)
01081 #endif
01082       elseif (present(a3)) then
01083          if(xmaster) read(fid,*) a,a1,a2,a3
01084 #ifdef USEMPI
01085          call xmpi_bcast(a1,readkey_inio)
01086          call xmpi_bcast(a2,readkey_inio)
01087          call xmpi_bcast(a3,readkey_inio)
01088 #endif
01089       elseif (present(a2)) then
01090          if(xmaster) read(fid,*) a,a1,a2
01091 #ifdef USEMPI
01092          call xmpi_bcast(a1,readkey_inio)
01093          call xmpi_bcast(a2,readkey_inio)
01094 #endif
01095       elseif (present(a1)) then
01096          if(xmaster) read(fid,*) a,a1
01097 #ifdef USEMPI
01098          call xmpi_bcast(a1,readkey_inio)
01099 #endif
01100       else
01101          if(xmaster) read(fid,*) a
01102       endif
01103 #ifdef USEMPI
01104       call xmpi_bcast(a,readkey_inio)
01105 #endif
01106    end subroutine read_v_9
01107 
01108    integer function count_lines(f)
01109       !
01110       ! returns number of lines in file f
01111       ! to be called by all, xmaster will count
01112       ! result is broadcasted to all
01113       !
01114       use xmpi_module
01115       use filefunctions
01116       character(len=*), intent(in) :: f
01117       integer lines,fid,ierr
01118       if(xmaster) then
01119          fid = create_new_fid()
01120          open(fid,file=f)
01121          lines = 0
01122          ierr = 0
01123          do while(ierr == 0)
01124             read(fid,*,iostat=ierr)
01125             if (ierr == 0) lines = lines+1
01126          enddo
01127          close(fid)
01128       endif
01129 #ifdef USEMPI
01130       call xmpi_bcast(lines,readkey_inio)
01131 #endif
01132       count_lines = lines
01133 
01134    end function count_lines
01135 
01136    character(slen) function strippedline(line)
01137 
01138       character(slen),intent(in) :: line
01139       integer  :: itab
01140 
01141       do itab=1,slen
01142          if (ichar(line(itab:itab))<32 .or. ichar(line(itab:itab))>126) then  ! this is anything not in standard
01143             ! alphanumeric
01144             strippedline(itab:itab) = ' '
01145          else
01146             strippedline(itab:itab) = line(itab:itab)
01147          endif
01148       enddo
01149 
01150    end function
01151 end module readkey_module
 All Classes Files Functions Variables Defines