!! Copyright (C) Stichting Deltares, 2005-2016. !! !! This file is part of iMOD. !! !! This program is free software: you can redistribute it and/or modify !! it under the terms of the GNU General Public License as published by !! the Free Software Foundation, either version 3 of the License, or !! (at your option) any later version. !! !! This program 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 General Public License for more details. !! !! You should have received a copy of the GNU General Public License !! along with this program. If not, see . !! !! Contact: imod.support@deltares.nl !! Stichting Deltares !! P.O. Box 177 !! 2600 MH Delft, The Netherlands. !! MODULE MOD_UTL !USE WINTERACTER !USE RESOURCE !USE IMODCONFIG !USE MOD_PREF_PAR, ONLY : PREFVAL USE MODPLOT, ONLY : MP,MPW,LEGENDOBJ,MXCLR,MXCLASS USE MOD_IDF_PAR, ONLY : IDFOBJ USE MOD_POLINT, ONLY : POL1LOCATE !USE IMODVAR, ONLY : MXTP,TP,IDPROC,BVERSION,RVERSION,LBETA,LEXPDATE,EXPDATE,SAVEDIR,ICDEBUGLEVEL !USE MOD_OSD, ONLY : OSD_OPEN,OSD_GETENV,OS USE MOD_QKSORT !## max. number of messages INTEGER,PARAMETER :: MXMESSAGE=16 INTEGER,DIMENSION(MXMESSAGE) :: IMESSAGE CHARACTER(LEN=256),ALLOCATABLE,DIMENSION(:) :: LISTNAME INTEGER,ALLOCATABLE,DIMENSION(:) :: ILIST CHARACTER(LEN=2),PARAMETER :: NEWLINE=CHAR(13)//CHAR(10) INTEGER,PARAMETER :: MAXLEN=52 CHARACTER(LEN=MAXLEN),POINTER,DIMENSION(:,:) :: VAR,VAR_TMP,DVAR CHARACTER(LEN=MAXLEN),POINTER,DIMENSION(:) :: CCNST INTEGER,ALLOCATABLE,DIMENSION(:) :: IVAR,ICOL_VAR,IACT_VAR !## max. variables/max. lines INTEGER :: NV,NL,IV TYPE PROCOBJ INTEGER,DIMENSION(2) :: IFLAGS INTEGER :: ID CHARACTER(LEN=52) :: CID END TYPE PROCOBJ REAL,PARAMETER,PRIVATE :: SDAY=86400.0 REAL,DIMENSION(13) :: SXVALUE,SYVALUE INTEGER :: NSX,NSY CONTAINS ! !###====================================================================== ! SUBROUTINE UTL_MEASUREMAIN() ! !###====================================================================== ! IMPLICIT NONE ! REAL,DIMENSION(:),POINTER :: XCRD,YCRD => NULL() ! INTEGER :: NCRD ! ! IF(ASSOCIATED(XCRD))DEALLOCATE(XCRD) ! IF(ASSOCIATED(YCRD))DEALLOCATE(YCRD) ! CALL UTL_MEASURE(XCRD,YCRD,NCRD) ! DEALLOCATE(XCRD,YCRD) ! ! END SUBROUTINE UTL_MEASUREMAIN ! ! !###====================================================================== ! SUBROUTINE UTL_MEASURE(XCRD,YCRD,NCRD) ! !###====================================================================== ! IMPLICIT NONE ! REAL,DIMENSION(:),POINTER,INTENT(INOUT) :: XCRD,YCRD ! REAL,DIMENSION(:),POINTER :: XCRD_BU,YCRD_BU ! INTEGER,INTENT(OUT) :: NCRD ! TYPE(WIN_MESSAGE) :: MESSAGE ! INTEGER :: I,ITYPE,MAXCRD ! LOGICAL :: LEX ! ! CALL IGRPLOTMODE(MODEXOR); CALL IGRCOLOURN(WRGB(255,255,255)) ! CALL WCURSORSHAPE(ID_CURSORDISTANCE) ! ! CALL IGRFILLPATTERN(OUTLINE); CALL IGRLINETYPE(SOLIDLINE) ! CALL WINDOWOUTSTATUSBAR(2,'Press right mouse button to stop') ! ! MAXCRD=50; ALLOCATE(XCRD(MAXCRD),YCRD(MAXCRD)) ! LEX =.FALSE.; NCRD=0 ! ! DO ! CALL WMESSAGE(ITYPE,MESSAGE) ! SELECT CASE (ITYPE) ! ! !## mouse-move ! CASE (MOUSEMOVE) ! ! CALL WINDOWSELECT(0) ! CALL WINDOWOUTSTATUSBAR(1,'X:'//TRIM(RTOS(MESSAGE%GX/1000.,'F',7))//' km, Y:'//TRIM(RTOS(MESSAGE%GY/1000.,'F',7))//' km') ! ! !## first point set ! IF(NCRD.GE.2)THEN ! CALL IDFPLOT1BITMAP() ! IF(LEX)CALL UTL_MEASUREPLOTSHAPE(XCRD,YCRD,NCRD) ! LEX=.TRUE.; XCRD(NCRD)=MESSAGE%GX; YCRD(NCRD)=MESSAGE%GY ! CALL UTL_MEASUREPLOTSHAPE(XCRD,YCRD,NCRD) ! CALL IDFPLOT2BITMAP() ! ENDIF ! !! CASE (PUSHBUTTON) !! SELECT CASE (MESSAGE%VALUE1) !! CASE (IDCANCEL) !! EXIT !! END SELECT ! ! CASE (MOUSEBUTDOWN) ! CALL IDFPLOT1BITMAP() ! IF(LEX)CALL UTL_MEASUREPLOTSHAPE(XCRD,YCRD,NCRD) ! ! SELECT CASE (MESSAGE%VALUE1) ! !## left button ! CASE (1) ! !## increase memory ! IF(NCRD+2.GT.MAXCRD)THEN ! MAXCRD=MAXCRD+50; ALLOCATE(XCRD_BU(MAXCRD),YCRD_BU(MAXCRD)) ! DO I=1,NCRD; XCRD_BU(I)=XCRD(I); YCRD_BU(I)=YCRD(I); ENDDO ! DEALLOCATE(XCRD,YCRD); XCRD=>XCRD_BU; YCRD=>YCRD_BU ! ENDIF ! NCRD=NCRD+1; IF(NCRD.EQ.1)NCRD=NCRD+1 ! DO I=NCRD-1,NCRD; XCRD(I)=MESSAGE%GX; YCRD(I)=MESSAGE%GY; ENDDO ! CALL UTL_MEASUREPLOTSHAPE(XCRD,YCRD,NCRD) ! CALL IDFPLOT2BITMAP() ! ! !## right button ! CASE (3) ! EXIT ! END SELECT ! ! !## bitmap scrolled, renew top-left pixel coordinates ! CASE (BITMAPSCROLLED) ! MPW%IX=MESSAGE%VALUE1; MPW%IY=MESSAGE%VALUE2 ! !! CASE (EXPOSE) !! IF(WMENUGETSTATE(ID_PLOTLEGEND,2).EQ.1)CALL LEGPLOT_PLOTUPDATE(.FALSE.) !! CALL IGRUNITS(MPW%XMIN,MPW%YMIN,MPW%XMAX,MPW%YMAX) ! ! END SELECT ! END DO ! ! NCRD=NCRD-1 ! ! CALL IDFPLOT1BITMAP() ! CALL UTL_MEASUREPLOTSHAPE(XCRD,YCRD,NCRD) ! CALL UTL_MEASUREPLOTSHAPE(XCRD,YCRD,NCRD) ! CALL IDFPLOT2BITMAP() ! ! CALL WCURSORSHAPE(CURARROW); CALL IGRPLOTMODE(MODECOPY) ! CALL IGRFILLPATTERN(OUTLINE); CALL IGRLINETYPE(SOLIDLINE) ! CALL WINDOWSELECT(0); CALL WINDOWOUTSTATUSBAR(2,''); CALL WINDOWOUTSTATUSBAR(3,''); CALL WINDOWOUTSTATUSBAR(4,'') ! ! END SUBROUTINE UTL_MEASURE ! ! !###====================================================================== ! SUBROUTINE UTL_MEASUREPLOTSHAPE(XCRD,YCRD,NCRD) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: NCRD ! REAL,DIMENSION(:),POINTER,INTENT(IN) :: XCRD,YCRD ! INTEGER :: I ! REAL :: TDIST,DIST ! CHARACTER(LEN=256) :: STRING ! CHARACTER(LEN=256) :: CDIST,CTDIST ! ! CALL IGRFILLPATTERN(OUTLINE) ! CALL IGRPOLYLINE(XCRD,YCRD,NCRD) ! TDIST=0.0; DIST =0.0 ! DO I=2,NCRD ! DIST =SQRT((XCRD(I)-XCRD(I-1))**2.0+(YCRD(I)-YCRD(I-1))**2.0) ! TDIST=DIST+TDIST ! END DO ! ! IF(TDIST.LT.1.0)THEN ! CTDIST=TRIM(RTOS(TDIST*100.0 ,'F',3))//' cm' ! ELSEIF(TDIST.LT.1000.0)THEN ! CTDIST=TRIM(RTOS(TDIST ,'F',3))//' m' ! ELSE ! CTDIST=TRIM(RTOS(TDIST/1000.0,'F',3))//' km' ! ENDIF ! IF(DIST.LT.1.0)THEN ! CDIST=TRIM(RTOS(DIST*100.0 ,'F',3))//' cm' ! ELSEIF(DIST.LT.1000.0)THEN ! CDIST=TRIM(RTOS(DIST ,'F',3))//' m' ! ELSE ! CDIST=TRIM(RTOS(DIST/1000.0,'F',3))//' km' ! ENDIF ! ! STRING='Total distance= '//TRIM(CTDIST)//'; Distance last segment= '//TRIM(CDIST) ! ! CALL WINDOWOUTSTATUSBAR(4,STRING) ! ! END SUBROUTINE UTL_MEASUREPLOTSHAPE ! ! !###====================================================================== ! SUBROUTINE UTL_GETAXESCALES(XMIN,YMIN,XMAX,YMAX) ! !###====================================================================== ! IMPLICIT NONE ! REAL,INTENT(IN) :: XMIN,YMIN,XMAX,YMAX ! REAL :: DX,DY,X1,X2,Y1,Y2 ! INTEGER :: I ! ! CALL IPGNEWPLOT(PGSCATTERPLOT,1,1,0,1) ! ! X1=XMIN; Y1=YMIN; X2=XMAX; Y2=YMAX ! ! DO ! ! CALL IPGUNITS(X1,Y1,X2,Y2) ! ! !## get x-scale intervals ! SXVALUE=0.0; CALL IPGXGETSCALE(SXVALUE,NSX) ! !## get y-scale intervals ! SYVALUE=0.0; CALL IPGYGETSCALE(SYVALUE,NSY) ! ! I=0 ! !## see whether x-classes are distinghuisable ! IF(UTL_EQUALS_REAL(SXVALUE(2),SXVALUE(1)))THEN ! DX=EPSILON(X1); X1=X1-DX; DX=EPSILON(X2); X2=X2+DX; I=I+1 ! ENDIF ! !## see whether y-classes are distinghuisable ! IF(UTL_EQUALS_REAL(SYVALUE(2),SYVALUE(1)))THEN ! DY=ABS(Y1)*EPSILON(Y1); Y1=Y1-DY ! DY=ABS(Y2)*EPSILON(Y2); Y2=Y2+DY ! I=I+1 ! ENDIF ! ! IF(I.EQ.0)EXIT ! ! ENDDO ! ! !## get x-scale intervals ! DX=SXVALUE(2)-SXVALUE(1) ! DO I=2,NSX; SXVALUE(I)=SXVALUE(I-1)+DX; ENDDO ! ! !## get y-scale intervals ! DY=SYVALUE(2)-SYVALUE(1) ! DO I=2,NSY; SYVALUE(I)=SYVALUE(I-1)+DY; ENDDO ! ! END SUBROUTINE UTL_GETAXESCALES ! ! !###====================================================================== ! CHARACTER(LEN=15) FUNCTION UTL_WRITENUMBER(X) ! !###====================================================================== ! IMPLICIT NONE ! REAL,INTENT(IN) :: X ! ! WRITE(UTL_WRITENUMBER,UTL_GETFORMAT(X)) X ! ! END FUNCTION UTL_WRITENUMBER ! ! !###====================================================================== ! CHARACTER(LEN=15) FUNCTION UTL_GETFORMAT(X) ! !###====================================================================== ! IMPLICIT NONE ! REAL,INTENT(IN) :: X ! CHARACTER(LEN=20) :: XC ! INTEGER :: I,J,K,NDEC ! ! WRITE(XC,*) X ! XC=ADJUSTL(XC) ! ! CALL IUPPERCASE(XC) ! J=INDEX(XC,'E+00') ! IF(J.GT.0)XC=XC(:J-1) ! I=INDEX(XC,'E') ! IF(I.GT.0)THEN ! UTL_GETFORMAT='(E10.4)' ! ELSE ! I=INDEX(XC,'.') ! IF(I.EQ.0)THEN ! UTL_GETFORMAT='(F10.0)' ! ELSE ! J=LEN_TRIM(XC) ! DO K=J,I+1,-1 ! IF(XC(K:K).NE.'0')EXIT ! END DO ! NDEC=K-I ! ! IF(NDEC.EQ.0)THEN ! UTL_GETFORMAT='(F10.0)' ! ELSE ! WRITE(UTL_GETFORMAT,'(A5,I2.2,A)') '(F10.',NDEC,')' ! ENDIF ! ENDIF ! ENDIF ! ! END FUNCTION UTL_GETFORMAT ! ! !###====================================================================== ! SUBROUTINE UTL_DEBUGLEVEL(IONOFF) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: IONOFF ! ! IF(IONOFF.EQ.0)THEN ! CALL IDEBUGLEVEL(DBGSILENT) ! ELSE ! CALL IDEBUGLEVEL(ICDEBUGLEVEL) ! ENDIF ! ! END SUBROUTINE UTL_DEBUGLEVEL ! ! !###==================================================================== ! FUNCTION UTL_REALTOSTRING(X) ! !###==================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=15) :: UTL_REALTOSTRING,FSTRING ! REAL,INTENT(IN) :: X ! INTEGER :: I,J,NSIG ! REAL :: F ! CHARACTER(LEN=12) :: FRM ! ! I=INT(X); F=X-I ! UTL_REALTOSTRING=TRIM(ITOS(I)) ! IF(F.NE.0.0)THEN ! NSIG=MAX(0,7-LEN_TRIM(UTL_REALTOSTRING)) ! WRITE(FRM,'(A5,I2.2,A1)') '(F10.',NSIG,')' ! WRITE(FSTRING,FRM) F; FSTRING=ADJUSTL(FSTRING) ! !## search backwards for first non-zero ! DO J=LEN_TRIM(FSTRING),1,-1 ! IF(FSTRING(J:J).NE.'0')EXIT ! ENDDO ! IF(F.GT.0.0)UTL_REALTOSTRING=TRIM(UTL_REALTOSTRING)//'.'//FSTRING(3:J) ! IF(F.LT.0.0)UTL_REALTOSTRING=TRIM(UTL_REALTOSTRING)//'.'//FSTRING(4:J) ! ENDIF ! !## add minus ! IF(I.EQ.0.AND.X.LT.0.0)UTL_REALTOSTRING='-'//TRIM(UTL_REALTOSTRING) ! ! END FUNCTION UTL_REALTOSTRING ! !###==================================================================== SUBROUTINE UTL_RELPATHNAME(PATH,RFNAME,GFNAME) !###==================================================================== IMPLICIT NONE CHARACTER(LEN=*),INTENT(IN) :: PATH CHARACTER(LEN=*),INTENT(INOUT) :: RFNAME CHARACTER(LEN=*),INTENT(OUT) :: GFNAME CHARACTER(LEN=256) :: ROOTNAME !## check relative-pathnames IF(INDEX(RFNAME,':').EQ.0)THEN !## rootname ROOTNAME=PATH(:INDEX(PATH,'\',.TRUE.)-1) !## clip number of "..\" from the rootname DO IF(INDEX(RFNAME,'..\',.FALSE.).EQ.0)EXIT RFNAME=RFNAME(INDEX(RFNAME,'..\',.FALSE.)+3:) ROOTNAME=ROOTNAME(:INDEX(ROOTNAME,'\',.TRUE.)-1) ENDDO !## construct global filename GFNAME=TRIM(ROOTNAME)//'\'//TRIM(RFNAME) ELSE !## drive letter found GFNAME=RFNAME ENDIF END SUBROUTINE UTL_RELPATHNAME !!###==================================================================== !FUNCTION UTL_IMODVERSION(S1,S2) !!###==================================================================== !IMPLICIT NONE !CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: S1,S2 !CHARACTER(LEN=75) :: UTL_IMODVERSION ! !IF(LBETA)THEN ! UTL_IMODVERSION=TRIM(BVERSION)//'-iMOD' !ELSE ! UTL_IMODVERSION='iMOD' !ENDIF ! !IF(PRESENT(S1).AND.PRESENT(S2))THEN ! UTL_IMODVERSION=TRIM(UTL_IMODVERSION)//' ['//TRIM(UTL_SUBST(RVERSION,S1,S2))//' '//TRIM(CCONFIG)//']' !ELSE ! UTL_IMODVERSION=TRIM(UTL_IMODVERSION)//' ['//TRIM(RVERSION)//' '//TRIM(CCONFIG)//']' !ENDIF !IF(LEXPDATE)THEN ! UTL_IMODVERSION=TRIM(UTL_IMODVERSION)//' [Expiring date: '//TRIM(JDATETOGDATE(UTL_IDATETOJDATE(EXPDATE)))//']' !ENDIF ! !END FUNCTION UTL_IMODVERSION ! ! !###==================================================================== ! LOGICAL FUNCTION UTL_PCK_READTXT(ICOL,STIME,ETIME,QT,FNAME) ! !###==================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: ICOL ! INTEGER(KIND=8),INTENT(IN) :: STIME,ETIME ! CHARACTER(LEN=*),INTENT(IN) :: FNAME ! REAL,INTENT(OUT) :: QT ! INTEGER :: IR,I,I1,I2,IU,NR,NC,IDATE,JDATE,NDATE,N,IOS,TTIME,ITYPE,IZ,IZMIN,IZMAX,LUNIT,DIZ,SDATE,EDATE ! REAL :: Q1,QQ,Z ! CHARACTER(LEN=8) :: ATTRIB ! CHARACTER(LEN=256) :: LINE ! REAL,DIMENSION(:),ALLOCATABLE :: NODATA ! CHARACTER(LEN=52),DIMENSION(:),ALLOCATABLE :: QD ! ! UTL_PCK_READTXT=.FALSE. ! ! !## transient(2)/steady-state(1) ! QT=0.0 ! ! !## open textfiles with pump information ! IU=UTL_GETUNIT(); CALL OSD_OPEN(IU,FILE=FNAME,STATUS='OLD',ACTION='READ') ! IF(IU.LE.0)RETURN ! ! READ(IU,*) NR; IF(NR.LE.0)THEN; CLOSE(IU); UTL_PCK_READTXT=.TRUE.; RETURN; ENDIF ! ! READ(IU,'(A256)') LINE ! READ(LINE,*,IOSTAT=IOS) NC,ITYPE ! IF(IOS.NE.0)ITYPE=1 ! ITYPE=MAX(ITYPE,1) ! ! !## what type of file? ! SELECT CASE (ITYPE) ! !## timeseries ! CASE (1) ! !## sdate=yyyymmddmmhhss; edate=yyyymmddmmhhss ! SDATE=STIME/1000000; EDATE=ETIME/1000000 ! SDATE=UTL_IDATETOJDATE(SDATE); EDATE=UTL_IDATETOJDATE(EDATE) ! TTIME=EDATE-SDATE ! IF(TTIME.LE.0)THEN ! CLOSE(IU); CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'Timestep size to extract data is '//TRIM(ITOS(TTIME)),'Error') ! RETURN ! ENDIF ! !## boreholes/seismic ! CASE (2,3) ! SDATE=STIME; EDATE=ETIME ! LUNIT=1; TTIME=ABS((EDATE*LUNIT)-(SDATE*LUNIT)) ! ! END SELECT ! ! ALLOCATE(NODATA(NC),QD(NC)); QD='' !0.0 ! ! DO I=1,NC; READ(IU,*) ATTRIB,NODATA(I); ENDDO ! ! !## timeseries ! IF(ITYPE.EQ.1)THEN ! ! I1=1 ! DO IR=1,NR ! ! IF(IR.EQ.1)THEN ! READ(IU,*) IDATE,(QD(I),I=2,NC) ! READ(QD(ICOL),*) QQ !QQ=QD(ICOL) ! !## reset to zero for nodata value ! IF(QQ.EQ.NODATA(ICOL))QQ=0.0 ! ELSE ! !## use only whenever not equal to nodata ! IF(Q1.NE.NODATA(ICOL))QQ=Q1 ! IDATE=JDATE ! ENDIF ! ! !## edate=end date of current simulation period ! NDATE=EDATE ! IF(IR.LT.NR)THEN ! READ(IU,*) NDATE,(QD(I),I=2,NC) ! READ(QD(ICOL),*) Q1 !! Q1=QD(ICOL) ! JDATE=NDATE ! NDATE=UTL_IDATETOJDATE(NDATE) !## fname=optional for error message ! ENDIF ! ! !## ndate is min of end date in txt file or simulation period ! NDATE=MIN(NDATE,EDATE) ! ! !## is begin date read from txt file ! IDATE=UTL_IDATETOJDATE(IDATE) !## fname=optional for error message ! ! !## stop searching for data, outside modeling window! ! IF(IDATE.GT.EDATE)EXIT ! ! !## within modeling window ! IF(NDATE.GT.SDATE)THEN ! ! !### definitions ($ time window current stressperiod) ! ! $ |---------| $ ! !sdate idate ndate edate ! ! N=NDATE-SDATE ! !## if startingdate (read from txt file) greater than start date of current stressperiod ! IF(IDATE.GT.SDATE)N=N-(IDATE-SDATE) ! I2=I1+N-1 ! ! IF(I2.GE.I1)QT=QT+REAL(I2-I1+1)*QQ ! ! I1=I2+1 ! ! ENDIF ! END DO ! QT=QT/REAL(TTIME) ! UTL_PCK_READTXT=.TRUE. ! ! !## itype=2 borehole; itype=3 seismic ! ELSEIF(ITYPE.EQ.2.OR.ITYPE.EQ.3)THEN ! ! QQ=0.0; IZMAX=SDATE*LUNIT; IZMIN=EDATE*LUNIT; DIZ=(IZMAX-IZMIN)*LUNIT ! IF(ICOL.EQ.1)THEN ! DO IR=1,MIN(IZMAX,NR) ! READ(IU,*) Z ! ENDDO ! QT=Z; IF(Z.NE.NODATA(1).AND.IR.EQ.IZMAX+1)UTL_PCK_READTXT=.TRUE. ! ! ELSE ! READ(IU,*) Z,(QD(I),I=2,NC) ! IZ=INT(Z*LUNIT); I1=IZMAX-IZ+1 !! Q1=QD(ICOL) ! READ(QD(ICOL),*) Q1 ! DO IR=2,NR ! ! READ(IU,*) Z,(QD(I),I=2,NC) ! IZ=INT(Z*LUNIT) ! I2=IZMAX-IZ ! IF(I1.LE.DIZ.AND.I2.GT.0)THEN ! I2=MIN(DIZ,I2) ! I1=MAX(1,I1) ! IF(I2.GE.I1)QT=QT+REAL(I2-I1+1)*Q1 ! ENDIF ! I1=I2+1 !! Q1=QD(ICOL) ! READ(QD(ICOL),*) Q1 ! IF(I1.GT.DIZ)EXIT ! ENDDO ! QT=QT/REAL(TTIME) ! ! UTL_PCK_READTXT=.TRUE. ! ! ENDIF ! ENDIF ! ! CLOSE(IU); DEALLOCATE(QD) ! ! END FUNCTION UTL_PCK_READTXT ! ! !###====================================================================== ! SUBROUTINE UTL_PCK_GETTLP(N,TLP,KH,TOP,BOT,Z1,Z2,MINKH,ICLAY) ! !###====================================================================== ! IMPLICIT NONE ! REAL,PARAMETER :: MINP=0.0 ! INTEGER,INTENT(IN) :: N,ICLAY ! REAL,INTENT(IN) :: MINKH ! REAL,INTENT(INOUT) :: Z1,Z2 ! REAL,INTENT(IN),DIMENSION(N) :: KH,TOP,BOT ! REAL,INTENT(INOUT),DIMENSION(N) :: TLP ! INTEGER :: JLAY,ILAY,K,IDIFF ! REAL :: ZM,ZT,ZB,ZC,FC,DZ ! REAL,ALLOCATABLE,DIMENSION(:) :: L,TL ! INTEGER,ALLOCATABLE,DIMENSION(:) :: IL ! ! ALLOCATE(L(N),TL(N),IL(N)) ! ! !## make sure thickness is not exactly zero, minimal thickness is 0.01m ! IDIFF=0; IF(Z1.EQ.Z2)THEN; Z1=Z1+0.005; Z2=Z2-0.005; IDIFF=1; ENDIF ! ! !## filterlength for each modellayer ! L=0.0 ! DO ILAY=1,N ! ZT=MIN(TOP(ILAY),Z1); ZB=MAX(BOT(ILAY),Z2); L(ILAY)=MAX(0.0,ZT-ZB) ! ENDDO ! ! TLP=0.0 ! !## well within any aquifer(s) ! IF(SUM(L).GT.0.0)THEN ! !## compute percentage and include sumkd, only if itype.eq.2 ! L=L*KH ! !## percentage (0-1) L*KH ! DO ILAY=1,N; IF(L(ILAY).NE.0.0)TLP=(1.0/SUM(L))*L; ENDDO ! ENDIF ! ! !## correct for dismatch with centre of modelcell ! DO ILAY=1,N ! IF(TLP(ILAY).GT.0.0)THEN ! DZ= TOP(ILAY)-BOT(ILAY) ! ZC=(TOP(ILAY)+BOT(ILAY))/2.0 ! ZT= MIN(TOP(ILAY),Z1) ! ZB= MAX(BOT(ILAY),Z2) ! FC=(ZT+ZB)/2.0 ! TLP(ILAY)=TLP(ILAY)*(1.0-(ABS(ZC-FC)/(0.5*DZ))) ! ENDIF ! ENDDO ! ! !## normalize tlp() again ! IF(SUM(TLP).GT.0.0)TLP=(1.0/SUM(TLP))*TLP ! ! !## remove small permeabilities ! IF(MINKH.GT.0.0)THEN ! ZT=SUM(TLP) ! DO ILAY=1,N; IF(KH(ILAY).LT.MINKH)TLP(ILAY)=0.0; ENDDO ! IF(SUM(TLP).GT.0.0)THEN ! ZT=ZT/SUM(TLP); TLP=ZT*TLP ! ENDIF ! !## normalize tlp() again ! IF(SUM(TLP).GT.0.0)TLP=(1.0/SUM(TLP))*TLP ! ENDIF ! ! IF(MINP.GT.0.0)THEN ! !## remove small percentages ! DO ILAY=1,N; IF(TLP(ILAY).LT.MINP)TLP(ILAY)=0.0; ENDDO ! !## normalize tlp() again ! IF(SUM(TLP).GT.0.0)TLP=(1.0/SUM(TLP))*TLP ! ENDIF ! ! !## if no layers has been used for the assignment, try to allocate it to the nearest ! IF(ICLAY.EQ.1.AND.SUM(TLP).EQ.0.0)THEN ! ZM=(Z1+Z2)/2.0; DZ=99999.0; JLAY=0 ! DO ILAY=1,N ! ZT=TOP(ILAY); ZB=BOT(ILAY) ! IF(ABS(ZT-ZM).LT.DZ.OR.ABS(ZB-ZM).LT.DZ)THEN ! DZ =MIN(ABS(ZT-ZM),ABS(ZB-ZM)) ! JLAY=ILAY ! ENDIF ! ENDDO ! IF(JLAY.NE.0)TLP(JLAY)=-1.0 ! ENDIF ! ! !## make sure only one layer is assigned whenever z1.eq.z2 ! IF(IDIFF.EQ.1)THEN ! K=0; ZT=0.0; DO ILAY=1,N ! IF(ABS(TLP(ILAY)).GT.ZT)THEN ! ZT=ABS(TLP(ILAY)); K=ILAY ! ENDIF ! ENDDO ! IF(K.GT.0)THEN ! ZT=TLP(K) ! TLP=0.0; TLP(K)=1.0 ! IF(ZT.LT.0.0)TLP(K)=-1.0*TLP(K) ! ENDIF ! ENDIF ! ! IF(SUM(TLP).NE.SUM(TLP))THEN ! WRITE(*,*) ! ENDIF ! ! !## nothing in model, whenever system on top of model, put them in first modellayer with thickness ! IF(SUM(TLP).EQ.0.0)THEN ! IF(Z1.GE.TOP(1))THEN ! DO ILAY=1,N ! IF(TOP(ILAY)-BOT(ILAY).GT.0.0.AND.KH(ILAY).GT.MINKH)THEN; TLP(ILAY)=1.0; EXIT; ENDIF ! ENDDO ! ENDIF ! ENDIF ! ! DEALLOCATE(L,TL,IL) ! ! END SUBROUTINE UTL_PCK_GETTLP ! ! !###====================================================================== ! SUBROUTINE UTL_LISTOFFILES(FNAME_IN,STRING,BACTION,TEXT,HELP) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(OUT) :: BACTION ! INTEGER,PARAMETER :: STRLEN=256 ! INTEGER :: ITYPE ! TYPE(WIN_MESSAGE) :: MESSAGE ! CHARACTER(LEN=STRLEN),POINTER,DIMENSION(:),INTENT(INOUT) :: FNAME_IN ! CHARACTER(LEN=*),INTENT(IN),DIMENSION(6) :: STRING ! CHARACTER(LEN=STRLEN),POINTER,DIMENSION(:) :: FNAME => NULL() ! CHARACTER(LEN=STRLEN) :: EFNAME ! CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: TEXT ! CHARACTER(LEN=256),INTENT(IN),OPTIONAL :: HELP ! INTEGER,DIMENSION(:),ALLOCATABLE :: LRLIST,ILIST,JLIST ! INTEGER :: N,DID,I,J,NL,NR ! ! DID=WINFODIALOG(CURRENTDIALOG) ! ! !## store copy of filenames ! IF(ASSOCIATED(FNAME_IN))THEN ! ALLOCATE(FNAME(SIZE(FNAME_IN))) ! IF(STRING(1).EQ.'IMODMANAGER')THEN ! DO I=1,SIZE(FNAME); FNAME(I)=FNAME_IN(I)(2:); ENDDO ! ELSE ! DO I=1,SIZE(FNAME); FNAME(I)=FNAME_IN(I); ENDDO ! ENDIF ! ENDIF ! ! !## Define "String" for changing names on push buttons and window title if "String" is available. ! IF(STRING(1).EQ.'IMODMANAGER')THEN ! CALL WDIALOGLOAD(ID_DLISTOFFILES2,ID_DLISTOFFILES2) ! CALL WDIALOGPUTIMAGE(ID_RIGHT,ID_ICONRIGHT,1) ! CALL WDIALOGPUTIMAGE(ID_LEFT,ID_ICONLEFT,1) ! NR=0; NL=SIZE(FNAME_IN); ALLOCATE(LRLIST(NL),ILIST(NL),JLIST(NL)) ! !## all on left menu ! DO I=1,SIZE(FNAME) ! IF(FNAME_IN(I)(1:1).EQ.'-')LRLIST(I)= I ! IF(FNAME_IN(I)(1:1).EQ.'+')LRLIST(I)=-I ! ENDDO ! ELSE ! CALL WDIALOGLOAD(ID_DLISTOFFILES1,ID_DLISTOFFILES1) ! CALL WDIALOGPUTIMAGE(ID_OPEN,ID_ICONOPEN,1) ! CALL WDIALOGPUTIMAGE(ID_DELETE,ID_ICONDELETE,1) ! ENDIF ! ! CALL WDIALOGTITLE('Extra files') ! IF(LEN_TRIM(STRING(2)).NE.0)CALL WDIALOGTITLE(TRIM(STRING(2))) !## changes title of dialog window ! IF(LEN_TRIM(STRING(3)).NE.0)CALL WDIALOGPUTSTRING(IDCANCEL,TRIM(STRING(3))) !## changes text on close-button ! IF(LEN_TRIM(STRING(4)).NE.0)CALL WDIALOGPUTSTRING(IDHELP,TRIM(STRING(4))) !## changes text on help-button ! IF(LEN_TRIM(STRING(5)).NE.0)CALL WDIALOGPUTSTRING(IDOK,TRIM(STRING(5))) !## changes text on apply-button ! IF(LEN_TRIM(STRING(6)).NE.0)CALL WDIALOGPUTSTRING(IDF_STRING1,TRIM(STRING(6))//': '//TRIM(TEXT))!## changes text on text field ! ! IF(.NOT.PRESENT(HELP))CALL WDIALOGFIELDSTATE(IDHELP,3) ! ! IF(STRING(1).EQ.'IMODMANAGER')THEN ! CALL UTL_LISTOFFILES_FILLMENU(LRLIST,FNAME,FNAME_IN,ILIST,JLIST) ! CALL WDIALOGFIELDSTATE(ID_RIGHT,0) ! CALL WDIALOGFIELDSTATE(ID_LEFT,0) ! ELSE ! CALL UTL_LISTOFFILES_MANIPULATE(FNAME,STRLEN,0,EFNAME) ! ENDIF ! CALL WDIALOGSHOW(-1,-1,0,3) ! ! BACTION=0 ! DO ! CALL WMESSAGE(ITYPE,MESSAGE) ! SELECT CASE (ITYPE) ! CASE(FIELDCHANGED) ! !## previous field ! SELECT CASE (MESSAGE%VALUE1) ! CASE (IDF_MENU1) ! END SELECT ! !## next field ! SELECT CASE (MESSAGE%VALUE2) ! CASE (IDF_MENU1) ! IF(STRING(1).EQ.'IMODMANAGER')THEN ! CALL WDIALOGGETMENU(IDF_MENU1,ILIST) ! CALL WDIALOGFIELDSTATE(ID_RIGHT,MIN(1,SUM(ILIST))) ! ENDIF ! CASE (IDF_MENU2) ! IF(STRING(1).EQ.'IMODMANAGER')THEN ! CALL WDIALOGGETMENU(IDF_MENU2,JLIST) ! CALL WDIALOGFIELDSTATE(ID_LEFT,MIN(1,SUM(JLIST))) ! ENDIF ! END SELECT ! ! CASE(PUSHBUTTON) ! SELECT CASE (MESSAGE%VALUE1) ! CASE (ID_OPEN) ! IF(UTL_WSELECTFILE('Files ('//TRIM(STRING(1))//')|'//TRIM(STRING(1))//'|',LOADDIALOG+MUSTEXIST+PROMPTON+ & ! DIRCHANGE+APPENDEXT+MULTIFILE,EFNAME,'Load Files ('//TRIM(STRING(1))//')'))CALL UTL_LISTOFFILES_MANIPULATE(FNAME,STRLEN,1,EFNAME) ! CASE (ID_DELETE) ! CALL WDIALOGGETMENU(IDF_MENU1,N,EFNAME) ! CALL WMESSAGEBOX(YESNO,QUESTIONICON,COMMONNO,'Are you sure to remove the file:'//CHAR(13)// & ! TRIM(EFNAME),'Question'); IF(WINFODIALOG(4).EQ.1)CALL UTL_LISTOFFILES_MANIPULATE(FNAME,STRLEN,-1,EFNAME) ! ! CASE (ID_RIGHT,ID_LEFT) ! ! IF(MESSAGE%VALUE1.EQ.ID_RIGHT)THEN ! !## get selected files in left menu field ! CALL WDIALOGGETMENU(IDF_MENU1,ILIST) ! J=0; DO I=1,SIZE(LRLIST) ! IF(LRLIST(I).GT.0)THEN ! J=J+1; IF(ILIST(J).EQ.1)LRLIST(I)=-1*LRLIST(I) ! ENDIF ! ENDDO ! ELSE ! !## get selected files in right menu field ! CALL WDIALOGGETMENU(IDF_MENU2,JLIST) ! J=0; DO I=1,SIZE(LRLIST) ! IF(LRLIST(I).LT.0)THEN ! J=J+1; IF(JLIST(J).EQ.1)LRLIST(I)=-1*LRLIST(I) ! ENDIF ! ENDDO ! ENDIF ! ! CALL UTL_LISTOFFILES_FILLMENU(LRLIST,FNAME,FNAME_IN,ILIST,JLIST) ! ! CALL WDIALOGFIELDSTATE(ID_RIGHT,0); CALL WDIALOGFIELDSTATE(ID_LEFT,0) ! ! CASE (IDOK) ! BACTION=1 ! !## copy adjusted filename ! IF(STRING(1).EQ.'IMODMANAGER')THEN ! NR=0; DO I=1,SIZE(LRLIST) ! IF(LRLIST(I).LT.0)THEN; NR=NR+1; FNAME(NR)=FNAME_IN(I); ENDIF ! ENDDO ! IF(ASSOCIATED(FNAME_IN))DEALLOCATE(FNAME_IN) ! ALLOCATE(FNAME_IN(NR)); DO I=1,NR; FNAME_IN(I)=FNAME(I); ENDDO ! ELSE ! IF(ASSOCIATED(FNAME))THEN ! ALLOCATE(FNAME_IN(SIZE(FNAME))); DO I=1,SIZE(FNAME); FNAME_IN(I)=FNAME(I); ENDDO ! ENDIF ! ENDIF ! EXIT ! CASE (IDHELP) ! CALL UTL_LISTOFFILES_GETHELP(HELP) ! CASE (IDCANCEL) ! EXIT ! END SELECT ! END SELECT ! ! ENDDO ! ! IF(ASSOCIATED(FNAME))DEALLOCATE(FNAME) ! IF(ALLOCATED(LRLIST))DEALLOCATE(LRLIST) ! IF(ALLOCATED(ILIST))DEALLOCATE(ILIST); IF(ALLOCATED(JLIST))DEALLOCATE(JLIST) ! ! CALL WDIALOGUNLOAD(); IF(DID.NE.0)CALL WDIALOGSELECT(DID) ! ! END SUBROUTINE UTL_LISTOFFILES ! ! !###====================================================================== ! SUBROUTINE UTL_LISTOFFILES_FILLMENU(LRLIST,FNAME,FNAME_IN,ILIST,JLIST) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),DIMENSION(:),INTENT(IN) :: FNAME_IN ! CHARACTER(LEN=*),DIMENSION(:),INTENT(OUT) :: FNAME ! INTEGER,DIMENSION(:),INTENT(INOUT) :: LRLIST,ILIST,JLIST ! INTEGER :: NR,NL,I ! ! !## fill left menu ! NL=0; DO I=1,SIZE(LRLIST); IF(LRLIST(I).GT.0)THEN; NL=NL+1; FNAME(NL)=FNAME_IN(I)(INDEX(FNAME_IN(I),'\',.TRUE.)+1:); ENDIF; ENDDO ! IF(NL.GT.0)THEN ! ILIST=0; CALL WDIALOGPUTMENU(IDF_MENU1,FNAME,NL,ILIST) ! CALL WDIALOGFIELDSTATE(IDF_MENU1,1) ! ELSE ! CALL WDIALOGCLEARFIELD(IDF_MENU1); CALL WDIALOGFIELDSTATE(IDF_MENU1,0) ! ENDIF ! ! !## fill right menu ! NR=0; DO I=1,SIZE(LRLIST); IF(LRLIST(I).LT.0)THEN; NR=NR+1; FNAME(NR)=FNAME_IN(I)(INDEX(FNAME_IN(I),'\',.TRUE.)+1:); ENDIF; ENDDO ! IF(NR.GT.0)THEN ! JLIST=0; CALL WDIALOGPUTMENU(IDF_MENU2,FNAME,NR,JLIST) ! CALL WDIALOGFIELDSTATE(IDF_MENU2,1) ! ELSE ! CALL WDIALOGCLEARFIELD(IDF_MENU2); CALL WDIALOGFIELDSTATE(IDF_MENU2,0) ! ENDIF ! ! END SUBROUTINE UTL_LISTOFFILES_FILLMENU ! ! !###====================================================================== ! SUBROUTINE UTL_LISTOFFILES_MANIPULATE(FNAME,STRLEN,IADD,EFNAME) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: IADD,STRLEN ! CHARACTER(LEN=STRLEN),INTENT(IN) :: EFNAME ! CHARACTER(LEN=STRLEN),POINTER,DIMENSION(:),INTENT(INOUT) :: FNAME ! CHARACTER(LEN=STRLEN),POINTER,DIMENSION(:) :: FNAME_BU ! INTEGER :: I,J,K,II,ISEL,NFILE ! CHARACTER(LEN=256) :: FLIST ! CHARACTER(LEN=256),ALLOCATABLE,DIMENSION(:) :: FNAMES ! ! NULLIFY(FNAME_BU) ! ! !## get number of files selected ! K=INDEX(EFNAME,CHAR(0)) ! IF(K.GT.0)THEN ! FLIST=EFNAME ! NFILE=0 ! I=K+1 ! DO WHILE(.TRUE.) ! J=INDEX(FLIST(I:),CHAR(0)) ! NFILE=NFILE+1 ! IF(J.EQ.0)EXIT ! I=I+J ! END DO ! ELSE ! NFILE=1 ! ENDIF ! ! !## collect filenames ! ALLOCATE(FNAMES(NFILE)) ! DO II=1,NFILE ! !## construct new name in multi-file selection mode ! IF(NFILE.GT.1)THEN ! I=INDEX(FLIST,CHAR(0))+1 ! DO K=1,II-1 ! J=INDEX(FLIST(I:),CHAR(0)) ! I=I+J ! END DO ! J=INDEX(FLIST(I:),CHAR(0)) ! K=INDEX(FLIST,CHAR(0))-1 ! IF(J.EQ.0)THEN ! FNAMES(II)=FLIST(:K)//'\'//FLIST(I:) ! ELSE ! J=J+I ! FNAMES(II)=FLIST(:K)//'\'//FLIST(I:J-1) ! ENDIF ! J=INDEXNOCASE(FNAMES(II),CHAR(0),.TRUE.) ! IF(J.GT.0)FNAMES(II)=FNAMES(II)(:J-1) ! ELSE ! FNAMES(II)=EFNAME ! ENDIF ! ENDDO ! ! DO II=1,NFILE ! ! !## add file ! IF(IADD.EQ.1)THEN ! ! IF(ASSOCIATED(FNAME))THEN ! !## check double files !! DO I=1,SIZE(FNAME); IF(TRIM(UTL_CAP(FNAME(I),'U')).EQ.TRIM(UTL_CAP(EFNAME,'U')))EXIT; ENDDO ! DO I=1,SIZE(FNAME); IF(TRIM(UTL_CAP(FNAME(I),'U')).EQ.TRIM(UTL_CAP(FNAMES(II),'U')))EXIT; ENDDO ! IF(I.LE.SIZE(FNAME))THEN ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'Current file already exists'//CHAR(13)//TRIM(FNAMES(II)),'Error') !! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'Current file already exists'//CHAR(13)//TRIM(EFNAME),'Error') ! RETURN ! ELSE ! ALLOCATE(FNAME_BU(SIZE(FNAME)+1)) ! DO I=1,SIZE(FNAME); FNAME_BU(I)=FNAME(I); ENDDO; FNAME_BU(I)=FNAMES(II); ISEL=I !! DO I=1,SIZE(FNAME); FNAME_BU(I)=FNAME(I); ENDDO; FNAME_BU(I)=EFNAME; ISEL=I ! DEALLOCATE(FNAME) ! ENDIF ! ELSE ! ALLOCATE(FNAME_BU(1)); FNAME_BU(1)=FNAMES(II); ISEL=1 !! ALLOCATE(FNAME_BU(1)); FNAME_BU(1)=EFNAME; ISEL=1 ! ENDIF ! FNAME=>FNAME_BU ! ! !## remove file ! ELSEIF(IADD.EQ.-1)THEN ! ! IF(SIZE(FNAME)-1.GT.0)THEN ! ALLOCATE(FNAME_BU(SIZE(FNAME)-1)) ! J=0; DO I=1,SIZE(FNAME) ! IF(TRIM(UTL_CAP(FNAME(I),'U')).NE.TRIM(UTL_CAP(FNAMES(II),'U')))THEN !! IF(TRIM(UTL_CAP(FNAME(I),'U')).NE.TRIM(UTL_CAP(EFNAME,'U')))THEN ! J=J+1; FNAME_BU(J)=FNAME(I) ! ELSE ! ISEL=J ! ENDIF ! ENDDO ! DEALLOCATE(FNAME); FNAME=>FNAME_BU ! ELSE ! DEALLOCATE(FNAME) ! ENDIF ! ! ELSE ! ! ISEL=1 ! ! ENDIF ! ! ENDDO ! ! IF(ASSOCIATED(FNAME))THEN ! CALL WDIALOGPUTMENU(IDF_MENU1,FNAME,SIZE(FNAME),MAX(1,ISEL)) ! CALL WDIALOGFIELDSTATE(IDF_MENU1,1) ! CALL WDIALOGFIELDSTATE(ID_DELETE,1) ! ELSE ! CALL WDIALOGPUTMENU(IDF_MENU1,(/'Add files ...'/),1,1) ! CALL WDIALOGFIELDSTATE(IDF_MENU1,2) ! CALL WDIALOGFIELDSTATE(ID_DELETE,2) ! ENDIF ! ! END SUBROUTINE UTL_LISTOFFILES_MANIPULATE ! !!###========================================================================= ! SUBROUTINE UTL_LISTOFFILES_GETHELP(HELP) !!###========================================================================= ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: HELP ! LOGICAL :: LEX ! INTEGER :: I ! CHARACTER(LEN=256) :: LINE ! CHARACTER(LEN=10) :: EXT ! ! !## error/warning checking ! IF(TRIM(HELP).EQ.'')THEN ! CALL WMESSAGEBOX(OKONLY,COMMONOK,EXCLAMATIONICON,'You should specify the keyword HELP in the *.INI file of the plugin.'// & ! 'E.g. HELP=D:\Plugin1\WaterbalanceTool\HELP.PDF','Warning') ! RETURN ! ENDIF ! INQUIRE(FILE=TRIM(HELP),EXIST=LEX) ! IF(.NOT.LEX)THEN ! CALL WMESSAGEBOX(OKONLY,COMMONOK,EXCLAMATIONICON,'Cannot find the specified HELP= '//TRIM(HELP),'Warning') ! RETURN ! ENDIF ! ! !#find file extension ! I=INDEXNOCASE(TRIM(HELP),'.',.TRUE.) ! EXT=HELP(I+1:) ! ! !## open help file ! IF(UTL_CAP(TRIM(EXT),'U').EQ.'PDF')THEN ! !## acrobat reader ! IF(PREFVAL(13).EQ.'')THEN ! CALL WMESSAGEBOX(OKONLY,COMMONOK,EXCLAMATIONICON,'You should specify the keyword ACROBATREADER in the Preference file of iMOD.'// & ! 'E.g. ACROBATREADER=c:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe','Warning') ! RETURN ! ENDIF ! INQUIRE(FILE=PREFVAL(13),EXIST=LEX) ! IF(.NOT.LEX)THEN ! CALL WMESSAGEBOX(OKONLY,COMMONOK,EXCLAMATIONICON,'Cannot find the specified ACROBATREADER='//TRIM(PREFVAL(13)),'Warning') ! RETURN ! ENDIF ! LINE='"'//TRIM(PREFVAL(13))//' '//TRIM(HELP)//'"' ! CALL IOSCOMMAND(LINE,PROCSILENT) ! ! ELSEIF(UTL_CAP(TRIM(EXT),'U').EQ.'HTM')THEN ! !## webpage ! CALL WHELPFILE(TRIM(HELP)) ! ! ENDIF ! ! END SUBROUTINE UTL_LISTOFFILES_GETHELP ! ! !###====================================================================== ! SUBROUTINE UTL_READTXTFILE(FNAME,TEXT) ! !###====================================================================== ! !## Subroutine to read text containing multiple lines ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(INOUT) :: TEXT ! CHARACTER(LEN=:),ALLOCATABLE :: LINE ! CHARACTER(LEN=*), INTENT(IN) :: FNAME ! INTEGER :: IU,IOS,LENTXT ! LOGICAL :: LEX ! ! TEXT='' ! ! INQUIRE(FILE=FNAME,EXIST=LEX) ! IF(.NOT.LEX)THEN; TEXT='No textfile with additional information found.'; RETURN; ENDIF ! IU=UTL_GETUNIT(); CALL OSD_OPEN(IU,FILE=FNAME,STATUS='OLD',ACTION='READ') ! IF(IU.EQ.0)RETURN ! ! LENTXT = LEN(TEXT) ! ALLOCATE(CHARACTER(LEN=LENTXT) :: LINE) ! ! DO ! READ(IU,'(A)',IOSTAT=IOS) LINE ! IF(IOS.NE.0)EXIT ! IF(LEN_TRIM(TEXT).EQ.0)THEN ! TEXT=TRIM(LINE) ! ELSE ! TEXT=TRIM(TEXT)//CHAR(13)//CHAR(10)//TRIM(LINE) ! ENDIF ! ENDDO ! CLOSE(IU) ! ! DEALLOCATE(LINE) ! ! END SUBROUTINE UTL_READTXTFILE ! ! !###=================================================================== ! SUBROUTINE UTL_MODEL1CHECKFNAME(FNAME,LU) ! !###=================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: LU ! CHARACTER(LEN=*),INTENT(IN) :: FNAME ! REAL :: X ! INTEGER :: IOS,I,J ! LOGICAL :: LEX ! ! IF(LEN_TRIM(FNAME).EQ.0)THEN ! IF(LU.EQ.0)CALL UTL_PRINTTEXT('No file given',2) ! IF(LU.GT.0)THEN ! WRITE(LU,*) 'Error:' ! WRITE(LU,*) ' No file given' ! ENDIF ! ENDIF ! ! !get first non character ! I=0 ! DO ! I=I+1 ! J=ICHAR(FNAME(I:I)) ! IF(J.GT.32)EXIT ! ENDDO ! ! X=UTL_GETREAL(FNAME(I:),IOS) ! IF(IOS.NE.0)THEN ! ! INQUIRE(FILE=FNAME(I:),OPENED=LEX) ! IF(LEX)RETURN ! ! INQUIRE(FILE=FNAME(I:),EXIST=LEX) ! IF(.NOT.LEX)THEN ! IF(LU.EQ.0)CALL UTL_PRINTTEXT('File '//TRIM(FNAME(I:))//' does not exist !',2) ! IF(LU.GT.0)THEN ! WRITE(LU,*) 'Error:' ! WRITE(LU,*) TRIM(FNAME(I:))//' does not exist!' ! ENDIF ! ENDIF ! ! ENDIF ! ! END SUBROUTINE UTL_MODEL1CHECKFNAME ! ! !###==================================================================== ! SUBROUTINE UTL_APPLYFCT_R(A,NODATA,NROW,NCOL,FCT,IMP) ! !###==================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: NROW,NCOL ! REAL,INTENT(IN) :: FCT,IMP,NODATA ! REAL,INTENT(INOUT),DIMENSION(NCOL,NROW) :: A ! INTEGER :: IROW,ICOL ! ! DO IROW=1,NROW ! DO ICOL=1,NCOL ! IF(A(ICOL,IROW).NE.NODATA)THEN ! A(ICOL,IROW)=A(ICOL,IROW)*FCT ! A(ICOL,IROW)=A(ICOL,IROW)+IMP ! ENDIF ! END DO ! END DO ! ! END SUBROUTINE UTL_APPLYFCT_R ! ! !###==================================================================== ! SUBROUTINE UTL_APPLYFCT_I(A,NODATA,NROW,NCOL,FCT,IMP) ! !###==================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: NROW,NCOL ! REAL,INTENT(IN) :: FCT,IMP,NODATA ! INTEGER,INTENT(INOUT),DIMENSION(NCOL,NROW) :: A ! INTEGER :: IROW,ICOL ! ! DO IROW=1,NROW ! DO ICOL=1,NCOL ! IF(A(ICOL,IROW).NE.NODATA)THEN ! A(ICOL,IROW)=A(ICOL,IROW)*FCT ! A(ICOL,IROW)=A(ICOL,IROW)+IMP ! ENDIF ! END DO ! END DO ! ! END SUBROUTINE UTL_APPLYFCT_I ! ! !###=================================================================== ! SUBROUTINE UTL_STRING(LINE) ! !###=================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(INOUT) :: LINE ! ! CALL UTL_DELNULCHAR(LINE) ! CALL UTL_DELCONTROLM(LINE) ! ! END SUBROUTINE UTL_STRING ! ! !###=================================================================== ! SUBROUTINE UTL_FILENAME(LINE) ! !###=================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(INOUT) :: LINE ! ! CALL UTL_SWAPSLASH(LINE) ! LINE=ADJUSTL(LINE) ! ! END SUBROUTINE UTL_FILENAME ! ! !###=================================================================== ! SUBROUTINE UTL_DELNULCHAR(LINE) ! !###=================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(INOUT) :: LINE ! INTEGER :: I ! ! !## find ^M (null character) ! I=INDEX(LINE,CHAR(0)) ! IF(I.EQ.0)RETURN ! !## replace by space ! LINE(I:I)=CHAR(32) ! ! END SUBROUTINE UTL_DELNULCHAR ! ! !###=================================================================== ! SUBROUTINE UTL_DELCONTROLM(LINE) ! !###=================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(INOUT) :: LINE ! INTEGER :: I ! ! !#find ^M (carriage return) ! I=INDEX(LINE,CHAR(13)) ! IF(I.LE.0)RETURN ! !#replace by space ! LINE(I:I)=CHAR(32) ! ! END SUBROUTINE UTL_DELCONTROLM ! ! !###=================================================================== ! REAL FUNCTION UTL_GETREAL(LINE,IOS) ! !###=================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(OUT) :: IOS ! CHARACTER(LEN=*),INTENT(IN) :: LINE ! ! READ(LINE,*,IOSTAT=IOS) UTL_GETREAL ! IF(IOS.NE.0)UTL_GETREAL=0.0 ! ! END FUNCTION UTL_GETREAL ! ! !###=================================================================== ! CHARACTER(LEN=256) FUNCTION UTL_GETFNAME(LINE) ! !###=================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: LINE ! INTEGER :: I,J,K ! ! K=39 ! I=INDEX(LINE,CHAR(K),.FALSE.) !## '-tje ! IF(I.EQ.0)THEN ! K=34 ! I=INDEX(LINE,CHAR(K),.FALSE.) !## "-tje ! ENDIF ! !## quotes found, find other, to be sure it is consistent ! IF(I.GT.0)THEN ! J=INDEX(LINE,CHAR(K),.TRUE.) ! IF(I.EQ.J)THEN ! CALL UTL_PRINTTEXT('',0) ! CALL UTL_PRINTTEXT('Missing second quote '//CHAR(K)//' in line:',0) ! CALL UTL_PRINTTEXT(TRIM(LINE),0) ! CALL UTL_PRINTTEXT('',2) ! ENDIF ! UTL_GETFNAME=LINE(I+1:J-1) ! ELSE ! !## search for comma's, backward ! I=INDEX(TRIM(LINE),',',.TRUE.) ! J=INDEX(TRIM(LINE),' ',.TRUE.) ! UTL_GETFNAME=LINE(MAX(I+1,J+1):) ! ENDIF ! ! END FUNCTION UTL_GETFNAME ! ! !###=================================================================== ! SUBROUTINE UTL_SWAPSLASH(LINE) ! !###=================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(INOUT) :: LINE ! INTEGER :: I,IFR,ITO ! ! IF(OS.EQ.1)THEN ! IFR=47 ! ITO=92 ! ELSEIF(OS.EQ.2)THEN ! IFR=92 ! ITO=47 ! ENDIF ! ! DO ! I=INDEX(LINE,CHAR(IFR)) ! IF(I.EQ.0)EXIT ! LINE(I:I)=CHAR(ITO) ! ENDDO ! ! END SUBROUTINE UTL_SWAPSLASH ! ! !###====================================================================== ! SUBROUTINE UTL_DIR_LEVEL_UP(FNAME) ! !###====================================================================== ! ! IMPLICIT NONE ! ! CHARACTER(LEN=*), INTENT(INOUT) :: FNAME ! INTEGER :: N ! ! N = LEN_TRIM(FNAME) ! ! IF (N==0) RETURN ! ! IF (FNAME(1:1)=='.')THEN ! WRITE(FNAME,'(2A)') '..\',TRIM(FNAME) ! END IF ! ! CALL UTL_SWAPSLASH(FNAME) ! ! END SUBROUTINE UTL_DIR_LEVEL_UP ! ! !###=================================================================== ! SUBROUTINE UTL_PRINTTEXT(TXT,TXTTYPE) ! !###=================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: TXT ! INTEGER,INTENT(IN) :: TXTTYPE ! ! SELECT CASE (TXTTYPE) ! !## file ! CASE (0) ! WRITE(*,'(A)') TRIM(TXT) ! !## information ! CASE (-1,1) ! WRITE(*,'(A)') TRIM(TXT) ! !IF(IFLAG(1).EQ.1)PAUSE ! !## error ! CASE (2) ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,TRIM(TXT),'Error') ! CASE DEFAULT ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,TRIM(TXT),'Error') ! END SELECT ! ! END SUBROUTINE UTL_PRINTTEXT ! ! !###====================================================================== ! SUBROUTINE UTL_PROFILE_GETVIEWBOX(X1,Y1,X2,Y2,XSIGHT,XYPOL,XMN,YMN,XMX,YMX) ! !###====================================================================== ! IMPLICIT NONE ! REAL,INTENT(IN) :: X1,X2,Y1,Y2,XSIGHT ! REAL,INTENT(OUT) :: XMN,YMN,XMX,YMX ! REAL,DIMENSION(4,2),INTENT(OUT) :: XYPOL ! ! CALL UTL_PROFILE_COMPVIEWBOX(X1,X2,Y1,Y2,XYPOL,XSIGHT) ! XMN=MINVAL(XYPOL(:,1)) ! XMX=MAXVAL(XYPOL(:,1)) ! YMN=MINVAL(XYPOL(:,2)) ! YMX=MAXVAL(XYPOL(:,2)) ! ! END SUBROUTINE UTL_PROFILE_GETVIEWBOX ! ! !###====================================================================== ! SUBROUTINE UTL_PROFILE_COMPVIEWBOX(X1,X2,Y1,Y2,XYPOL,XSIGHT) ! !###====================================================================== ! IMPLICIT NONE ! REAL,PARAMETER :: RAD=360.0/(2.0*3.1415) ! REAL,INTENT(IN) :: X1,X2,Y1,Y2,XSIGHT ! REAL,INTENT(OUT),DIMENSION(4,2) :: XYPOL ! REAL :: DX,DY,TNG ! ! DX =X2-X1 ! DY =Y2-Y1 ! IF(DY.EQ.0.0)TNG=0.0 ! IF(ABS(DY).GT.0.0)TNG=ATAN2(DY,DX) ! TNG=TNG+90.0/RAD ! ! XYPOL(1,1)=X1+COS(TNG)*XSIGHT ! XYPOL(1,2)=Y1+SIN(TNG)*XSIGHT ! XYPOL(2,1)=X2+COS(TNG)*XSIGHT ! XYPOL(2,2)=Y2+SIN(TNG)*XSIGHT ! XYPOL(3,1)=X2-COS(TNG)*XSIGHT ! XYPOL(3,2)=Y2-SIN(TNG)*XSIGHT ! XYPOL(4,1)=X1-COS(TNG)*XSIGHT ! XYPOL(4,2)=Y1-SIN(TNG)*XSIGHT ! ! END SUBROUTINE UTL_PROFILE_COMPVIEWBOX ! ! !###====================================================================== ! LOGICAL FUNCTION UTL_LOADIMAGE(BMPFNAME,N,IBMPDATA,IBATCH) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: BMPFNAME ! INTEGER,INTENT(IN) :: N ! INTEGER,INTENT(OUT),DIMENSION(N) :: IBMPDATA ! INTEGER,INTENT(IN) :: IBATCH ! CHARACTER(LEN=256) :: LINE ! INTEGER :: I ! LOGICAL :: LEX ! ! UTL_LOADIMAGE=.TRUE. ! ! INQUIRE(FILE=BMPFNAME,EXIST=LEX) ! IF(.NOT.LEX)THEN ! IF(IBATCH.EQ.0)CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'File: '//TRIM(BMPFNAME)//CHAR(13)//'does not exists','Error') ! IF(IBATCH.EQ.1)WRITE(*,'(A)') 'File: '//TRIM(BMPFNAME)//' does not exists' ! RETURN ! ENDIF ! ! !## clear existing error ! I=WINFOERROR(1) ! CALL IGRLOADIMAGEDATA(BMPFNAME,IBMPDATA) ! I=WINFOERROR(1) ! ! IF(I.EQ.0)RETURN ! ! CALL WINFOERRORMESSAGE(I,LINE) ! IF(IBATCH.EQ.0)CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'Error reading file:'//CHAR(13)// & ! TRIM(BMPFNAME)//CHAR(13)//'Error message:'//CHAR(13)//TRIM(LINE),'Error') ! IF(IBATCH.EQ.1)WRITE(*,'(A)') 'Error reading file:'//TRIM(BMPFNAME)//' Error message:'//TRIM(LINE) ! ! UTL_LOADIMAGE=.FALSE. ! ! END FUNCTION UTL_LOADIMAGE ! ! !###====================================================================== ! INTEGER FUNCTION UTL_GETIDPROC(PROC,ICLEAN) ! !###====================================================================== ! IMPLICIT NONE ! TYPE(PROCOBJ),INTENT(INOUT),POINTER,DIMENSION(:) :: PROC ! TYPE(PROCOBJ),POINTER,DIMENSION(:) :: PROC_BU ! INTEGER,INTENT(IN) :: ICLEAN ! INTEGER :: I,J,N,ISTATUS,IEXCOD ! CHARACTER(LEN=256) :: STRING ! INTEGER,DIMENSION(2) :: PID ! ! IF(ASSOCIATED(PROC))THEN ! !## evaluate current status ! DO I=1,SIZE(PROC) ! PID=PROC(I)%ID ! ! !## not running free, process ! IF(ISTATUS.EQ.0)THEN ! !## non-blocked process not stopped correctly ! IF(PROC(I)%IFLAGS(2).EQ.0.AND.IEXCOD.NE.0)THEN ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,TRIM(STRING)//CHAR(13)//'in program:'//TRIM(PROC(I)%CID),'Program Terminated') ! ENDIF ! PROC(I)%ID=0; PROC(I)%CID=''; PROC(I)%IFLAGS=0 ! !## process is still running ! ELSEIF(ISTATUS.EQ.1)THEN ! ! ENDIF ! ENDDO ! ELSE ! ALLOCATE(PROC(1)); PROC(1)%ID=0; PROC(1)%CID=''; PROC(1)%IFLAGS=0 ! ENDIF ! ! N=SIZE(PROC) ! ! !## clean ! J=0; DO I=1,N ! IF(PROC(I)%ID.NE.0)THEN ! J=J+1; IF(I.NE.J)THEN; PROC(J)=PROC(I); ENDIF ! ENDIF ! ENDDO ! DO I=J+1,N; PROC(I)%ID=0; PROC(I)%CID=''; PROC(I)%IFLAGS=0; ENDDO ! ! !## find empty spot ! DO I=1,SIZE(PROC); IF(PROC(I)%ID.EQ.0)EXIT; ENDDO; N=I ! IF(ICLEAN.EQ.1)N=I-1 ! ! IF(N.EQ.0)THEN ! IF(ASSOCIATED(PROC))DEALLOCATE(PROC) ! ELSE ! IF(N.NE.SIZE(PROC))THEN ! ALLOCATE(PROC_BU(N)); DO I=1,N; PROC_BU(I)=PROC(I); ENDDO; DEALLOCATE(PROC) ! ALLOCATE(PROC(N+1)); DO I=1,N+1; PROC(I)%ID=0; PROC(I)%CID=''; PROC(I)%IFLAGS=0; ENDDO ! DO I=1,N; PROC(I)=PROC_BU(I); ENDDO; DEALLOCATE(PROC_BU) ! ENDIF ! ENDIF ! ! UTL_GETIDPROC=N ! ! END FUNCTION UTL_GETIDPROC ! ! !###====================================================================== ! SUBROUTINE UTL_DELSPACE(LINE1,LINE2) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: LINE1 ! CHARACTER(LEN=*),INTENT(OUT) :: LINE2 ! INTEGER :: I,J,K ! ! LINE2=''; K=0 ! J=0; DO I=1,LEN_TRIM(LINE1) ! IF(LINE1(I:I).EQ.CHAR(34).OR.LINE1(I:I).EQ.CHAR(39))THEN ! K=ABS(K-1) ! ENDIF ! !## copy non-spaces or inside quotes ! IF(LINE1(I:I).NE.CHAR(32).OR.K.EQ.1)THEN ! J=J+1; LINE2(J:J)=LINE1(I:I) ! ENDIF ! ENDDO ! ! END SUBROUTINE UTL_DELSPACE ! ! !###====================================================================== ! LOGICAL FUNCTION UTL_DATA_CSV(TXT) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),DIMENSION(:),INTENT(IN) :: TXT ! INTEGER :: I,J,ITYPE,NP ! CHARACTER(LEN=256) :: FNAME ! TYPE(WIN_MESSAGE) :: MESSAGE ! ! UTL_DATA_CSV=.FALSE. ! NP=SIZE(TXT) ! ! IF(.NOT.UTL_WSELECTFILE('Load Comma Separated File (*.csv)|*.csv|',& ! LOADDIALOG+MUSTEXIST+PROMPTON+DIRCHANGE+APPENDEXT,FNAME,& ! 'Load Comma Separated File (*.csv)'))RETURN ! ! CALL UTL_GENLABELSREAD(FNAME) ! IF(NV.LE.0)THEN ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'Cannot read column info (header) from file!','Error'); RETURN ! ENDIF ! ! CALL WDIALOGLOAD(ID_READCSV,ID_READCSV) ! IF(SIZE(TXT).GT.WINFOGRID(IDF_GRID1,GRIDROWSMAX))THEN ! CALL WDIALOGUNLOAD() ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'Cannot read more than '//TRIM(ITOS(WINFOGRID(IDF_GRID1,GRIDROWSMAX)))// & ! ' columns in this iMOD version','Error'); RETURN ! ENDIF ! ! CALL WGRIDROWS(IDF_GRID1,NP) ! ! !## put parameters ! CALL WGRIDPUTSTRING(IDF_GRID1,2,TXT,NP) ! ! !## assign variable to parameter ! IF(ALLOCATED(IACT_VAR))DEALLOCATE(IACT_VAR); ALLOCATE(IACT_VAR(NP)) ! IACT_VAR=1 ! CALL WGRIDPUTCHECKBOX(IDF_GRID1,1,IACT_VAR,NP) ! IF(ALLOCATED(ICOL_VAR))DEALLOCATE(ICOL_VAR); ALLOCATE(ICOL_VAR(NP)) ! J=0; DO I=1,NP; J=J+1; IF(J.GT.NV)J=1; ICOL_VAR(I)=J; ENDDO ! CALL WGRIDPUTMENU(IDF_GRID1,3,VAR(:,0),NV,ICOL_VAR,NP) ! IF(ASSOCIATED(CCNST))DEALLOCATE(CCNST); ALLOCATE(CCNST(NP)) ! CCNST='' ! CALL WGRIDPUTSTRING(IDF_GRID1,4,CCNST,NP) ! ! CALL WDIALOGSHOW(-1,-1,0,3) ! ! DO ! CALL WMESSAGE(ITYPE,MESSAGE) ! SELECT CASE (ITYPE) ! CASE (PUSHBUTTON) ! SELECT CASE (MESSAGE%VALUE1) ! CASE (IDOK) ! CALL WGRIDGETCHECKBOX(IDF_GRID1,1,IACT_VAR,NP) ! CALL WGRIDGETMENU(IDF_GRID1,3,ICOL_VAR,NP) ! CALL WGRIDGETSTRING(IDF_GRID1,4,CCNST,NP) ! EXIT ! CASE (IDHELP) ! CALL IMODGETHELP('2.5.10','iF.CSV') ! CASE (IDCANCEL) ! EXIT ! END SELECT ! CASE (FIELDCHANGED) ! ! END SELECT ! ENDDO ! ! CALL WDIALOGUNLOAD() ! ! UTL_DATA_CSV=.TRUE. ! ! END FUNCTION UTL_DATA_CSV ! ! !###====================================================================== ! SUBROUTINE UTL_GENLABELSGET(CID,JL) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: CID ! INTEGER,INTENT(OUT) :: JL ! INTEGER :: SC ! CHARACTER(LEN=52) :: STRING ! ! JL=0; IF(NV.LE.0.OR.NL.LE.0)RETURN ! ! SC=1 !## search column ! ! !## evaluate the first ! DO JL=1,NL ! STRING=VAR(SC,JL) ! !## math found ! IF(TRIM(UTL_CAP(CID,'U')).EQ.TRIM(UTL_CAP(STRING,'U')))RETURN ! END DO ! JL=0 ! ! END SUBROUTINE UTL_GENLABELSGET ! ! !###====================================================================== ! SUBROUTINE UTL_GENLABELSREAD(FNAME,SKIPLINES,ILABELS) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: FNAME ! INTEGER,INTENT(IN),OPTIONAL :: SKIPLINES,ILABELS ! INTEGER :: CFN_N_ELEM,CFN_ELEM_POS,CFN_UNQUOTE,INL ! INTEGER,ALLOCATABLE,DIMENSION(:) :: BPV,EPV ! INTEGER :: ML,I,J,INCL,IOS,IU ! CHARACTER(LEN=1256) :: STRING ! ! !## initialize table of data for gen polygons ! NV =0 ! NL =0 ! INCL=50 ! ! IU=UTL_GETUNIT() ! CALL OSD_OPEN(IU,FILE=FNAME,STATUS='OLD',ACTION='READ',IOSTAT=IOS) ! IF(IOS.NE.0)THEN ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot OPEN/READ file called:'//CHAR(13)//& ! TRIM(FNAME),'Error') ! RETURN ! ENDIF ! ! IF(PRESENT(SKIPLINES))THEN ! DO I=1,SKIPLINES; READ(IU,*); ENDDO ! ENDIF ! ! !## get number of variables ! READ(IU,'(A1256)',IOSTAT=IOS) STRING ! IF(IOS.NE.0)RETURN ! IF(LEN_TRIM(STRING).EQ.0)RETURN ! ! !## read the rest of the table in order to fill var(), 0=label ! INL=-1 ! IF(PRESENT(ILABELS))INL=-ILABELS ! ! NV=CFN_N_ELEM(' ,;',3,STRING) ! ALLOCATE(BPV(NV)); ALLOCATE(EPV(NV)) ! ALLOCATE(VAR(NV,INL+1:INCL)) ! ML=INCL ! NL=INL ! DO ! NL=NL+1 ! IF(NL.GT.ML)THEN ! ALLOCATE(DVAR(NV,INL+1:ML+INCL)) ! !## copy current part ! DO I=1,SIZE(VAR,1); DO J=INL+1,ML; DVAR(I,J)=VAR(I,J); ENDDO; ENDDO ! DEALLOCATE(VAR) ! VAR=>DVAR ! ML=ML+INCL ! NULLIFY(DVAR) ! ENDIF ! !## get variables ! I=CFN_ELEM_POS(NV,' ,;',3,STRING,1000,BPV,EPV) ! DO I=1,NV ! VAR(I,NL)='' ! IF(BPV(I).LE.LEN(STRING).AND. & ! BPV(I).LE.EPV(I))THEN ! !## maximize lengt of variable ! J=(EPV(I)-BPV(I))+1; EPV(I)=BPV(I)+MIN(MAXLEN,J)-1 ! VAR(I,NL)=STRING(BPV(I):EPV(I)) ! IF(CFN_UNQUOTE(VAR(I,NL)).LE.0)VAR(I,NL)='' ! ENDIF ! END DO ! READ(IU,'(A1256)',IOSTAT=IOS) STRING ! IF(IOS.NE.0)EXIT ! IF(LEN_TRIM(STRING).EQ.0)EXIT ! ENDDO ! CLOSE(IU) ! IF(ALLOCATED(BPV))DEALLOCATE(BPV); IF(ALLOCATED(EPV))DEALLOCATE(EPV) ! ! IF(NL.NE.ML)THEN ! ALLOCATE(DVAR(NV,INL+1:NL)) ! !## copy current part ! DO I=1,SIZE(VAR,1); DO J=INL+1,NL; DVAR(I,J)=VAR(I,J); ENDDO; ENDDO ! DEALLOCATE(VAR) ! VAR=>DVAR ! NULLIFY(DVAR) ! ENDIF ! ! END SUBROUTINE UTL_GENLABELSREAD ! ! !###====================================================================== ! SUBROUTINE UTL_GENLABELSWRITE(FNAME) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: FNAME ! INTEGER :: IU,IOS,I,J ! CHARACTER(LEN=512) :: LINE ! ! !## nothing to write ! IF(NL.LE.0)RETURN ! IF(.NOT.ASSOCIATED(VAR))RETURN ! ! IU=UTL_GETUNIT() ! CALL OSD_OPEN(IU,FILE=FNAME,STATUS='UNKNOWN',ACTION='WRITE',IOSTAT=IOS) ! IF(IOS.NE.0)THEN ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot OPEN/WRITE associated data file called:'//CHAR(13)//& ! TRIM(FNAME),'Error') ! RETURN ! ENDIF ! ! DO I=0,NL ! LINE=TRIM(VAR(1,I)) ! DO J=2,NV; LINE=TRIM(LINE)//','//TRIM(VAR(J,I)); END DO ! WRITE(IU,'(A)') TRIM(LINE) ! ENDDO ! CLOSE(IU) ! ! END SUBROUTINE UTL_GENLABELSWRITE ! ! !###====================================================================== ! SUBROUTINE UTL_GENLABELSDEALLOCATE() ! !###====================================================================== ! IMPLICIT NONE ! ! IF(ASSOCIATED(VAR))DEALLOCATE(VAR) ! IF(ALLOCATED(IVAR))DEALLOCATE(IVAR) ! IF(ALLOCATED(ICOL_VAR))DEALLOCATE(ICOL_VAR) ! IF(ALLOCATED(IACT_VAR))DEALLOCATE(IACT_VAR) ! IF(ASSOCIATED(CCNST))DEALLOCATE(CCNST) ! ! END SUBROUTINE UTL_GENLABELSDEALLOCATE ! ! !###====================================================================== ! REAL FUNCTION UTL_POLYGON1AREA(X,Y,N) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: N ! REAL,INTENT(IN),DIMENSION(N) :: X,Y ! INTEGER :: I ! ! UTL_POLYGON1AREA=0.0 ! DO I=1,N-1 ! UTL_POLYGON1AREA=UTL_POLYGON1AREA+0.5*((X(I)*Y(I+1))-(X(I+1)*Y(I))) ! END DO ! UTL_POLYGON1AREA=UTL_POLYGON1AREA+0.5*((X(N)*Y(1))-(X(1)*Y(N))) ! ! END FUNCTION UTL_POLYGON1AREA ! ! !###====================================================================== ! INTEGER FUNCTION UTL_INSIDEPOLYGON(PX,PY,XX,YY,N) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: N ! REAL,INTENT(IN) :: PX,PY ! REAL,DIMENSION(N),INTENT(IN) :: XX,YY ! INTEGER :: ND ! REAL,DIMENSION(4) :: XXD,YYD ! ! UTL_INSIDEPOLYGON=-1 ! IF(N.EQ.2)THEN ! ND=4 ! XXD(1)=XX(1); YYD(1)=YY(1) ! XXD(2)=XX(2); YYD(2)=YY(1) ! XXD(3)=XX(2); YYD(3)=YY(2) ! XXD(4)=XX(1); YYD(4)=YY(2) ! IF(IGRINSIDEPOLYGON(XXD,YYD,ND,PX,PY))UTL_INSIDEPOLYGON=1 ! ELSE ! IF(IGRINSIDEPOLYGON(XX,YY,N,PX,PY))UTL_INSIDEPOLYGON=1 ! ENDIF ! ! END FUNCTION UTL_INSIDEPOLYGON ! ! !###====================================================================== ! SUBROUTINE UTL_STDEF(X,N,NODATA,VAR,XT,NPOP) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: N ! INTEGER,INTENT(OUT) :: NPOP ! REAL,DIMENSION(N),INTENT(IN) :: X ! REAL,INTENT(IN) :: NODATA ! REAL,INTENT(OUT) :: XT,VAR ! INTEGER :: I ! REAL :: XV ! ! VAR=0.0 ! ! NPOP=0 ! XT=0.0 ! DO I=1,N ! IF(X(I).NE.NODATA)THEN ! NPOP=NPOP+1 ! XT=XT+X(I) ! ENDIF ! ENDDO ! ! IF(NPOP.LE.0)RETURN ! ! XT=XT/REAL(NPOP) ! ! NPOP=0 ! XV=0.0 ! DO I=1,N ! IF(X(I).NE.NODATA)THEN ! NPOP=NPOP+1 ! XV=XV+(X(I)-XT)**2.0 ! ENDIF ! END DO ! ! IF(XV.LE.0.0)RETURN ! VAR=SQRT(XV/REAL(NPOP)) ! ! END SUBROUTINE UTL_STDEF ! ! !###====================================================================== ! REAL FUNCTION UTL_DIST(X1,Y1,X2,Y2) ! !###====================================================================== ! IMPLICIT NONE ! REAL,INTENT(IN) :: X1,Y1,X2,Y2 ! REAL :: DX,DY ! ! UTL_DIST=0.0 ! ! DX=(X1-X2)**2.0 ! DY=(Y1-Y2)**2.0 ! IF(DX+DY.NE.0.0)UTL_DIST=SQRT(DX+DY) ! ! END FUNCTION UTL_DIST ! ! !###====================================================================== ! LOGICAL FUNCTION UTL_WSELECTFILE(FILTERSTR,IFLAGS,FILEDIR,TITLE) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: FILTERSTR ! CHARACTER(LEN=*),INTENT(INOUT) :: FILEDIR ! INTEGER,INTENT(IN) :: IFLAGS ! CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: TITLE ! INTEGER :: I,J,K,ISAVE ! CHARACTER(LEN=10) :: EXT ! ! UTL_WSELECTFILE=.FALSE. ! ! !## store original filedir ! ISAVE=1; IF(INDEX(FILEDIR,'*').GT.0)ISAVE=0 ! IF(ISAVE.EQ.1)FILEDIR=SAVEDIR ! ! DO ! ! IF(PRESENT(TITLE))THEN ! CALL WSELECTFILE(FILTERSTR,IFLAGS,FILEDIR,TITLE) ! ELSE ! CALL WSELECTFILE(FILTERSTR,IFLAGS,FILEDIR) ! ENDIF ! IF(WINFODIALOG(4).NE.1)THEN ! FILEDIR='' ! RETURN ! ENDIF ! !## check extent ... ! I=INDEX(FILEDIR,'.',.TRUE.) ! IF(I.EQ.0)EXIT ! ! IF(INDEX(FILTERSTR,'*.*').LE.0)THEN ! EXT=FILEDIR(I+1:) ! J=INDEX(UTL_CAP_BIG(FILTERSTR(1:MIN(1024,LEN(FILTERSTR))),'U'),'*.'//TRIM(UTL_CAP(EXT,'U'))) ! IF(J.NE.0)EXIT ! ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'You should select a file that agrees the supplied filterstring:'//CHAR(13)// & ! TRIM(FILTERSTR),'Error') ! ELSE ! EXIT ! ENDIF ! ! ENDDO ! ! !## removes filename from directory name before saving ! K=INDEX(FILEDIR,'\',.TRUE.) ! !## save directory name into SAVEDIR ! IF(ISAVE.EQ.1)SAVEDIR=FILEDIR(:K) ! ! UTL_WSELECTFILE=.TRUE. ! ! END FUNCTION UTL_WSELECTFILE ! ! !###====================================================================== ! SUBROUTINE IDFPLOT1BITMAP() ! !###====================================================================== ! IMPLICIT NONE ! ! CALL IGRSELECT(DRAWBITMAP,MPW%IBITMAP) ! CALL IGRAREA(0.0,0.0,1.0,1.0) ! CALL IGRUNITS(MPW%XMIN,MPW%YMIN,MPW%XMAX,MPW%YMAX) ! ! END SUBROUTINE IDFPLOT1BITMAP ! ! !###====================================================================== ! SUBROUTINE IDFPLOT2BITMAP() ! !###====================================================================== ! IMPLICIT NONE ! ! CALL IGRSELECT(DRAWWIN) ! CALL WINDOWSELECT(MPW%IWIN) ! CALL WBITMAPVIEW(MPW%IBITMAP,MPW%IX,MPW%IY,MODELESS) ! CALL IGRAREA(0.0,0.0,1.0,1.0) ! CALL IGRUNITS(MPW%XMIN,MPW%YMIN,MPW%XMAX,MPW%YMAX) ! ! END SUBROUTINE IDFPLOT2BITMAP ! ! !###====================================================================== ! SUBROUTINE IDFMEM2BITMAP() ! !###====================================================================== ! IMPLICIT NONE ! ! CALL IGRSELECT(DRAWWIN) ! CALL WINDOWSELECT(MPW%IWIN) ! CALL IGRAREA(0.0,0.0,1.0,1.0) ! CALL IGRUNITS(MPW%XMIN,MPW%YMIN,MPW%XMAX,MPW%YMAX) ! ! END SUBROUTINE IDFMEM2BITMAP ! ! !###====================================================================== ! FUNCTION REALTOSTRING(X) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=20) :: REALTOSTRING ! REAL,INTENT(IN) :: X ! INTEGER :: I ! ! WRITE(REALTOSTRING,*) X ! !eliminate all zero at the end! ! DO I=LEN_TRIM(REALTOSTRING),1,-1 ! IF(REALTOSTRING(I:I).NE.'0')EXIT ! END DO ! IF(REALTOSTRING(I:I).EQ.'.'.OR.REALTOSTRING(I:I).EQ.',')I=I-1 ! REALTOSTRING=REALTOSTRING(1:I) ! ! END FUNCTION REALTOSTRING ! !!###====================================================================== !INTEGER FUNCTION UTL_IDFGETCLASS(LEG,GRD) !!###====================================================================== !IMPLICIT NONE !TYPE(LEGENDOBJ),INTENT(IN) :: LEG !REAL,INTENT(IN) :: GRD !INTEGER :: I ! !!## default=wit! !UTL_IDFGETCLASS=WRGB(255,255,255) ! !CALL POL1LOCATE(LEG%CLASS,LEG%NCLR,REAL(GRD,8),I) !!## correct if equal to top-class boundary !IF(I.GT.0.AND.I.LE.MXCLR)THEN ! UTL_IDFGETCLASS=LEG%RGB(I) !ELSE ! IF(UTL_EQUALS_REAL(GRD,LEG%CLASS(0)))UTL_IDFGETCLASS=LEG%RGB(1) !ENDIF ! !END FUNCTION UTL_IDFGETCLASS ! !###====================================================================== ! SUBROUTINE UTL_IDFCURDIM(XMIN,YMIN,XMAX,YMAX,IDF,NC1,NC2,NR1,NR2) ! !###====================================================================== ! IMPLICIT NONE ! TYPE(IDFOBJ),INTENT(INOUT) :: IDF ! REAL,INTENT(IN) :: XMIN,YMIN,XMAX,YMAX ! REAL :: D ! INTEGER,INTENT(OUT) :: NC1,NC2,NR1,NR2 ! ! IF(IDF%IEQ.EQ.0)THEN ! ! !## min. column ! D =XMIN-IDF%XMIN ! NC1=INT(D/IDF%DX)+1 ! IF(MOD(D,IDF%DX).NE.0.0)NC1=NC1+1 ! !## max. column ! D =XMAX-IDF%XMIN ! NC2=INT(D/IDF%DX) ! !## min. row ! D =IDF%YMAX-YMAX ! NR1=INT(D/IDF%DY)+1 ! IF(MOD(D,IDF%DY).NE.0.0)NR1=NR1+1 ! !## max. row ! D =IDF%YMAX-YMIN ! NR2=INT(D/IDF%DY) ! ! ELSE ! ! !## min. column ! CALL POL1LOCATE(IDF%SX,IDF%NCOL+1,REAL(XMIN,8),NC1) ! !## max. column ! CALL POL1LOCATE(IDF%SX,IDF%NCOL+1,REAL(XMAX,8),NC2) ! !## min. row ! CALL POL1LOCATE(IDF%SY,IDF%NROW+1,REAL(YMAX,8),NR1) ! !## max. row ! CALL POL1LOCATE(IDF%SY,IDF%NROW+1,REAL(YMIN,8),NR2) ! ! ENDIF ! ! NC1=MAX(1,NC1) ! NC1=MIN(NC1,IDF%NCOL) ! NC2=MAX(1,NC2) ! NC2=MIN(NC2,IDF%NCOL) ! NR1=MAX(1,NR1) ! NR1=MIN(NR1,IDF%NROW) ! NR2=MAX(1,NR2) ! NR2=MIN(NR2,IDF%NROW) ! ! IF(IDF%IEQ.EQ.1)THEN ! IF(MPW%XMIN.GT.IDF%SX(NC1-1))NC1=NC1+1 ! IF(MPW%XMAX.LT.IDF%SX(NC2))NC2=NC2-1 ! IF(MPW%YMAX.LT.IDF%SY(NR1-1))NR1=NR1+1 ! IF(MPW%YMIN.GT.IDF%SY(NR2))NR2=NR2-1 ! ENDIF ! ! END SUBROUTINE UTL_IDFCURDIM ! ! !###====================================================================== ! SUBROUTINE UTL_IDFCRDCOR(X1,X2,Y1,Y2,WIDTH,HEIGTH) ! !###====================================================================== ! IMPLICIT NONE ! REAL,INTENT(IN) :: WIDTH,HEIGTH ! REAL,INTENT(INOUT) :: X1,X2,Y1,Y2 ! REAL :: RAT1,RAT2,X,Y,XLEN,YLEN ! ! RAT1=WIDTH/HEIGTH ! X=X2-X1 ! Y=Y2-Y1 ! RAT2=X/Y ! IF(RAT2.LT.RAT1)THEN ! YLEN=Y2-Y1 ! XLEN=YLEN*RAT1 ! X1=X1-((XLEN-X)/2.) ! X2=X1+XLEN ! ELSE ! XLEN=X2-X1 ! YLEN=XLEN/RAT1 ! Y1=Y1-((YLEN-Y)/2.) ! Y2=Y1+YLEN ! ENDIF ! ! END SUBROUTINE UTL_IDFCRDCOR ! !###====================================================================== SUBROUTINE UTL_FILLARRAY(IP,NP,B) !###====================================================================== !# read binair number (e.g. 256) and returns array (/1,0,0,1,0,0,1/) IMPLICIT NONE INTEGER,INTENT(IN) :: NP,B INTEGER,INTENT(OUT),DIMENSION(NP) :: IP INTEGER :: I,BB IP=0 BB=B DO I=1,NP IP(I)=MOD(BB,2) BB=BB/2 END DO !## make sure results are only 0/1 values DO I=1,NP IF(IP(I).LT.0.OR.IP(I).GT.1)IP(I)=0 END DO END SUBROUTINE UTL_FILLARRAY ! !###====================================================================== ! SUBROUTINE UTL_READARRAY(IP,NP,B) ! !###====================================================================== ! !# write a binair-number given an array (/1,0,0,4,0,0,7/) ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: NP ! INTEGER,INTENT(OUT) :: B ! INTEGER,INTENT(IN),DIMENSION(NP) :: IP ! INTEGER :: I,J ! ! B=0 ! DO I=1,NP ! J=MAX(0,MIN(IP(I),1)) ! B=B+(J*(2**(I-1))) ! END DO ! ! END SUBROUTINE UTL_READARRAY ! ! !###====================================================================== ! LOGICAL FUNCTION UTL_READINITFILE(CKEY,LINE,IU,IOPT) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: IU,IOPT ! CHARACTER(LEN=*),INTENT(IN) :: CKEY ! CHARACTER(LEN=*),INTENT(OUT) :: LINE ! INTEGER :: IOS,I,J,N,M,II,ITRY ! CHARACTER(LEN=7) :: FRMT ! CHARACTER(LEN=256) :: FNAME ! CHARACTER(LEN=:),ALLOCATABLE :: STR ! ! UTL_READINITFILE=.FALSE. ! ! N=LEN(LINE); WRITE(FRMT,'(A2,I4.4,A1)') '(A',N,')' ! ! !## backup line ! ALLOCATE(CHARACTER(LEN=N) :: STR) ! ! !## read from current position, if not found try from beginning ! ITRY=1 ! DO ! READ(IU,FRMT,IOSTAT=IOS) LINE ! IF(IOS.NE.0)THEN ! IF(ITRY.EQ.2)THEN ! IF(IOPT.EQ.0)THEN ! INQUIRE(UNIT=IU,NAME=FNAME); CLOSE(IU) ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD DID NOT find keyword: ['//TRIM(CKEY)//'] within Settings file:'// & ! CHAR(13)//'['//TRIM(FNAME)//']','Error') ! ENDIF ! RETURN ! ELSE ! REWIND(IU) ! ITRY=ITRY+1 ! CYCLE ! ENDIF ! ENDIF ! ! STR=LINE ! ! N=LEN(LINE) ! M=256 !## length of utl_cap() function ! !## split cap function in case ! IF(N.GT.M)THEN ! I=1; J=I+M-1 ! DO ! LINE(I:J)=UTL_CAP(LINE(I:J),'U') ! I=I+M ! IF(I.GT.N)EXIT ! J=MIN(N,I+M-1) ! ENDDO ! ELSE ! LINE=UTL_CAP(LINE,'U') ! ENDIF ! ! II=INDEX(TRIM(LINE),'!') !## skip comment lines for keyword ! I =INDEX(TRIM(LINE),TRIM(CKEY)) ! IF(II.EQ.0)II=I ! !## okay, proper line found ! IF(I.NE.0.AND.II.GE.I)THEN ! !## make sure previous to i or j no character is available ! IF(I.GE.2)THEN ! IF(LINE(I-1:I-1).NE.' ')I=0 !## not correct ! ENDIF ! !## make sure next to i or j no character or "=" sign ! IF(LINE(I+LEN_TRIM(CKEY):I+LEN_TRIM(CKEY)).NE.' '.AND. & ! LINE(I+LEN_TRIM(CKEY):I+LEN_TRIM(CKEY)).NE.'=')I=0 !## not correct ! J=INDEX(TRIM(LINE),'=') ! IF(I.NE.0.AND.J.GT.I)EXIT ! ENDIF ! ENDDO ! ! I=INDEX(LINE,'=') ! IF(I.LE.0)THEN ! INQUIRE(UNIT=IU,NAME=FNAME); CLOSE(IU) ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD misses "=" after keyword: ['//TRIM(CKEY)//'] within Settings file:'// & ! CHAR(13)//'[ '//TRIM(FNAME)//' ]','Error') ! RETURN ! ENDIF ! ! I=I+1 ! LINE(1:N-I+1)=STR(I:N) ! ! !## remove leading space, if there is one ! LINE=ADJUSTL(LINE) ! ! DEALLOCATE(STR) ! ! !## check whether there is an argment given ... ! IF(TRIM(LINE).EQ.'')THEN ! INQUIRE(UNIT=IU,NAME=FNAME); CLOSE(IU) ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD misses an argument after the "=" sign for keyword: ['//TRIM(CKEY)//'] within Settings file:'// & ! CHAR(13)//'[ '//TRIM(FNAME)//' ]','Error') ! RETURN ! ENDIF ! ! UTL_READINITFILE=.TRUE. ! ! END FUNCTION UTL_READINITFILE ! ! !###==================================================================== ! SUBROUTINE UTL_DRAWLEGENDBOX(XMIN,YMIN,XMAX,YMAX,ICLR,IWIDTH,ITYPE,IPATTERN,LEG,XT) ! !###==================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: IPATTERN !## 0=solid,1=line,2=dots ! INTEGER,INTENT(IN) :: ICLR,IWIDTH,ITYPE ! REAL,INTENT(IN) :: XMIN,XMAX,YMAX ! REAL,INTENT(INOUT) :: YMIN ! REAL,INTENT(IN),OPTIONAL :: XT ! TYPE(LEGENDOBJ),INTENT(INOUT),OPTIONAL :: LEG ! REAL :: DX,DY,Y ! INTEGER :: I ! ! !## solid ! IF(IPATTERN.EQ.0)THEN ! ! CALL IGRCOLOURN(ICLR) ! CALL IGRFILLPATTERN(SOLID) ! CALL IGRRECTANGLE(XMIN,YMIN,XMAX,YMAX) ! ! !## lines ! ELSEIF(IPATTERN.EQ.1)THEN ! ! !## clear it (white) ! CALL IGRFILLPATTERN(SOLID) ! CALL IGRCOLOURN(WRGB(255,255,255)) ! CALL IGRRECTANGLE(XMIN,YMIN,XMAX,YMAX) ! ! CALL IGRCOLOURN(ICLR) ! CALL IGRFILLPATTERN(OUTLINE) ! ! CALL IGRLINETYPE(ITYPE) ! CALL IGRLINEWIDTH(IWIDTH) ! CALL IGRMOVETO(XMIN,YMIN) ! DX=(XMAX-XMIN)/3.0 ! DY=(YMAX-YMIN) ! ! CALL IGRLINETOREL(DX, DY) ! CALL IGRLINETOREL(DX,-DY) ! CALL IGRLINETOREL(DX, DY) ! ! !## dots ! ELSEIF(IPATTERN.EQ.2)THEN ! ! !## clear it (white) ! CALL IGRFILLPATTERN(SOLID) ! CALL IGRCOLOURN(WRGB(255,255,255)) ! CALL IGRRECTANGLE(XMIN,YMIN,XMAX,YMAX) ! ! DY=(XMAX-XMIN)/10.0 ! CALL IGRCOLOURN(ICLR) ! CALL IGRFILLPATTERN(SOLID) ! DX=(XMAX-XMIN)/4.0 ! DO I=1,3 ! CALL IGRCIRCLE(XMIN+(DX*REAL(I)),(YMAX+YMIN)/2.0,DY) ! END DO ! ! !## filled in (a) if present with legend (b) stripes ! ELSEIF(IPATTERN.EQ.3)THEN ! ! CALL IGRFILLPATTERN(SOLID) ! ! !## use a legend if present ! IF(PRESENT(LEG))THEN ! IF(LEG%NCLR.GT.MXCLASS)THEN; DY=(3.0*(YMAX-YMIN))/REAL(LEG%NCLR); ELSE; DY=YMAX-YMIN; ENDIF; Y=YMAX ! DO I=1,LEG%NCLR ! CALL IGRCOLOURN(LEG%RGB(I)); CALL IGRRECTANGLE(XMIN,Y-DY,XMAX,Y) ! IF(LEG%NCLR.LE.MXCLASS)THEN ! CALL IGRCOLOURN(WRGB(0,0,0)); CALL WGRTEXTSTRING(XT,Y-(DY/2.0),TRIM(LEG%LEGTXT(I))) ! ELSE ! CALL IGRCOLOURN(WRGB(0,0,0)) ! IF(I.EQ.1) CALL WGRTEXTSTRING(XT,YMAX-(0.5*(YMAX-YMIN)),TRIM(LEG%LEGTXT(I))) ! IF(I.EQ.LEG%NCLR)CALL WGRTEXTSTRING(XT,YMAX-(2.5*(YMAX-YMIN)),TRIM(LEG%LEGTXT(I))) ! ENDIF ! Y=Y-DY ! END DO ! YMIN=Y ! ELSE ! DX=(XMAX-XMIN)/10.0 ! DO I=1,9 ! IF(MOD(I,2).EQ.0)CALL IGRCOLOURN(ICLR) ! IF(MOD(I,2).NE.0)CALL IGRCOLOURN(WRGB(255,255,255)) ! CALL IGRRECTANGLE(XMIN+(DX*REAL(I-1)),YMIN,XMIN+(DX*REAL(I)),YMAX) ! END DO ! ENDIF ! ! ENDIF ! ! CALL IGRFILLPATTERN(OUTLINE) ! CALL IGRLINETYPE(SOLIDLINE) ! CALL IGRLINEWIDTH(1) ! CALL IGRCOLOURN(WRGB(0,0,0)) ! CALL IGRRECTANGLE(XMIN,YMIN,XMAX,YMAX) ! ! CALL IGRCOLOURN(ICLR) ! ! END SUBROUTINE ! ! !###==================================================================== ! SUBROUTINE UTL_GETRELEVANTDIR(DIRNAMES,NDIR) ! !###==================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: NDIR ! CHARACTER(LEN=*),INTENT(INOUT),DIMENSION(NDIR) :: DIRNAMES ! INTEGER :: I,II,JJ,J ! ! !## nothing to do ! IF(NDIR.LE.0)RETURN ! ! IF(NDIR.EQ.1)THEN ! I=INDEX(DIRNAMES(1),'\',.TRUE.) ! IF(I.NE.0)DIRNAMES(1)='..\'//DIRNAMES(1)(I+1:) ! RETURN ! ENDIF ! ! DO I=1,NDIR ! DIRNAMES(I)=UTL_CAP(DIRNAMES(I),'U') ! END DO ! II=0 ! JJ=0 ! DO WHILE(JJ.EQ.0) ! II=II+1 ! DO I=1,NDIR ! DO J=1,NDIR ! IF(DIRNAMES(I)(II:II).NE.DIRNAMES(J)(II:II).AND.JJ.EQ.0)JJ=II!EXIT! LOOPII ! END DO ! END DO ! ENDDO ! DO I=1,NDIR ! J=INDEX(DIRNAMES(I)(:II),'\',.TRUE.) ! IF(J.NE.0)DIRNAMES(I)='..\'//DIRNAMES(I)(J+1:) ! ENDDO ! ! END SUBROUTINE UTL_GETRELEVANTDIR ! ! !###==================================================================== ! SUBROUTINE UTL_GETDIRPART(IPART,DIR,DIRPART) ! !###==================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: IPART ! CHARACTER(LEN=*),INTENT(IN) :: DIR ! CHARACTER(LEN=*),INTENT(OUT) :: DIRPART ! INTEGER :: I,J,K ! ! DIRPART='' ! ! IF(IPART.EQ.0)THEN ! J=INDEX(DIR,':') ! IF(J.EQ.0)RETURN ! DIRPART=DIR(:J-1) ! ELSE ! K=1 ! DO I=1,IPART ! J=INDEX(DIR(K:),'\') ! !## nothing found for current ipart ! IF(J.EQ.0)RETURN ! K=J+1 ! ENDDO ! J=INDEX(DIR(K:),'\') ! IF(J.NE.0)DIRPART=DIR(K:J-1) ! ENDIF ! ! END SUBROUTINE UTL_GETDIRPART ! ! !###==================================================================== ! SUBROUTINE UTL_SETTEXTSIZE(CHW,CHH,DY) ! !###==================================================================== ! IMPLICIT NONE ! REAL,INTENT(IN) :: DY ! REAL,INTENT(OUT) :: CHW,CHH ! REAL :: IWD,IHD,X1,X2,Y1,Y2,RAT ! ! IWD=WINFODRAWABLE(DRAWABLEWIDTH) ! IHD=WINFODRAWABLE(DRAWABLEHEIGHT) ! X1 =INFOGRAPHICS(GRAPHICSAREAMINX) ! X2 =INFOGRAPHICS(GRAPHICSAREAMAXX) ! Y1 =INFOGRAPHICS(GRAPHICSAREAMINY) ! Y2 =INFOGRAPHICS(GRAPHICSAREAMAXY) ! ! CHH=DY ! CHW=DY/(0.03333/0.01333) ! ! RAT=IWD/IHD ! CHW=CHW/RAT ! ! RAT=(X2-X1)/(Y2-Y1) ! CHW=CHW/RAT ! ! END SUBROUTINE UTL_SETTEXTSIZE ! ! !###====================================================================== ! SUBROUTINE UTL_IMODFILLMENU(ID,DIRNAME,WC,F,N,IMENUTYPE,ISTORE,SETNAME) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(OUT) :: N ! INTEGER,INTENT(IN) :: ID,IMENUTYPE,ISTORE ! CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: SETNAME ! CHARACTER(LEN=*),INTENT(IN) :: DIRNAME,WC,F ! INTEGER :: I ! ! CALL UTL_IMODFILLMENU_DEAL() ! ! N=0 ! ! IF(LEN_TRIM(DIRNAME).EQ.0)THEN ! IF(ID.NE.0)CALL WDIALOGCLEARFIELD(ID) ! RETURN ! ENDIF ! ! IF(.NOT.IOSDIREXISTS(DIRNAME))THEN ! IF(ID.NE.0)CALL WDIALOGCLEARFIELD(ID) ! RETURN ! ENDIF ! ! CALL IOSDIRENTRYTYPE(F) ! CALL IOSDIRCOUNT(DIRNAME,WC,N) ! ! IF(N.EQ.0)THEN ! IF(ID.NE.0)THEN ! CALL WDIALOGCLEARFIELD(ID) ! CALL WDIALOGFIELDSTATE(ID,2) ! ENDIF ! ELSE ! ALLOCATE(LISTNAME(N)) ! CALL UTL_DIRINFO(DIRNAME,WC,LISTNAME,N,F) ! DO I=1,N; LISTNAME(I)=UTL_CAP(LISTNAME(I),'U'); END DO ! IF(N.GT.0.AND.ID.NE.0)THEN ! CALL WDIALOGFIELDSTATE(ID,1) ! IF(IMENUTYPE.EQ.0)THEN ! IF(PRESENT(SETNAME))THEN ! DO I=1,N; IF(UTL_CAP(LISTNAME(I),'U').EQ.UTL_CAP(SETNAME,'U'))EXIT; ENDDO ! IF(I.LE.N)THEN ! CALL WDIALOGPUTMENU(ID,LISTNAME,N,I) ! ELSE ! CALL WDIALOGPUTMENU(ID,LISTNAME,N,1) ! ENDIF ! ELSE ! CALL WDIALOGPUTMENU(ID,LISTNAME,N,1) ! ENDIF ! ELSEIF(IMENUTYPE.EQ.1)THEN ! ALLOCATE(ILIST(N)) ! ILIST=0 ! CALL WDIALOGPUTMENU(ID,LISTNAME,N,ILIST) ! ENDIF ! ELSE ! IF(ID.NE.0)THEN ! CALL WDIALOGCLEARFIELD(ID) ! CALL WDIALOGFIELDSTATE(ID,2) ! ENDIF ! ENDIF ! ENDIF ! ! IF(ISTORE.EQ.0)CALL UTL_IMODFILLMENU_DEAL() ! ! END SUBROUTINE UTL_IMODFILLMENU ! ! !###==================================================================== ! SUBROUTINE UTL_IMODFILLMENU_DEAL() ! !###==================================================================== ! IMPLICIT NONE ! ! IF(ALLOCATED(ILIST))DEALLOCATE(ILIST) ! IF(ALLOCATED(LISTNAME))DEALLOCATE(LISTNAME) ! ! END SUBROUTINE UTL_IMODFILLMENU_DEAL ! ! !###==================================================================== ! INTEGER FUNCTION GETITOPIC(CKEYWORD) ! !###==================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: CKEYWORD ! INTEGER :: I ! ! GETITOPIC=0 ! DO I=1,MXTP ! IF(TRIM(TP(I)%ACRNM).EQ.TRIM(CKEYWORD))GETITOPIC=I ! ENDDO ! ! END FUNCTION GETITOPIC ! ! !###====================================================================== ! SUBROUTINE UTL_PLOTLOCATIONIDF(IDF,IROW,ICOL) ! !###====================================================================== ! IMPLICIT NONE ! TYPE(IDFOBJ),INTENT(IN) :: IDF ! INTEGER,INTENT(IN) :: IROW,ICOL ! REAL :: X1,X2,Y1,Y2 ! ! IF(IROW.EQ.0.OR.ICOL.EQ.0)RETURN ! ! CALL IGRPLOTMODE(MODEXOR); CALL IGRFILLPATTERN(OUTLINE); CALL IGRLINEWIDTH(2) ! CALL IDFPLOT1BITMAP() ! ! IF(IDF%IEQ.EQ.0)THEN ! X1=IDF%XMIN+(ICOL-1)*IDF%DX; X2=IDF%XMIN+ ICOL *IDF%DX ! Y1=IDF%YMAX-(IROW-1)*IDF%DY; Y2=IDF%YMAX- IROW *IDF%DY ! ELSEIF(IDF%IEQ.EQ.1)THEN ! X1=IDF%SX(ICOL-1); Y1=IDF%SY(IROW-1) ! X2=IDF%SX(ICOL); Y2=IDF%SY(IROW) ! ENDIF ! ! !## selected cell ! CALL IGRRECTANGLE(X1,Y1,X2,Y2) ! ! CALL IGRLINEWIDTH(1) ! !! CALL IGRLINETYPE(DASHED) !! !## plot lines !! X=(X1+X2)/2.0; Y=(Y1+Y2)/2.0 !! CALL IGRJOIN(MPW%XMIN,Y,X1,Y); CALL IGRJOIN(X2,Y,MPW%XMAX,Y) !! CALL IGRJOIN(X,Y2,X,MPW%YMIN); CALL IGRJOIN(X,Y1,X,MPW%YMAX) ! ! CALL IGRLINETYPE(SOLIDLINE); CALL IDFPLOT2BITMAP() ! ! END SUBROUTINE UTL_PLOTLOCATIONIDF ! ! !###====================================================================== ! SUBROUTINE UTL_HIDESHOWDIALOG(ID,ISHOW) ! !###====================================================================== ! INTEGER,INTENT(IN) :: ID,ISHOW ! INTEGER :: IX,IY,I ! ! I=WINFOERROR(1) ! CALL WDIALOGSELECT(ID) ! I=WINFOERROR(1) ! IF(ISHOW.EQ.0)THEN ! CALL WDIALOGHIDE() ! ELSE ! IX=WINFODIALOG(DIALOGXPOS) ! IY=WINFODIALOG(DIALOGYPOS) ! CALL WDIALOGSHOW(IX,IY,0,ISHOW) ! ENDIF ! ! END SUBROUTINE UTL_HIDESHOWDIALOG ! ! !###====================================================================== ! SUBROUTINE UTL_IDFGETLAYERS(IDFNAME,N,ILAY,LDIM) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: N,LDIM ! CHARACTER(LEN=*),DIMENSION(N) :: IDFNAME ! INTEGER :: I,J,K,IL,IOS ! INTEGER,DIMENSION(LDIM) :: ILAY ! ! ILAY=0 ! DO I=1,N ! J=INDEXNOCASE(IDFNAME(I),'_L',.TRUE.) ! IF(J.NE.0)THEN ! K=INDEXNOCASE(IDFNAME(I),'.IDF',.TRUE.) ! IF(K.NE.0)THEN ! J=J+2 ! K=K-1 ! READ(IDFNAME(I)(J:K),*,IOSTAT=IOS) IL ! IF(IOS.EQ.0.AND.IL.GT.0)ILAY(IL)=1 ! ENDIF ! ENDIF ! END DO ! ! END SUBROUTINE UTL_IDFGETLAYERS ! !###====================================================================== SUBROUTINE UTL_IDFGETDATES(IDFNAME,N,M,O,MINDATE,MAXDATE) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: N INTEGER,INTENT(OUT) :: MINDATE,MAXDATE,M,O CHARACTER(LEN=*),DIMENSION(N) :: IDFNAME INTEGER :: I,IDATE MINDATE=21000101 MAXDATE=19000101 M =0 O =0 DO I=1,N IDATE=UTL_IDFGETDATE(IDFNAME(I)) IF(IDATE.NE.0)THEN O=O+1 MINDATE=MIN(MINDATE,IDATE) MAXDATE=MAX(MAXDATE,IDATE) ELSE IF(INDEX(UTL_CAP(IDFNAME(I),'U'),'_STEADY-STATE_').NE.0)M=M+1 ENDIF END DO END SUBROUTINE UTL_IDFGETDATES !###====================================================================== INTEGER FUNCTION UTL_IDFGETDATE(IDFNAME,DAYFRACTION,IYR,IMH,IDY,IHR,IMT,ISC) !###====================================================================== IMPLICIT NONE CHARACTER(LEN=*),INTENT(IN) :: IDFNAME REAL,INTENT(OUT),OPTIONAL :: DAYFRACTION INTEGER,INTENT(OUT),OPTIONAL :: IDY,IMH,IYR,IHR,IMT,ISC INTEGER :: IOS INTEGER :: I,II,J,N,YR,MT,DY,HR,MN,SC INTEGER,DIMENSION(2) :: NI DATA NI/14,8/ !## initially no data UTL_IDFGETDATE=0 !## try to find 16 numbers after eachother ... !## try to find 8 numbers after eachother ... DO II=1,2 N=0 !## start after last "\"-symbol DO I=INDEX(IDFNAME,'\',.TRUE.)+1,LEN_TRIM(IDFNAME) !## part of a number SELECT CASE (ICHAR(IDFNAME(I:I))) CASE (48:57) !## count numbers N=N+1 !## stop if 8/14 IF(N.EQ.NI(II))EXIT !## mark first position IF(N.EQ.1)J=I CASE DEFAULT N=0 END SELECT END DO IF(N.EQ.NI(II))EXIT !## nothing found IF(II.EQ.2.AND.N.LT.NI(II))RETURN ENDDO !## default IF(PRESENT(DAYFRACTION))DAYFRACTION=-1.0 IF(II.EQ.1)THEN READ(IDFNAME(J:) ,'(I8) ',IOSTAT=IOS) UTL_IDFGETDATE IF(PRESENT(DAYFRACTION))THEN READ(IDFNAME(J+8:),'(3I2)',IOSTAT=IOS) HR,MN,SC DAYFRACTION=REAL(HR*3600+MN*60+SC)/86400.0 DAYFRACTION=MAX(0.0,MIN(DAYFRACTION,1.0)) ENDIF READ(IDFNAME(J:) ,'(I4,5I2)',IOSTAT=IOS) YR,MT,DY,HR,MN,SC ELSE READ(IDFNAME(J:) ,'(I8)',IOSTAT=IOS) UTL_IDFGETDATE READ(IDFNAME(J:) ,'(I4,2I2)',IOSTAT=IOS) YR,MT,DY HR=0; MN=0; SC=0 ENDIF IF(PRESENT(IYR))IYR=YR IF(PRESENT(IMH))IMH=MT IF(PRESENT(IDY))IDY=DY IF(PRESENT(IHR))IHR=HR IF(PRESENT(IMT))IMT=MN IF(PRESENT(ISC))ISC=SC IF(IOS.NE.0)UTL_IDFGETDATE=0 END FUNCTION UTL_IDFGETDATE ! !###====================================================================== ! SUBROUTINE UTL_FILLDATES(IDY,IDM,IDD,JULD) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(OUT),OPTIONAL :: JULD ! INTEGER,INTENT(IN) :: IDM,IDY,IDD ! INTEGER :: M,Y,D,NDAY ! ! CALL WDIALOGGETMENU(IDM,M) ! CALL WDIALOGGETINTEGER(IDY,Y) ! NDAY=WDATEDAYSINMONTH(Y,M) ! CALL WDIALOGGETINTEGER(IDD,D) ! CALL WDIALOGRANGEINTEGER(IDD,1,NDAY) ! IF(D.GT.NDAY)CALL WDIALOGPUTINTEGER(IDD,NDAY) ! D=MIN(D,NDAY) ! ! IF(.NOT.PRESENT(JULD))RETURN ! JULD=JD(Y,M,D) ! ! END SUBROUTINE UTL_FILLDATES ! ! !###====================================================================== ! SUBROUTINE UTL_FILLDATESDIALOG(ID,IDD,IDM,IDY,JD) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: ID,IDD,IDM,IDY,JD ! INTEGER :: I,J,K ! ! CALL WDIALOGSELECT(ID) ! !## put begin date ! CALL IDATETOGDATE(JD,I,J,K) !## ID,IY,IM,ID ! CALL WDIALOGPUTINTEGER(IDD,K) ! CALL WDIALOGPUTINTEGER(IDY,I) ! CALL WDIALOGPUTOPTION(IDM,J) ! ! END SUBROUTINE UTL_FILLDATESDIALOG ! !###====================================================================== FUNCTION ITOS(I) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: I CHARACTER(LEN=10) :: TXT,ITOS ! call IntegerToString(I,ITOS,'(I10)') WRITE(TXT,'(I10)') I ITOS=ADJUSTL(TXT) END FUNCTION ITOS !###====================================================================== FUNCTION RTOS(X,F,NDEC) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: NDEC REAL,INTENT(IN) :: X CHARACTER(LEN=1),INTENT(IN) :: F CHARACTER(LEN=15) :: TXT,FRM,RTOS INTEGER :: IOS IF(F.EQ.'*')THEN WRITE(TXT,*,IOSTAT=IOS) X ELSE WRITE(FRM,'(2A1,I2.2,A1,I2.2,A1)') '(',F,LEN(RTOS),'.',NDEC,')' WRITE(TXT,FRM,IOSTAT=IOS) X ENDIF IF(IOS.NE.0)TXT='error' RTOS=ADJUSTL(TXT) END FUNCTION RTOS !###====================================================================== INTEGER FUNCTION UTL_GETUNIT() !###====================================================================== IMPLICIT NONE LOGICAL :: LEX UTL_GETUNIT=19 DO UTL_GETUNIT=UTL_GETUNIT+1 !20,5000 INQUIRE(UNIT=UTL_GETUNIT,OPENED=LEX) IF(.NOT.LEX)EXIT IF(UTL_GETUNIT.GT.1000000)EXIT END DO IF(LEX)THEN !CALL WMESSAGEBOX(OKONLY,COMMONOK,EXCLAMATIONICON,'iMOD cannot open more than 1000000 files simultaneously!','ERROR') UTL_GETUNIT=0 ENDIF END FUNCTION UTL_GETUNIT ! !###====================================================================== ! SUBROUTINE UTL_CLOSEUNITS() ! !###====================================================================== ! IMPLICIT NONE ! INTEGER :: I ! LOGICAL :: LEX ! ! DO I=20,5000 ! INQUIRE(UNIT=I,OPENED=LEX) ! IF(LEX)CLOSE(I) ! END DO ! ! END SUBROUTINE UTL_CLOSEUNITS ! ! !###====================================================================== ! SUBROUTINE INFOUNITS() ! !###====================================================================== ! IMPLICIT NONE ! INTEGER :: I ! LOGICAL :: LEX ! CHARACTER(LEN=256) :: FNAME ! ! DO I=20,5000 ! INQUIRE(UNIT=I,OPENED=LEX) ! IF(LEX)THEN ! INQUIRE(UNIT=I,NAME=FNAME) ! WRITE(*,*) 'UNIT ',I,' '//TRIM(FNAME) ! ENDIF ! END DO ! ! END SUBROUTINE INFOUNITS ! !!###====================================================================== !SUBROUTINE UTL_CREATEDIR(DIRNAME) !!###====================================================================== !IMPLICIT NONE !CHARACTER(LEN=*),INTENT(IN) :: DIRNAME !INTEGER :: I,J ! !!## create/check entire directory-structure !I=INDEX(DIRNAME,'\')+1 !DO ! J=INDEX(DIRNAME(I:),'\') ! IF(J.EQ.0)EXIT ! J=J+I ! IF(.NOT.IOSDIREXISTS(DIRNAME(:J-2)))CALL IOSDIRMAKE(DIRNAME(:J-2)) ! I=J !END DO ! !!## only create folder, is there is a subfolder left !IF(INDEX(DIRNAME,'\').NE.0)THEN ! !## last remaining of string (peter) ! IF(.NOT.IOSDIREXISTS(TRIM(DIRNAME)))CALL IOSDIRMAKE(TRIM(DIRNAME)) !ENDIF ! !END SUBROUTINE UTL_CREATEDIR ! !###====================================================================== ! SUBROUTINE UTL_DEL1TREE(DIR) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: DIR ! INTEGER :: I,IERROR ! CHARACTER(LEN=256) :: CURDIR,DELDIR ! ! CALL IOSDIRNAME(CURDIR) ! I=INDEXNOCASE(DIR,'\',.TRUE.) ! !## clear existing error? ! IERROR=INFOERROR(1) ! CALL IOSDIRCHANGE(DIR(:I-1)) ! IERROR=INFOERROR(1) ! !## dirchange error? ! IF(IERROR.NE.0)THEN ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'Could not find directory:'//CHAR(13)// & ! TRIM(DIR(:I-1)),'iMOD: Error') ! RETURN ! ENDIF ! !## make sure to delete directory ! CALL WMESSAGEBOX(YESNO,QUESTIONICON,COMMONNO,'Are you sure to delete'//CHAR(13)//TRIM(DIR),'Question?') ! IF(WINFODIALOG(4).NE.1)RETURN ! !## delete entire directory ! DELDIR=DIR(I+1:) ! CALL UTL_DEL2TREE(DELDIR) ! CALL IOSDIRCHANGE(CURDIR) ! ! END SUBROUTINE UTL_DEL1TREE ! ! !###====================================================================== ! RECURSIVE SUBROUTINE UTL_DEL2TREE(DIR) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=256),INTENT(IN) :: DIR ! INTEGER,PARAMETER :: MXDIR=50 ! INTEGER :: I,NDIR,IERROR ! CHARACTER(LEN=256),DIMENSION(MXDIR) :: RESDIR ! ! CALL WINDOWOUTSTATUSBAR(4,'Delete directory '//TRIM(DIR)//'...') ! ! !#clear existing error? ! IERROR=INFOERROR(1) ! !##go one level down ! CALL IOSDIRCHANGE(DIR) ! IERROR=INFOERROR(1) ! !#dirchange error? ! IF(IERROR.NE.0)THEN ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'Could not change towards directory:'//CHAR(13)// & ! TRIM(DIR),'iMOD: Error') ! RETURN ! ENDIF ! ! !##how many subdirectories exist? ! NDIR=MXDIR ! CALL IOSDIRENTRYTYPE('D') ! CALL IOSDIRINFO(' ',' ',RESDIR,NDIR) ! IF(NDIR.GT.MXDIR)THEN ! CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'MXDIR overwritten in del2tree()','ERROR') ! RETURN ! ENDIF ! DO I=3,NDIR ! CALL UTL_DEL2TREE(RESDIR(I)) ! END DO ! !##delete all files in directory ! CALL IOSDELETEFILE('*.*') ! !##return one level up ! CALL IOSDIRCHANGE('..') ! CALL IOSDIRDELETE(DIR) ! ! END SUBROUTINE UTL_DEL2TREE ! ! !###====================================================================== ! SUBROUTINE UTL_WAITMESSAGE(IRAT,IRAT1,I1,I2,WAITTXT,IBOX) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: I1,I2 ! INTEGER,INTENT(IN OUT) :: IRAT,IRAT1 ! CHARACTER(LEN=*),INTENT(IN) :: WAITTXT ! INTEGER,OPTIONAL,INTENT(IN) :: IBOX ! INTEGER :: JBOX ! ! JBOX=4; IF(PRESENT(IBOX))JBOX=IBOX ! ! IRAT=(I1*100)/I2 ! IF(IRAT.NE.IRAT1)THEN ! CALL WINDOWOUTSTATUSBAR(JBOX,TRIM(WAITTXT)//' '//TRIM(ITOS(IRAT))//' %') ! IRAT1=IRAT ! ENDIF ! ! END SUBROUTINE UTL_WAITMESSAGE ! !!###====================================================================== !SUBROUTINE UTL_MESSAGEHANDLE(ONOFF) !!###====================================================================== !IMPLICIT NONE !INTEGER,INTENT(IN) :: ONOFF !INTEGER :: I ! !IF(ONOFF.EQ.0)CALL WCURSORSHAPE(CURHOURGLASS) !IF(ONOFF.EQ.1)CALL WCURSORSHAPE(CURARROW) !DO I=1,MXMESSAGE ! IF(IMESSAGE(I).EQ.1)THEN ! IF(WINFOMESSAGE(I).NE.ONOFF)CALL WMESSAGEENABLE(I,ONOFF) ! ENDIF !END DO !IF(ONOFF.EQ.0)RETURN ! !END SUBROUTINE UTL_MESSAGEHANDLE ! !###====================================================================== ! SUBROUTINE UTL_MESSAGEHANDLE3D(ONOFF) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: ONOFF ! ! !## default mousemove off ! IMESSAGE(MOUSEMOVE)=ONOFF ! ! END SUBROUTINE UTL_MESSAGEHANDLE3D ! ! !###====================================================================== ! INTEGER FUNCTION UTL_GETCURRENTDATE() ! !###====================================================================== ! IMPLICIT NONE ! INTEGER :: IY,IM,ID ! ! CALL IOSDATE(IY,IM,ID) ! UTL_GETCURRENTDATE=IY*10000+IM*100+ID ! ! END FUNCTION UTL_GETCURRENTDATE ! ! !###====================================================================== ! CHARACTER(LEN=8) FUNCTION UTL_GETCURRENTTIME() ! !###====================================================================== ! IMPLICIT NONE ! INTEGER :: IH,IM,IS ! CHARACTER(LEN=8) :: CTIME ! ! CALL IOSTIME(IH,IM,IS) ! WRITE(CTIME,'(3(I2.2,A1))') IH,':',IM,':',IS ! ! UTL_GETCURRENTTIME=TRIM(CTIME) ! ! END FUNCTION UTL_GETCURRENTTIME ! ! !###====================================================================== ! FUNCTION JDATETOGDATE(I,DTYPE) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: I ! INTEGER,INTENT(IN),OPTIONAL :: DTYPE ! CHARACTER(LEN=10) :: JDATETOGDATE ! INTEGER :: IY,IM,ID ! ! CALL UTL_GDATE(I,IY,IM,ID) ! IF(PRESENT(DTYPE))THEN ! SELECT CASE (DTYPE) ! CASE (0) ! JDATETOGDATE=TRIM(ITOS(ID))//'-'//TRIM(ITOS(IM))//'-'//TRIM(ITOS(IY)) ! CASE (1) ! JDATETOGDATE=TRIM(ITOS(ID))//'/'//TRIM(ITOS(IM))//'/'//TRIM(ITOS(IY)) ! CASE (2) ! WRITE(JDATETOGDATE,'(I4.4,2I2.2)') IY,IM,ID ! END SELECT ! ELSE ! JDATETOGDATE=TRIM(ITOS(ID))//'/'//TRIM(ITOS(IM))//'/'//TRIM(ITOS(IY)) ! ENDIF ! ! END FUNCTION JDATETOGDATE ! ! !###====================================================================== ! CHARACTER(LEN=20) FUNCTION JDATETOFDATE(X,JOFFSET,DTYPE) ! !###====================================================================== ! IMPLICIT NONE !! CHARACTER(LEN=20) :: JDATETOFDATE ! INTEGER,INTENT(IN) :: JOFFSET ! INTEGER,INTENT(IN),OPTIONAL :: DTYPE ! REAL,INTENT(IN) :: X ! CHARACTER(LEN=8) :: CTIME ! REAL :: FTIME ! INTEGER :: DDTYPE ! ! IF(PRESENT(DTYPE))THEN ! DDTYPE=DTYPE ! ELSE ! DDTYPE=0 ! ENDIF ! ! JDATETOFDATE=JDATETOGDATE(INT(X)+JOFFSET,DTYPE) ! FTIME=X-FLOOR(X) ! CALL FTIMETOCTIME(FTIME,CTIME,DDTYPE) ! IF(CTIME.NE.'00:00:00')THEN ! IF(DDTYPE.EQ.2)THEN ! JDATETOFDATE=TRIM(JDATETOFDATE)//TRIM(CTIME) ! ELSE ! JDATETOFDATE=TRIM(JDATETOFDATE)//' '//TRIM(CTIME) ! ENDIF ! ENDIF ! ! END FUNCTION JDATETOFDATE ! ! !###====================================================================== ! INTEGER FUNCTION GDATETOJDATE(CDATE) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(INOUT) :: CDATE ! INTEGER :: IY,IM,ID,I,J,MD ! INTEGER,DIMENSION(3) :: IOS ! ! IOS=1 ! ! I=INDEX(CDATE,'/',.FALSE.) ! IF(I.GT.0)THEN ! READ(CDATE(1:I-1),*,IOSTAT=IOS(1)) ID ! J=INDEX(CDATE,'/',.TRUE.) ! IF(J.GT.0)THEN ! READ(CDATE(J+1:),*,IOSTAT=IOS(3)) IY ! IF(J-I.GT.0)READ(CDATE(I+1:J-1),*,IOSTAT=IOS(2)) IM ! ENDIF ! ENDIF ! ! !## initialize default value ! GDATETOJDATE=0 ! ! IM=MAX(1,MIN(12,IM)) ! MD=WDATEDAYSINMONTH(IY,IM) ! ID=MAX(1,MIN(MD,ID)) ! ! !## error reading dates ! IF(SUM(IOS).NE.0)RETURN ! ! J =JD(IY,IM,ID) ! CDATE =JDATETOGDATE(J) ! GDATETOJDATE=J ! ! END FUNCTION GDATETOJDATE ! !###==================================================================== INTEGER FUNCTION UTL_IDATETOJDATE(IDATE) !###==================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IDATE INTEGER :: IY,IM,ID CALL IDATETOGDATE(IDATE,IY,IM,ID) UTL_IDATETOJDATE=JD(IY,IM,ID) END FUNCTION UTL_IDATETOJDATE ! !###==================================================================== ! INTEGER FUNCTION UTL_JDATETOIDATE(JDATE) ! !###==================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: JDATE ! INTEGER :: IY,IM,ID ! ! CALL UTL_GDATE(JDATE,IY,IM,ID) ! UTL_JDATETOIDATE=IY*10000+IM*100+ID ! ! END FUNCTION UTL_JDATETOIDATE ! !###==================================================================== SUBROUTINE IDATETOGDATE(IDATE,IY,IM,ID) !###==================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IDATE INTEGER,INTENT(OUT) :: IY,IM,ID IY = IDATE / 10000 IM = MOD( IDATE, 10000 ) / 100 ID = MOD( IDATE, 100 ) END SUBROUTINE IDATETOGDATE ! !###==================================================================== ! SUBROUTINE FTIMETOITIME(FTIME,IH,IM,IS) ! !###==================================================================== ! IMPLICIT NONE ! REAL,INTENT(IN) :: FTIME ! INTEGER,INTENT(OUT) :: IH,IM,IS ! INTEGER :: ITIME ! ! ITIME=FTIME*SDAY ! CALL ITIMETOGTIME(ITIME,IH,IM,IS) ! ! END SUBROUTINE FTIMETOITIME ! ! !###==================================================================== ! SUBROUTINE FTIMETOCTIME(FTIME,CTIME,DTYPE) ! !###==================================================================== ! IMPLICIT NONE ! REAL,INTENT(IN) :: FTIME ! CHARACTER(LEN=*),INTENT(OUT) :: CTIME ! INTEGER,INTENT(IN),OPTIONAL :: DTYPE ! INTEGER :: IH,IM,IS ! INTEGER :: ITIME ! ! ITIME=FTIME*SDAY ! CALL ITIMETOGTIME(ITIME,IH,IM,IS) ! IF(PRESENT(DTYPE))THEN ! SELECT CASE (DTYPE) ! CASE (0) ! WRITE(CTIME,'(3(I2.2,A1))') IH,':',IM,':',IS ! CASE (1) ! WRITE(CTIME,'(3(I2.2,A1))') IH,'-',IM,'-',IS ! CASE (2) ! WRITE(CTIME,'(3I2.2)') IH,IM,IS ! END SELECT ! ELSE ! WRITE(CTIME,'(3(I2.2,A1))') IH,':',IM,':',IS ! ENDIF ! ! END SUBROUTINE FTIMETOCTIME ! ! !###==================================================================== ! REAL FUNCTION ITIMETOFTIME(ITIME) ! !###==================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: ITIME !## hhmmss notation ! INTEGER :: IH,IM,IS ! ! IH = ITIME / 10000 ! IM = MOD( ITIME, 10000 ) / 100 ! IS = MOD( ITIME, 100 ) ! ! ITIMETOFTIME=(REAL(IH)*3600.0+REAL(IM)*60.0+REAL(IS))/SDAY ! ! END FUNCTION ITIMETOFTIME ! ! !###==================================================================== ! SUBROUTINE ITIMETOHMS(ITIME,IH,IM,IS) ! !###==================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: ITIME !## hhmmss notation ! INTEGER,INTENT(OUT) :: IH,IM,IS ! ! IH = ITIME / 10000 ! IM = MOD( ITIME, 10000 ) / 100 ! IS = MOD( ITIME, 100 ) ! ! END SUBROUTINE ITIMETOHMS ! ! !###==================================================================== ! INTEGER FUNCTION HMSTOITIME(IH,IM,IS) ! !###==================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: IH,IM,IS ! ! HMSTOITIME=IH*10000+IM*100+IS ! ! END FUNCTION HMSTOITIME ! ! !###==================================================================== ! SUBROUTINE ITIMETOGDATE(IDATE,IYR,IMH,IDY,IHR,IMT,ISC) ! !###==================================================================== ! IMPLICIT NONE ! INTEGER(KIND=8),INTENT(IN) :: IDATE ! INTEGER,INTENT(OUT) :: IYR,IMH,IDY,IHR,IMT,ISC ! ! IYR = IDATE / 10000000000 ! IMH = MOD( IDATE, 10000000000 ) / 100000000 ! IDY = MOD( IDATE, 100000000 ) / 1000000 ! IHR = MOD( IDATE, 1000000 ) / 10000 ! IMT = MOD( IDATE, 10000 ) / 100 ! ISC = MOD( IDATE, 100 ) ! ! END SUBROUTINE ITIMETOGDATE ! ! !###==================================================================== ! REAL FUNCTION CTIMETOFTIME(CTIME) ! !###==================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*) :: CTIME ! INTEGER :: IH,IM,IS ! ! READ(CTIME,'(3(I2.0,1X))') IH,IM,IS ! CTIMETOFTIME=(REAL(IH)*3600.0+REAL(IM)*60.0+REAL(IS))/SDAY ! ! END FUNCTION CTIMETOFTIME ! ! !###==================================================================== ! SUBROUTINE DECDEGREES_TO_DMS(DEGREES,D,M,S) ! !###==================================================================== ! IMPLICIT NONE ! DOUBLE PRECISION,INTENT(IN) :: DEGREES ! REAL,INTENT(OUT) :: D,M,S ! REAL :: F ! ! D = INT(DEGREES) ! F = 60.0 * (DEGREES - D) ! M = INT(F) ! S = F - M ! ! END SUBROUTINE DECDEGREES_TO_DMS ! ! !###==================================================================== ! SUBROUTINE ITIMETOGTIME(ITIME,IH,IM,IS) ! !###==================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: ITIME !## time seconds ! INTEGER,INTENT(OUT) :: IH,IM,IS ! ! IH = ITIME / 3600 ! IM = MOD( ITIME, 3600 ) / 60 ! IS = MOD( ITIME, 60 ) ! ! END SUBROUTINE ITIMETOGTIME ! !###==================================================================== INTEGER FUNCTION JD(YEAR,MONTH,DAY) !###==================================================================== !Reference: Fliegel, H. F. & van Flandern, T. C. 1968, Communications of the ACM, 11, 657. IMPLICIT NONE INTEGER,INTENT(IN) :: YEAR,MONTH,DAY INTEGER :: I,J,K I =YEAR J =MONTH K =DAY JD=K-32075+1461*(I+4800+(J-14)/12)/4+367*(J-2-(J-14)/12*12) & /12-3*((I+4900+(J-14)/12)/100)/4 END FUNCTION JD ! !###==================================================================== ! SUBROUTINE UTL_GDATE(JD,YEAR,MONTH,DAY) ! !###==================================================================== ! !Reference: Fliegel, H. F. & van Flandern, T. C. 1968, Communications of the ACM, 11, 657. ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: JD ! INTEGER,INTENT(OUT) :: YEAR,MONTH,DAY ! INTEGER :: I,J,K,L,N ! ! L=JD+68569 ! N=4*L/146097 ! L=L-(146097*N+3)/4 ! I=4000*(L+1)/1461001 ! L=L-1461*I/4+31 ! J=80*L/2447 ! K=L-2447*J/80 ! L=J/11 ! J=J+2-12*L ! I=100*(N-49)+I+L ! ! YEAR =I ! MONTH=J ! DAY =K ! ! END SUBROUTINE UTL_GDATE ! ! !###==================================================================== ! FUNCTION UTL_SUBST(FNAME,SUB1,SUB2) ! !###==================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: SUB1,SUB2 ! CHARACTER(LEN=*),INTENT(IN) :: FNAME ! INTEGER :: I,J ! CHARACTER(LEN=256) :: UTL_SUBST ! ! UTL_SUBST=FNAME ! ! I=INDEX(FNAME,SUB1) ! IF(I.EQ.0)RETURN ! I=I-1 ! J=I+LEN_TRIM(SUB1)+1 ! ! UTL_SUBST=FNAME(:I)//TRIM(SUB2)//FNAME(J:) ! ! END FUNCTION UTL_SUBST ! ! !###==================================================== ! SUBROUTINE UTL_CHECKNAME(FNAME,EXT) ! !checks for existence of an extension EXT (for instance 'idf') ! !and replaces fname including the extension (EXT) if not found. ! !###==================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(INOUT) :: FNAME ! CHARACTER(LEN=*),INTENT(IN) :: EXT ! INTEGER :: I ! ! I=INDEXNOCASE(FNAME,'.',.TRUE.) ! IF(I.EQ.0)THEN ! FNAME=TRIM(FNAME)//'.'//TRIM(EXT) ! ELSE ! FNAME=FNAME(:I)//TRIM(EXT) ! ENDIF ! ! END SUBROUTINE UTL_CHECKNAME ! ! !###====================================================================== ! INTEGER FUNCTION INVERSECOLOUR(IRGB) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: IRGB ! INTEGER :: IR,IG,IB ! ! CALL WRGBSPLIT(IRGB,IR,IG,IB) ! INVERSECOLOUR=WRGB(255-IR,255-IG,255-IB) ! ! END FUNCTION INVERSECOLOUR ! ! !###====================================================================== ! SUBROUTINE UTL_FADEOUTCOLOUR(ICLR,FCT) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(INOUT) :: ICLR ! REAL,INTENT(IN) :: FCT ! INTEGER :: IR,IG,IB ! ! IF(FCT.GT.1.0.OR.FCT.LE.0.0)RETURN ! ! CALL WRGBSPLIT(ICLR,IR,IG,IB) ! IR =IR+((255-IR)*FCT) ! IG =IG+((255-IG)*FCT) ! IB =IB+((255-IB)*FCT) ! IR=MIN(255,MAX(0,IR)) ! IG=MIN(255,MAX(0,IG)) ! IB=MIN(255,MAX(0,IB)) ! !## faded colour becomes ! ICLR=WRGB(IR,IG,IB) ! ! END SUBROUTINE UTL_FADEOUTCOLOUR ! ! !###====================================================================== ! LOGICAL FUNCTION EQUALNAMES(NAME1,NAME2) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: NAME1,NAME2 ! LOGICAL :: CHF_LK ! ! EQUALNAMES=CHF_LK(NAME1,LEN(NAME1),NAME2,LEN(NAME2)) ! ! END FUNCTION EQUALNAMES ! !###====================================================================== FUNCTION UTL_CAP(STR,TXT) !###====================================================================== IMPLICIT NONE CHARACTER(LEN=*),INTENT(IN) :: TXT,STR INTEGER :: I,J,K,B1,B2 CHARACTER(LEN=256) :: UTL_CAP IF(TXT.EQ.'l'.OR.TXT.EQ.'L')THEN B1= 65 B2= 90 K = 32 ELSEIF(TXT.EQ.'u'.OR.TXT.EQ.'U')THEN B1= 97 B2= 122 K =-32 ENDIF UTL_CAP='' DO I=1,LEN_TRIM(STR) J=IACHAR(STR(I:I)) IF(J.GE.B1.AND.J.LE.B2)J=J+K UTL_CAP(I:I)=ACHAR(J) END DO END FUNCTION UTL_CAP ! !###====================================================================== ! FUNCTION UTL_CAP_BIG(STR,TXT) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: TXT,STR ! INTEGER :: I,J,K,B1,B2 ! CHARACTER(LEN=1052) :: UTL_CAP_BIG ! ! IF(TXT.EQ.'l'.OR.TXT.EQ.'L')THEN ! B1= 65 ! B2= 90 ! K = 32 ! ELSEIF(TXT.EQ.'u'.OR.TXT.EQ.'U')THEN ! B1= 97 ! B2= 122 ! K =-32 ! ENDIF ! ! UTL_CAP_BIG='' ! DO I=1,LEN_TRIM(STR) ! J=IACHAR(STR(I:I)) ! IF(J.GE.B1.AND.J.LE.B2)J=J+K ! UTL_CAP_BIG(I:I)=ACHAR(J) ! END DO ! ! END FUNCTION UTL_CAP_BIG ! ! !###====================================================================== ! SUBROUTINE UTL_DIRINFO(DIR,WC,LISTNAME,N,FT) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(INOUT) :: N ! CHARACTER(LEN=*),INTENT(IN) :: DIR,WC,FT ! CHARACTER(LEN=*),INTENT(OUT),DIMENSION(:) :: LISTNAME ! CHARACTER(LEN=512) :: LINE,BATFILE,TXTFILE ! INTEGER :: IU,I,J,IOS ! LOGICAL :: LEX ! ! BATFILE=TRIM(PREFVAL(1))//'\tmp\'//TRIM(OSD_GETENV('USERNAME'))//'_dir_imod.bat' ! TXTFILE=TRIM(PREFVAL(1))//'\tmp\'//TRIM(OSD_GETENV('USERNAME'))//'_dir_imod.txt' ! ! IU=UTL_GETUNIT(); CALL OSD_OPEN(IU,FILE=BATFILE,ACTION='WRITE',FORM='FORMATTED',IOSTAT=IOS) ! IF(IOS.NE.0)THEN ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD does not have priveleges to write CREATE: '//CHAR(13)//TRIM(BATFILE),'Error') ! IU=0; N=0; RETURN ! ENDIF ! ! INQUIRE(FILE=TXTFILE,EXIST=LEX) ! !## Successfully deleted ! IF(LEX)THEN ! I=WINFOERROR(1) ! CALL IOSDELETEFILE(TXTFILE) ! I=WINFOERROR(1) ! IF(I.EQ.ERROSCOMMAND)THEN ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD does not have priveleges to DELETE: '//CHAR(13)//TRIM(TXTFILE),'Error') ! CLOSE(IU); IU=0; N=0; RETURN ! ENDIF ! ENDIF ! ! IF(FT.EQ.'F'.OR.FT.EQ.'f') & ! LINE='dir /b /o "' //TRIM(DIR)//'\'//TRIM(WC)//'" > "'//TRIM(TXTFILE)//'"' ! IF(FT.EQ.'D'.OR.FT.EQ.'d') & ! LINE='dir /ad /b /o "'//TRIM(DIR)//'\'//TRIM(WC)//'" > "'//TRIM(TXTFILE)//'"' ! ! !## remove \\ ! DO ! I=INDEX(LINE,'\\') ! IF(I.EQ.0)EXIT ! LINE(I+1:256-1)=LINE(I+2:) ! ENDDO ! ! WRITE(IU,'(A)') TRIM(LINE) ! CLOSE(IU) ! !#if (defined(WINTERACTER8)) ! CALL IOSCOMMAND('"'//TRIM(BATFILE)//'"',PROCSILENT+PROCBLOCKED) !#endif !#if (defined(WINTERACTER9)) ! CALL IOSCOMMAND('"'//TRIM(BATFILE)//'"',PROCSILENT+PROCBLOCKED+PROCCMDPROC) !#endif ! ! IU=UTL_GETUNIT() ! CALL OSD_OPEN(IU,FILE=TXTFILE,ACTION='READ',FORM='FORMATTED') ! IF(IU.LE.0)THEN ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot OPEN: '//CHAR(13)//TRIM(TXTFILE),'Error') ! IU=0; N=0; RETURN ! ENDIF ! ! I=0 ! DO ! READ(IU,'(A256)',IOSTAT=IOS) LINE ! IF(IOS.NE.0)EXIT ! J=LEN_TRIM(LINE) ! IF(J.EQ.0)EXIT ! LINE(2:J+1)=LINE(1:J) ! LINE(1:1)='"' ! LINE(J+2:J+2)='"' ! I=I+1 ! READ(LINE,*,IOSTAT=IOS) LISTNAME(I) ! IF(IOS.NE.0)EXIT ! !## no more space in allocated array ! IF(I.EQ.SIZE(LISTNAME))EXIT ! END DO ! !## delete result txt file ! CLOSE(IU,STATUS='DELETE') ! N=I ! ! END SUBROUTINE UTL_DIRINFO ! ! !###====================================================================== ! LOGICAL FUNCTION UTL_DIRINFO_POINTER(DIR,WC,LISTNAME,FT) ! !###====================================================================== ! IMPLICIT NONE ! CHARACTER(LEN=*),INTENT(IN) :: DIR,WC,FT ! CHARACTER(LEN=*),INTENT(OUT),DIMENSION(:),POINTER :: LISTNAME ! CHARACTER(LEN=256),DIMENSION(:),POINTER :: C_LISTNAME ! CHARACTER(LEN=512) :: LINE,BATFILE,TXTFILE ! INTEGER :: IU,I,J,N,IOS ! LOGICAL :: LEX ! ! UTL_DIRINFO_POINTER=.FALSE. ! ! IF(LEN(C_LISTNAME).LT.LEN(LISTNAME))CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'c_listname() "'//TRIM(TXTFILE)//'"' ! IF(FT.EQ.'D'.OR.FT.EQ.'d') & ! LINE='dir /ad /b /o "'//TRIM(DIR)//'\'//TRIM(WC)//'" > "'//TRIM(TXTFILE)//'"' ! ! !## remove \\ ! DO ! I=INDEX(LINE,'\\') ! IF(I.EQ.0)EXIT ! LINE(I+1:256-1)=LINE(I+2:) ! ENDDO ! ! WRITE(IU,'(A)') TRIM(LINE) ! CLOSE(IU) ! !#if (defined(WINTERACTER8)) ! CALL IOSCOMMAND('"'//TRIM(BATFILE)//'"',PROCSILENT+PROCBLOCKED) !#endif !#if (defined(WINTERACTER9)) ! CALL IOSCOMMAND('"'//TRIM(BATFILE)//'"',PROCSILENT+PROCBLOCKED+PROCCMDPROC) !#endif ! ! IU=UTL_GETUNIT() ! CALL OSD_OPEN(IU,FILE=TXTFILE,ACTION='READ',FORM='FORMATTED') ! IF(IU.LE.0)THEN ! CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot OPEN: '//CHAR(13)//TRIM(TXTFILE),'Error') ! IU=0; N=0; RETURN ! ENDIF ! ! ALLOCATE(C_LISTNAME(50)) ! ! I=0 ! DO ! READ(IU,'(A256)',IOSTAT=IOS) LINE ! IF(IOS.NE.0)EXIT ! J=LEN_TRIM(LINE) ! IF(J.EQ.0)EXIT ! LINE(2:J+1)=LINE(1:J) ! LINE(1:1)='"' ! LINE(J+2:J+2)='"' ! I=I+1 ! IF(I.GT.SIZE(C_LISTNAME))THEN ! N=SIZE(C_LISTNAME) ! ALLOCATE(LISTNAME(N)); LISTNAME(1:N)=C_LISTNAME(1:N) ! DEALLOCATE(C_LISTNAME); ALLOCATE(C_LISTNAME(N*2)) ! C_LISTNAME(1:N)=LISTNAME(1:N); DEALLOCATE(LISTNAME) ! ENDIF ! READ(LINE,*,IOSTAT=IOS) C_LISTNAME(I) ! IF(IOS.NE.0)EXIT ! END DO ! ! CLOSE(IU) ! ! N=I ! ! ALLOCATE(LISTNAME(N)) ! LISTNAME(1:N)=C_LISTNAME(1:N) ! DEALLOCATE(C_LISTNAME) ! ! UTL_DIRINFO_POINTER=.TRUE. ! ! END FUNCTION UTL_DIRINFO_POINTER ! !###====================================================================== SUBROUTINE UTL_IDFSNAPTOGRID(MINX,MAXX,MINY,MAXY,CS,NCOL,NROW) !###====================================================================== REAL,INTENT(INOUT) :: MINX,MAXX,MINY,MAXY REAL,INTENT(IN) :: CS INTEGER,INTENT(OUT) :: NCOL,NROW REAL :: D CALL UTL_IDFSNAPTOGRID_LLC(MINX,MAXX,MINY,MAXY,CS,NCOL,NROW) RETURN D=MOD(ABS(MINX),CS) IF(D.NE.0.0)MINX=(MINX+(CS-D))-CS D=MOD(ABS(MAXX),CS) IF(D.NE.0.0)MAXX=(MAXX-D)+CS D=MOD(ABS(MINY),CS) IF(D.NE.0.0)MINY=(MINY+(CS-D))-CS D=MOD(ABS(MAXY),CS) IF(D.NE.0.0)MAXY=(MAXY-D)+CS NCOL=INT((MAXX-MINX)/CS) NROW=INT((MAXY-MINY)/CS) END SUBROUTINE UTL_IDFSNAPTOGRID ! !###====================================================================== ! SUBROUTINE UTL_IDFSNAPTONICEGRID(MINX,MAXX,MINY,MAXY,CS,NCOL,NROW) ! !###====================================================================== ! REAL,INTENT(INOUT) :: MINX,MAXX,MINY,MAXY ! REAL,INTENT(IN) :: CS ! INTEGER,INTENT(OUT) :: NCOL,NROW ! REAL :: D ! ! D=MOD(ABS(MINX),CS) ! IF(D.NE.0.0)MINX=(MINX+(CS-D))-CS ! D=MOD(ABS(MAXX),CS) ! IF(D.NE.0.0)MAXX=(MAXX-D)+CS ! D=MOD(ABS(MINY),CS) ! IF(D.NE.0.0)MINY=(MINY+(CS-D))-CS ! D=MOD(ABS(MAXY),CS) ! IF(D.NE.0.0)MAXY=(MAXY-D)+CS ! ! NCOL=INT((MAXX-MINX)/CS) ! NROW=INT((MAXY-MINY)/CS) ! ! END SUBROUTINE UTL_IDFSNAPTONICEGRID ! !###====================================================================== SUBROUTINE UTL_IDFSNAPTOGRID_LLC(MINX,MAXX,MINY,MAXY,CS,NCOL,NROW,LLC) !###====================================================================== REAL,INTENT(INOUT) :: MINX,MAXX,MINY,MAXY REAL,INTENT(IN) :: CS INTEGER,INTENT(OUT) :: NCOL,NROW LOGICAL,INTENT(IN),OPTIONAL :: LLC LOGICAL :: LLLC NCOL=(MAXX-MINX)/CS NROW=(MAXY-MINY)/CS LLLC=.TRUE.; IF(PRESENT(LLC))LLLC=LLC IF(LLLC)THEN MAXX=MINX+NCOL*CS MAXY=MINY+NROW*CS ELSE MINX=MAXX-NCOL*CS MINY=MAXY-NROW*CS ENDIF END SUBROUTINE UTL_IDFSNAPTOGRID_LLC !###==================================================================== REAL FUNCTION UTL_GETMOSTFREQ(FREQ,MFREQ,NFREQ) !###==================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: MFREQ,NFREQ REAL,DIMENSION(MFREQ),INTENT(IN) :: FREQ INTEGER :: I,MI,NI NI=1 !number of unique MI=NI !max. number of unique UTL_GETMOSTFREQ=FREQ(NI) DO I=2,NFREQ IF(FREQ(I).NE.FREQ(I-1))THEN IF(NI.GT.MI)THEN UTL_GETMOSTFREQ=FREQ(I-1) MI=NI ENDIF NI=1 ELSE NI=NI+1 ENDIF END DO !test final IF(NI.GT.MI) UTL_GETMOSTFREQ=FREQ(NFREQ) END FUNCTION UTL_GETMOSTFREQ ! !###==================================================== ! SUBROUTINE UTL_GETHIST(X,NX,NODATA,HIST,NHIST,MX,XHIST) ! !###==================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: NX,NHIST !## size array,number of percentiles to be comp. ! INTEGER,INTENT(OUT) :: MX !## number of values ne nodata ! REAL,INTENT(IN),DIMENSION(NHIST) :: HIST !## percentile 0-100% ! REAL,INTENT(OUT),DIMENSION(NHIST) :: XHIST !## yielding percentile(s) ! REAL,INTENT(IN) :: NODATA !## nodata value !,PERC ! REAL,DIMENSION(NX),INTENT(INOUT) :: X !## array ! INTEGER :: I,J ! ! XHIST=0.0; MX=0; IF(NX.LE.0)RETURN ! ! DO I=1,NX ! IF(X(I).EQ.NODATA)CYCLE ! MX=MX+1 ! DO J=1,NHIST-1 ! IF(X(I).GT.HIST(J).AND.X(I).LE.HIST(J+1))THEN ! XHIST(J)=XHIST(J)+1 ! EXIT ! ENDIF ! ENDDO ! ENDDO ! ! END SUBROUTINE UTL_GETHIST ! !###==================================================== SUBROUTINE UTL_GETMED(X,NX,NODATA,PERC,NPERC,MX,XMED) !###==================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: NX,NPERC !## size array,number of percentiles to be comp. INTEGER,INTENT(OUT) :: MX !## number of values ne nodata REAL,INTENT(IN),DIMENSION(NPERC) :: PERC !## percentile 0-100% REAL,INTENT(OUT),DIMENSION(NPERC) :: XMED !## yielding percentile(s) REAL,INTENT(IN) :: NODATA !## nodata value !,PERC REAL,DIMENSION(NX),INTENT(INOUT) :: X !## array INTEGER :: I,J,IP REAL :: FRAC XMED=NODATA; MX=0 IF(NX.LE.0)RETURN !## only one sample IF(NX.EQ.1)THEN IF(X(1).NE.NODATA)THEN XMED=X(1) MX =1 ENDIF RETURN ENDIF !## do not include nodata values for median-computation DO I=1,NX IF(X(I).NE.NODATA)THEN MX =MX+1 X(MX)=X(I) ENDIF END DO IF(MX.LE.0)RETURN !## sort data, excl. nodata values IF(MX.LE.100)THEN CALL SHELLSORT(MX,X) ELSE CALL UTL_QKSORT(MX,MX,X) ENDIF DO IP=1,NPERC IF(PERC(IP).LE.0.0)THEN XMED(IP)=X(1) ELSEIF(PERC(IP).GE.100.0)THEN XMED(IP)=X(MX) ELSE FRAC=1.0/(PERC(IP)/100.0) IF(MOD(REAL(MX),FRAC).EQ.0.0)THEN I=MAX(1,INT(REAL(MX)/FRAC)) XMED(IP)=X(I) ELSE I=MAX(1,INT(REAL(MX)/FRAC)) J=MIN(I+1,MX) XMED(IP)=(X(I)+X(J))/2.0 ENDIF ENDIF ENDDO END SUBROUTINE UTL_GETMED ! !###==================================================== ! SUBROUTINE UTL_GETMED_INVERSE(X,NX,NODATA,PERC,NPERC,MX,XMED) ! !###==================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: NX,NPERC !## size array,number of percentiles to be comp. ! INTEGER,INTENT(OUT) :: MX !## number of values ne nodata ! REAL,INTENT(IN),DIMENSION(NPERC) :: PERC !## percentile 0-100% ! REAL,INTENT(OUT),DIMENSION(NPERC) :: XMED !## yielding percentile(s) ! REAL,INTENT(IN) :: NODATA !## nodata value ! REAL,DIMENSION(NX),INTENT(INOUT) :: X !## array ! INTEGER :: I,IP ! REAL :: FRAC ! ! XMED=NODATA ! ! IF(NX.LE.0)RETURN ! ! !## only one sample ! IF(NX.EQ.1)THEN ! DO IP=1,NPERC ! XMED(IP)=0.0 ! IF(X(1).LE.PERC(IP))XMED(IP)=1.0 ! ENDDO ! MX =1 ! RETURN ! ENDIF ! ! !## do not include nodata values for median-computation ! MX=0 ! DO I=1,NX ! IF(X(I).NE.NODATA)THEN ! MX =MX+1 ! X(MX)=X(I) ! ENDIF ! END DO ! ! IF(MX.LE.0)RETURN ! ! !## sort data, excl. nodata values ! IF(MX.LE.100)THEN ! CALL SHELLSORT(MX,X) ! ELSE ! CALL UTL_QKSORT(MX,MX,X) ! ENDIF ! ! !## find appropriate values for percentiles ! FRAC=1.0 ! DO IP=1,NPERC ! IF(MX.EQ.1)THEN ! XMED(IP)=0.0 ! IF(X(1).LE.PERC(IP))XMED(IP)=1.0 ! ELSE ! IF(PERC(IP).LE.X(1))THEN ! XMED(IP)=0.0 ! ELSEIF(PERC(IP).GT.X(MX))THEN ! XMED(IP)=1.0 ! ELSE ! DO I=2,MX ! IF(X(I-1).LE.PERC(IP).AND. & ! X(I) .GE.PERC(IP))THEN ! FRAC=(PERC(IP)-X(I-1))/(X(I)-X(I-1)) ! XMED(IP)=(REAL(I-1)+FRAC)/REAL(MX) ! EXIT ! ENDIF ! ENDDO ! ENDIF ! ENDIF ! WRITE(*,*) 'PERC(IP)=',PERC(IP) ! WRITE(*,*) 'XMED(IP)=',XMED(IP) ! WRITE(*,*) 'FRAC =',FRAC ! DO I=1,MX; WRITE(*,'(I10,F15.7)') I,X(I); ENDDO ! ENDDO ! ! END SUBROUTINE UTL_GETMED_INVERSE ! ! !###====================================================================== ! INTEGER FUNCTION CALCPERIODS(ISTARTDATE,IENDDATE) ! !###====================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: ISTARTDATE,IENDDATE ! ! CALCPERIODS=UTL_IDATETOJDATE(IENDDATE)-UTL_IDATETOJDATE(ISTARTDATE)+1 ! ! END FUNCTION CALCPERIODS ! ! !###==================================================== ! SUBROUTINE UTL_GETUNIQUE(X,N,NU,NODATA) ! !###==================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: N ! INTEGER,INTENT(OUT) :: NU ! REAL,INTENT(IN),OPTIONAL :: NODATA ! REAL,INTENT(INOUT),DIMENSION(N) :: X ! INTEGER :: I ! ! CALL UTL_QKSORT(N,N,X) ! ! !## determine number of unique classes ! IF(PRESENT(NODATA))THEN ! NU=0 ! DO I=1,N ! IF(NU.EQ.0)THEN ! IF(X(I).NE.NODATA)THEN ! NU=NU+1 ! X(NU)=X(I) ! ENDIF ! ELSE ! IF(X(I).NE.X(NU).AND.X(I).NE.NODATA)THEN ! NU =NU+1 ! X(NU)=X(I) ! ENDIF ! ENDIF ! END DO ! ELSE ! NU=1 ! DO I=2,N ! IF(X(I).NE.X(NU))THEN ! NU =NU+1 ! X(NU)=X(I) ! ENDIF ! END DO ! ENDIF ! ! END SUBROUTINE UTL_GETUNIQUE ! ! !###==================================================== ! SUBROUTINE UTL_GETUNIQUE_INT(IX,N,NU) ! !###==================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: N ! INTEGER,INTENT(OUT) :: NU ! INTEGER,INTENT(INOUT),DIMENSION(N) :: IX ! INTEGER :: I ! ! CALL SHELLSORT_INT(N,IX) ! ! !## determine number of unique classes ! NU=1 ! DO I=2,N ! IF(IX(I).NE.IX(NU))THEN ! NU =NU+1 ! IX(NU)=IX(I) ! ENDIF ! END DO ! ! END SUBROUTINE UTL_GETUNIQUE_INT ! ! !###==================================================== ! SUBROUTINE UTL_GETUNIQUE_CHAR(CH,N,NU) ! !###==================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: N ! INTEGER,INTENT(OUT) :: NU ! CHARACTER(LEN=*),INTENT(INOUT),DIMENSION(N) :: CH ! INTEGER :: I,J ! ! !## determine number of unique classes ! NU=1 ! DO I=2,N ! DO J=1,NU ! IF(CH(J).EQ.CH(I))EXIT !## get it already ! ENDDO ! IF(J.LE.NU)CYCLE ! !## add new to unique string ! NU=NU+1 ! CH(NU)=CH(I) ! END DO ! ! END SUBROUTINE UTL_GETUNIQUE_CHAR ! !###==================================================== LOGICAL FUNCTION UTL_EQUALS_REAL(A,B) !###==================================================== IMPLICIT NONE REAL, INTENT(IN) :: A, B REAL :: EPS EPS=ABS(A)*EPSILON(A) ! SCALE EPSILON IF(EPS.EQ.0.0)THEN EPS=TINY (A) ! IF EPS UNDERFLOWED TO 0 ! USE A VERY SMALL ! POSITIVE VALUE FOR EPSILON END IF IF(ABS(A-B).GT.EPS)THEN UTL_EQUALS_REAL=.FALSE. ! NOT EQUAL IF DIFFERENCE>EPS ELSE UTL_EQUALS_REAL=.TRUE. ! EQUAL OTHERWISE ENDIF END FUNCTION UTL_EQUALS_REAL ! !###==================================================== ! SUBROUTINE PEUCKER_SIMPLIFYLINE(XC,YC,PDCODE,N) ! !###==================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: N ! REAL,INTENT(IN),DIMENSION(N) :: XC,YC ! REAL,INTENT(OUT),DIMENSION(N) :: PDCODE ! INTEGER :: MJ,J1,J2 ! REAL :: MD ! ! PDCODE=-999.99 ! !## set first and last point, distance is zero ! PDCODE(1)=0.0; PDCODE(N)=0.0 ! ! !## process each intermediate point ! DO ! ! !## get the start point (first empty spot) ! DO J1=1,N-1; IF(PDCODE(J1).LT.0.0)EXIT; ENDDO ! !## finished ! IF(J1.EQ.N)EXIT ! !## previous fixed point ! J1=J1-1 ! ! !## get the end point (fixed point) ! DO J2=J1+1,N; IF(PDCODE(J2).GE.0.0)EXIT; ENDDO ! ! !## get the maximal distance in between i1 and i2 and tag it ! CALL PEUCKER_CALCDISTANCE(J1,J2,N,XC,YC,MJ,MD) ! ! !## tag decrease line segment to examine ! IF(MJ.GT.0)PDCODE(MJ)=MD ! ! ENDDO ! ! END SUBROUTINE PEUCKER_SIMPLIFYLINE ! ! !###==================================================== ! SUBROUTINE PEUCKER_CALCDISTANCE(J1,J2,N,XC,YC,MJ,MD) ! !###==================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: N,J1,J2 ! REAL,INTENT(OUT) :: MD ! REAL,INTENT(IN),DIMENSION(N) :: XC,YC ! INTEGER,INTENT(OUT) :: MJ ! INTEGER :: J ! REAL :: B,A,D,Y ! ! !## line equation ! B=YC(J1); A=(YC(J2)-YC(J1))/(XC(J2)-XC(J1)); MD=-1.0; MJ=0 ! ! !## loop over all points ! DO J=J1+1,J2-1 ! !## get point on line ! Y=(XC(J)-XC(J1))*A+B ! !## get difference between line and point ! D=ABS(Y-YC(J)) ! !## keep this one is this is largers ! IF(D.GT.MD)THEN ! MD=D; MJ=J ! ENDIF ! ENDDO ! ! END SUBROUTINE PEUCKER_CALCDISTANCE ! ! !###==================================================================== ! REAL FUNCTION UTL_GOODNESS_OF_FIT(X,Y,N) ! !###==================================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: N ! REAL,INTENT(IN),DIMENSION(N) :: X,Y ! REAL :: XN,YN,X1,X2,X3 ! INTEGER :: I ! ! XN=SUM(X)/REAL(N) ! YN=SUM(Y)/REAL(N) ! ! X1=0.0; X2=0.0; X3=0.0 ! DO I=1,N ! X1=X1+(X(I)-XN)*(Y(I)-YN) ! X2=X2+(X(I)-XN)**2.0 ! X3=X3+(Y(I)-YN)**2.0 ! ENDDO ! ! IF(X2.NE.0.0.AND.X3.NE.0.0)UTL_GOODNESS_OF_FIT=X1/(SQRT(X2)*SQRT(X3)) ! ! END FUNCTION UTL_GOODNESS_OF_FIT ! ! !###==================================================== ! SUBROUTINE UTL_FIT_REGRESSION(X,Y,NDATA,SIG,MWT,A,B,SIGA,SIGB,CHI2,Q) ! !###==================================================== ! IMPLICIT NONE ! INTEGER,INTENT(IN) :: NDATA,MWT ! REAL,INTENT(OUT) :: A,B,CHI2,Q,SIGA,SIGB ! REAL,DIMENSION(NDATA) :: X,Y,SIG ! INTEGER :: I ! REAL :: SIGDAT,SS,ST2,SX,SXOSS,SY,T,WT ! ! SX =0.0 ! SY =0.0 ! ST2=0.0 ! B =0.0 ! ! IF(MWT.NE.0)THEN ! SS=0.0 ! DO I=1,NDATA ! WT=1.0/(SIG(I)**2) ! SS=SS+WT ! SX=SX+X(I)*WT ! SY=SY+Y(I)*WT ! ENDDO ! ELSE ! DO I=1,NDATA ! SX=SX+X(I) ! SY=SY+Y(I) ! ENDDO ! SS=FLOAT(NDATA) ! ENDIF ! ! SXOSS=SX/SS ! ! IF(MWT.NE.0)THEN ! DO I=1,NDATA ! T=(X(I)-SXOSS)/SIG(I) ! ST2=ST2+T*T ! B=B+T*Y(I)/SIG(I) ! ENDDO ! ELSE ! DO I=1,NDATA ! T=X(I)-SXOSS ! ST2=ST2+T*T ! B=B+T*Y(I) ! ENDDO ! ENDIF ! ! B=B/ST2 ! A=(SY-SX*B)/SS ! SIGA=SQRT((1.0+SX*SX/(SS*ST2))/SS) ! SIGB=SQRT(1.0/ST2) ! CHI2=0.0 ! ! IF(MWT.EQ.0)THEN ! DO I=1,NDATA ! CHI2=CHI2+(Y(I)-A-B*X(I))**2 ! ENDDO ! Q=1.0 ! SIGDAT=SQRT(CHI2/REAL(NDATA-2)) ! SIGA=SIGA*SIGDAT ! SIGB=SIGB*SIGDAT ! ELSE ! DO I=1,NDATA ! CHI2=CHI2+((Y(I)-A-B*X(I))/SIG(I))**2 ! ENDDO ! Q=UTL_GAMMQ(0.5*(NDATA-2),0.5*CHI2) ! ENDIF ! ! END SUBROUTINE UTL_FIT_REGRESSION ! ! !###==================================================== ! REAL FUNCTION UTL_GAMMQ(A,X) ! !###==================================================== ! IMPLICIT NONE ! REAL,INTENT(IN) :: A,X ! REAL :: GAMMCF,GAMSER,GLN ! ! IF(X.LT.0.0.OR.A.LE.0.0)PAUSE 'BAD ARGUMENT IN UTL_GAMMQ' ! IF(X.LT.A+1.0)THEN ! CALL UTL_GSER(GAMSER,A,X,GLN) ! UTL_GAMMQ=1.0-GAMSER ! ELSE ! CALL UTL_GCF(GAMMCF,A,X,GLN) ! UTL_GAMMQ=GAMMCF ! ENDIF ! ! END FUNCTION ! ! !###==================================================== ! SUBROUTINE UTL_GSER(GAMSER,A,X,GLN) ! !###==================================================== ! IMPLICIT NONE ! REAL,INTENT(IN) :: A,X ! REAL,INTENT(OUT) :: GLN,GAMSER ! INTEGER,PARAMETER :: ITMAX=100 ! REAL,PARAMETER :: EPS=3.0E-7 ! INTEGER :: N ! REAL :: AP,DEL,SUM ! ! GLN=UTL_GAMMLN(A) ! IF(X.LE.0.0)THEN ! IF(X.LT.0.0)PAUSE 'X < 0 IN UTL_GSER' ! GAMSER=0.0 ! RETURN ! ENDIF ! ! AP=A ! SUM=1.0/A ! DEL=SUM ! ! DO N=1,ITMAX ! AP=AP+1.0 ! DEL=DEL*X/AP ! SUM=SUM+DEL ! IF(ABS(DEL).LT.ABS(SUM)*EPS)GOTO 1 ! ENDDO ! ! PAUSE 'A TOO LARGE, ITMAX TOO SMALL IN UTL_GSER' !1 GAMSER=SUM*EXP(-X+A*LOG(X)-GLN) ! ! END SUBROUTINE UTL_GSER ! ! !###==================================================== ! SUBROUTINE UTL_GCF(GAMMCF,A,X,GLN) ! !###==================================================== ! IMPLICIT NONE ! INTEGER,PARAMETER :: ITMAX=100 ! REAL,PARAMETER :: EPS=3.0E-7,FPMIN=1.0-30 ! REAL,INTENT(IN) :: A,X ! REAL,INTENT(OUT) :: GAMMCF,GLN ! INTEGER :: I ! REAL :: AN,B,C,D,DEL,H ! ! GLN=UTL_GAMMLN(A) ! B=X+1.0-A ! C=1.0/FPMIN ! D=1.0/B ! H=D ! DO I=1,ITMAX ! AN=-I*(I-A) ! B=B+2.0 ! D=AN*D+B ! IF(ABS(D).LT.FPMIN)D=FPMIN ! C=B+AN/C ! IF(ABS(C).LT.FPMIN)C=FPMIN ! D=1.0/D ! DEL=D*C ! H=H*DEL ! IF(ABS(DEL-1.0).LT.EPS)GOTO 1 ! ENDDO ! PAUSE 'A TOO LARGE, ITMAX TOOP SMALL IN UTL_GCF' !1 GAMMCF=EXP(-X+A*LOG(X)-GLN)*H ! ! END SUBROUTINE UTL_GCF ! ! !###==================================================== ! REAL FUNCTION UTL_GAMMLN(XX) ! !###==================================================== ! IMPLICIT NONE ! REAL,INTENT(IN) :: XX ! INTEGER :: J ! DOUBLE PRECISION,SAVE :: SER,STP,TMP,X,Y,COF(6) ! DATA COF,STP/76.18009172947146D0,-86.50532032941677D0, & ! 24.01409824083091D0,-1.231739572450155D0,0.1208650973866179D-2, & ! -0.5395239384953D-5,2.5066282746310005D0/ ! ! X=XX ! Y=X ! TMP=X+5.5D0 ! TMP=(X+0.5D0)*LOG(TMP)-TMP ! SER=1.000000000190015D0 ! DO J=1,6 ! Y=Y+1.0D0 ! SER=SER+COF(J)/Y ! ENDDO ! UTL_GAMMLN=TMP+LOG(STP*SER/X) ! ! END FUNCTION UTL_GAMMLN ! END MODULE MOD_UTL